How To Upload Image to Shiny App From Dropdown - r

I am trying to upload images to my shiny app, but seem to be stuck on a basic step. The images are in my www directory. I am able to implement a drop down option, and would like the user to select an image (e.g, mouse.png) which would upload said image. However, the image itself is not uploading.
This is my code, does anyone have any ideas?
library(shiny)
#create a box function
my.box <- function(title, obj) {
box(
title = title,
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
plotOutput(obj, height = "300px")
)
}
# List of choices for selectInput
mylist <- list.files("~/APP/www/")
body <- dashboardBody(tableOutput("filtered_table"),
my.box("Table1", "Table1"))
#create dropbox
ui <- fluidPage(
#drop down box
selectInput(inputId ="gene",label = h3("Select an image from below"),choices = mylist),
#name of the plot.
mainPanel(plotOutput("image")) #NOT SURE WHAT TO PLACE HERE
)
#server function
server = shinyServer(function(input, output,session){
observeEvent(input$myFile, {
inFile <- input$myFile
if (is.null(inFile))
return()
file.copy(inFile$datapath, file.path("~/APP/www/", inFile$name) )
})
})

Following the example from the shiny tutorial, you can use renderImage/imageOutput. Note that I've adjusted the file paths a bit.
library(shiny)
library(shinydashboard)
#create a box function
my.box <- function(title, obj) {
box(
title = title,
status = "primary",
solidHeader = TRUE,
collapsible = TRUE,
plotOutput(obj, height = "300px")
)
}
# List of choices for selectInput
mylist <- list.files("./www")
body <- dashboardBody(tableOutput("filtered_table"),
my.box("Table1", "Table1"))
#create dropbox
ui <- fluidPage(
#drop down box
selectInput(inputId ="gene",label = h3("Select an image from below"),choices = mylist),
#name of the plot.
mainPanel(imageOutput("image"))
)
#server function
server = shinyServer(function(input, output,session){
output$image <- renderImage({
filename <- normalizePath(file.path('www',
input$gene))
list(src = filename)
}, deleteFile = FALSE)
})
shinyApp(ui, server)

Related

Textoutput as hyperlink in R shiny

I need to have the outputText (Key_facts) as a hyperlink, whenever I extract it from csv file could you please help me to figure out how to solve this issue
library(shiny)
info_360 <- read.csv('data/360_photos.csv')
ui <-
fluidRow(
box(
title = "Key Facts",
closable = FALSE,
width = 9,
status = "primary",
solidHeader = FALSE,
collapsible = TRUE,
textOutput("keyfacts"))
server <- function(input, output,session) {
Keyfactstext <- reactive({
if (input$mySliderText %in% info_360$press )
{
info_360 %>%
filter(press == input$mySliderText)%>%
pull(Key_facts)
**#this contains a text that includes a website link, I need only the link to appear as a hyperlink?????????????????**
}
})
output$keyfacts<- renderText({ Keyfactstext ()})
}
shinyApp(ui = ui, server = server)
This might work but I can't test without your file
library(shiny)
info_360 <- read.csv('data/360_photos.csv')
ui <-
fluidRow(
box(
title = "Key Facts",
closable = FALSE,
width = 9,
status = "primary",
solidHeader = FALSE,
collapsible = TRUE,
uiOutput("keyfacts"))
server <- function(input, output,session) {
Keyfactstext <- reactive({
if (input$mySliderText %in% info_360$press )
{
info_360 %>%
filter(press == input$mySliderText)%>%
pull(Key_facts)
**#this contains a text that includes a website link, I need only the link to appear as a hyperlink?????????????????**
}
})
output$keyfacts<- renderUI({
tagList$a(href = Keyfactstext(), "Click me")})
}
shinyApp(ui = ui, server = server)

How to have one observable function for three buttons in Shiny app

I have a button linked to an observable event. The button just uploads an excel spreadsheet and then loads it as a dataframe. I have three of these buttons. Each does the same thing. I would like to create a function that does the uploading so that I dont have to define it two separate times. I just cant figure out how to create a function that allows me to do this in Shiny.
library(shiny)
library(shinydashboard)
library(shinyjs)
library(readxl)
ui <- fluidPage(
titlePanel("My button issue"),
mainPanel(
box(status = "primary", solidHeader = TRUE,collapsible = T,collapsed=FALSE,title = "A. Upload data",
fileInput("pathology",label="",multiple = FALSE),br()),
box(status = "primary", solidHeader = TRUE,collapsible = T,collapsed=FALSE,title = "B. Upload data",
fileInput("FileIn_endoscopy",label="",multiple = FALSE),br())
)
)
server <- function(input, output) {
observe({
inFile_path <- input$pathology
if (!is.null(inFile_path)) {
dataFile <- read_excel(inFile_path$datapath, sheet=1)
RV2$data<-data.frame(dataFile, stringsAsFactors=FALSE)
enable("textPrepPath")
}
else{disable("textPrepPath")}
})
observe({
inFile_endoscopy <- input$FileIn_endoscopy
if (!is.null(inFile_endoscopy)) {
dataFile <- read_excel(inFile_endoscopy$datapath, sheet=1)
RV$data<-data.frame(dataFile, stringsAsFactors=FALSE)
enable("textPrep")
}
else{disable("textPrep")}
})
}
# Run the application
shinyApp(ui = ui, server = server)
I don't have a lot of experience with shiny modules, but I think it's a good approach here. Your example code is incomplete so I can't test it, but maybe something like this whould work?
library(shiny)
library(shinydashboard)
library(shinyjs)
library(readxl)
fileButton <- function(id, title) {
ns <- NS(id)
tagList(
box(status = "primary", solidHeader = TRUE,collapsible = T,collapsed=FALSE,title = title,
fileInput(ns("inputfile"),label="",multiple = FALSE),br())
)
}
file <- function(input, output, session) {
observeEvent(input$inputfile, {
inFile_path <- input$inputfile
if (!is.null(inFile_path)) {
dataFile <- read_excel(inFile_path$datapath, sheet=1)
RV2$data<-data.frame(dataFile, stringsAsFactors=FALSE)
enable("textPrepPath")
}
else{disable("textPrepPath")}
})
}
ui <- fluidPage(
titlePanel("My button issue"),
mainPanel(
fileButton("pathology", "A. Upload data"),
fileButton("FileIn_endoscopy", "B. Upload data")
)
)
server <- function(input, output) {
callModule(file, "pathology")
callModule(file, "FileIn_endoscopy")
}
# Run the application
shinyApp(ui = ui, server = server)

How to avoid collapsing with shinyWidgets dropdown and a datatable

I want to display a spreadsheet with some information in shinyWidgets dropdown, sometimes spanning multiple pages.
If you click on the next page, the dropdown closes again.
How can I avoid this?
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
br(),br(),br(),
p("How to go to the next page, without collapsing?"),
uiOutput("irisdrop", inline = TRUE)
)
server <- function(input, output, session) {
output$irisdrop <- renderUI({
dropdown(circle = FALSE, inputId = "iris",
label = "iris", status = "primary",
datatable(iris, rownames = NULL,
height = "100%",
selection = "none"
)
)
})
}
shinyApp(ui, server)
You can do something like this -
library(shiny)
library(shinyWidgets)
library(DT)
ui <- fluidPage(
dropdownButton(
inputId = "iris",
label = "iris",
icon = icon("sliders"),
status = "primary",
circle = FALSE,
DT::dataTableOutput("iris_tb")
)
)
server <- function(input, output, session) {
output$iris_tb <- DT::renderDataTable({
datatable(iris, rownames = NULL,
height = "100%",
selection = "none"
)
})
}
shinyApp(ui, server)
Note: You can even use dropdown() instead of dropdownButton() from shinyWidgets package.
dropdown() is similar to dropdownButton() but it don't use Bootstrap, so you can put pickerInput in it. Moreover you can add animations on the appearance / disappearance of the dropdown with animate.css.
For more detail, you can look at the page 30 of the following document -
https://cran.r-project.org/web/packages/shinyWidgets/shinyWidgets.pdf

div in shiny overriding scroll bars for whole app

I am trying to use a package that allows users to graph their data in shiny (esquiss). It works fine. However the user interface for the shiny module in the package requires a fixed height container. I have therefore placed the call to the module in tag$div (inside a modal) called by a button.
The problem is that this call to this module seems to get rid of all the scrollbars for the main page of the app (so I can't scroll to the bottom of the main page (it is a one page app).
How can I limit the html of the module to prevent it from overriding the rest of the app? The code for the module being called is here.
My reproducible example follows:
ui.R
library(shiny)
library(esquisse)
library(shinyBS)
ui <- fluidPage(
dashboardPage(
dashboardHeader(title = ''),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard")
)),
dashboardBody(
actionButton(inputId = "esquissGraphs",label = "esquissGraphs"),
DT::dataTableOutput("mytable"),
bsModal("modalExample", "Data Table", "esquissGraphs", size = "large",
tags$h1("Use esquisse as a Shiny module"),
radioButtons(
inputId = "data",
label = "Data to use:",
choices = c("Mydftbbinnit", "mtcars"),
inline = TRUE
),
tags$div(
style = "height: 700px;", # needs to be in fixed height container
esquisserUI(
id = "esquisse",
header = FALSE, # dont display gadget title
choose_data = FALSE # dont display button to change data
)
)
)
)
)
)
server.R
RV <- reactiveValues(data = data.frame())
RV2 <- reactiveValues(data = data.frame())
server <- function(input, output, session) {
n<-c("1","434","101")
t<-c("Bugs","Mugs","Thugs")
RV$data<-data.frame(n,t,stringsAsFactors = FALSE)
o<-c("1","434","101")
p<-c("Bugs","Mugs","Thugs")
RV2$data<-data.frame(o,p,stringsAsFactors = FALSE)
output$mytable = DT::renderDataTable({
mtcars
})
data_r <-reactiveValues(data = data.frame())
observeEvent(input$data, {
if (input$data == "Mydftbbinnit") {
data_r$data <- RV$data
data_r$name <- "Mydftbbinnit"
} else {
data_r$data <- RV2$data
data_r$name <- "The rest"
}
})
callModule(module = esquisserServer, id = "esquisse", data = data_r)
}
shinyApp(ui, server)
You need to add
tags$style("html, body {overflow: visible !important;")
in your UI to force scrollbar to appear.
Source : https://github.com/dreamRs/esquisse/blob/master/R/esquisserUI.R
Full example gives :
library(shiny)
library(shinydashboard)
library(esquisse)
library(shinyBS)
library(shiny)
library(esquisse)
library(shinyBS)
ui <- fluidPage(
dashboardPage(
dashboardHeader(title = ""),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard")
)
),
dashboardBody(
tags$style("html, body {overflow: visible !important;"),
actionButton(inputId = "esquissGraphs", label = "esquissGraphs"),
DT::dataTableOutput("mytable"),
bsModal("modalExample", "Data Table", "esquissGraphs",
size = "large",
tags$h1("Use esquisse as a Shiny module"),
radioButtons(
inputId = "data",
label = "Data to use:",
choices = c("Mydftbbinnit", "mtcars"),
inline = TRUE
),
tags$div(
style = "height: 700px;", # needs to be in fixed height container
esquisserUI(
id = "esquisse",
header = FALSE, # dont display gadget title
choose_data = FALSE # dont display button to change data
)
)
)
)
)
)
RV <- reactiveValues(data = data.frame())
RV2 <- reactiveValues(data = data.frame())
server <- function(input, output, session) {
n <- c("1", "434", "101")
t <- c("Bugs", "Mugs", "Thugs")
RV$data <- data.frame(n, t, stringsAsFactors = FALSE)
o <- c("1", "434", "101")
p <- c("Bugs", "Mugs", "Thugs")
RV2$data <- data.frame(o, p, stringsAsFactors = FALSE)
output$mytable <- DT::renderDataTable({
mtcars
})
data_r <- reactiveValues(data = data.frame())
observeEvent(input$data, {
if (input$data == "Mydftbbinnit") {
data_r$data <- RV$data
data_r$name <- "Mydftbbinnit"
} else {
data_r$data <- RV2$data
data_r$name <- "The rest"
}
})
callModule(module = esquisserServer, id = "esquisse", data = data_r)
}
shinyApp(ui, server)

Shiny conditional panel

In my app I want the user to choose a folder, and the to choose a file from that folder.
I thought to use conditionalPanel() so the user will see only the first button until he pick's the folder. I wrote this code but I get this error message, 'object 'input' is not found', what would be the right way to do this? And is it a problem to put a conditional panel in an absolute panel?
library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel(""),
fluidRow(
# select input for selecting a folder
column(2, absolutePanel(fixed = TRUE, width = '180px',
selectInput("pick_folder", label = '', selected='choose_a_folder',
choices = setNames(as.list(c('choose_a_folder', basename(setdiff(list.dirs(recursive = FALSE),'.')))),
c('choose_a_folder', basename(setdiff(list.dirs(recursive = FALSE),'.'))))))),
# select input for selecting a file absolutePanel then conditionalPanel
column(2, absolutePanel(fixed = TRUE, width = '180px',
conditionalPanel(condition="input.pick_folder==choose_a_folder",
selectInput('pick_file', label = '', selected = 'choose_a_file',
choices = setNames(as.list(c('choose_a_file', basename(setdiff(list.files(path=input$pick_folder ,recursive = FALSE),'.')))),
c('choose a file', basename(setdiff(list.files(path=input$pick_folder ,recursive = FALSE),'.')))))))),
),
fluidRow(
#plot
plotOutput('my_plot')
)))
# server
server <- shinyServer(function(input, output) {
output$my_plot <- renderPlot({
dat <- read.table(file=paste(input$pick_folder, input$pick_file, sep='/'))
# some plots over dat
})
})
shinyApp(ui, server)
The probem arises from trying to dynamically create the choices for the file selection inside the ui part of your app. The way you should do this is to create the dynamic part of the ui (Your file selection) in your server part using uiOutput and renderUI
The following code seems to do what you describe you want:
library(shiny)
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel(""),
fluidRow(
# select input for selecting a folder
column(2, absolutePanel(fixed = TRUE, width = '180px',
selectInput("pick_folder", label = '', selected='choose_a_folder',
choices = setNames(as.list(c('choose_a_folder', basename(setdiff(list.dirs(recursive = FALSE),'.')))),
c('choose_a_folder', basename(setdiff(list.dirs(recursive = FALSE),'.'))))))),
# select input for selecting a file absolutePanel then conditionalPanel
column(2, absolutePanel(fixed = TRUE, width = '180px',
conditionalPanel(condition="input.pick_folder==choose_a_folder",
# Insert a dynamic bit of UI
uiOutput("fileselection")
)
)
)
),
fluidRow(
#plot
plotOutput('my_plot')
)))
# server
server <- shinyServer(function(input, output) {
output$my_plot <- renderPlot({
dat <- read.table(file=paste(input$pick_folder, input$pick_file, sep='/'))
# some plots over dat
})
output$fileselection <- renderUI({ #Define the dynamic UI
selectInput('pick_file', label = '', selected = 'choose_a_file',
choices = setNames(as.list(c('choose_a_file', basename(setdiff(list.files(path=input$pick_folder ,recursive = FALSE),'.')))),
c('choose a file', basename(setdiff(list.files(path=input$pick_folder ,recursive = FALSE),'.'))
)
)
)
})
})
shinyApp(ui, server)

Resources