Choose folder or folder directory inside shiny app - r

I have a problem using shiny. I want to choose the folder where all the files I want to use in my app are saved either 1) by setting the working directory to that folderpath or 2) by uploading all csv data inside this folder to my app for further processing. for 1) I found the shinyFiles package but it is very very slow -not due to my PC- as well as giving me the error:
Warning: Error in dir.create: invalid 'path' argument
Stack trace (innermost first):
59: dir.create
58: dirCreate
57: observerFunc
2: runApp
1: shinyFilesExample
when I selected a folder and the create folder button becomes clickable and I am putting a name of the new folder into it and clicking on the "+" beneath that panel. Anybody knows why? Despite that this method works but is very very slow. code below:
library(shiny)
library(shinyFiles)
ui<-fluidPage(sidebarLayout(
sidebarPanel(
shinyDirButton("dir", "Chose directory", "Upload")
),
mainPanel(
h4("output$dir"),
verbatimTextOutput("dir"), br()
)
))
server <- function(input,output,session){
# dir
shinyDirChoose(input, 'dir', roots = getVolumes())
dir <- reactive(input$dir)
output$dir <- renderPrint(dir())
}
shinyApp(ui = ui, server = server)
Is there another option? Maybe to upload all csv data via the fileInput function? Or another way? It should not work only locally but on a server so choose.dir might be not the right way.
Many thanks

so far, shinyfiles is the only way to input folders, as far as I know. It cannot work on a server, because browsers are not allowed to select folders (for security reasons).
The zipping way might be the only way to go if you want it to be working on a server (but I have no clue if it can actually be done)

The funktion getwd() gets your current working directory.
server <- function(input,output,session){
# dir
shinyDirChoose(input, 'dir', roots = c(name=getwd()))
dir <- reactive(input$dir)
output$dir <- renderPrint(dir())
}

If there are not too many files in your directory, you can just use fileInput with multiple=T. You can also filter them by extension.
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
# ?fileInput
fileInput("file1", "Choose HTML File(s)", multiple=T, accept = ".html")
),
mainPanel(
verbatimTextOutput("out.print")
)
)
)
server <- function(input, output) {
output$out.print <- renderPrint({
file <- input$file1
ext <- tools::file_ext(file$datapath)
req(file)
validate(need(ext == "html", "Please upload html file(s)"))
file
})
}
shinyApp(ui, server)
However, if you have too many files, it seems like library(shinyFiles) remains to be your option

Related

Shiny method to browse and pass filename

I am trying to build a front end using Shiny to pass some parameters to a markdown document. One parameter I want to pass is a user selected file name, including the path. I would like to use a file open type dialogue box for the user to navigate through directories and select the file. I do not need/want to actually open the file, that happens in the markdown file, I just want to pass the path and file name of the selected file out of the shiny app. I have this set up using fileInput() but of course this opens the file and makes a copy in a temp directory and the associated path is to the temp directory not the original directory. There have been some related questions about this and the only answers are that this is a security issue related to the server-based nature of shiny. Again, I don't want to open the file, just grab the original path and name. Any thoughts on how to achieve this? Here's the code stripped down to just this issue ...
library(shiny)
ui <- fluidPage(
titlePanel("Input"),
mainPanel(
fileInput(inputId = "rtffile", "Choose RTF File", accept = ".rtf", ),
)
server <- function(input, output, session) {
observe({
filename <<- input$rtffile
})
}
shinyApp(ui = ui, server = server)
In general, you can’t get a web browser to give you the path to a file on the
user’s local machine.
However, it’s possible to get a path to a file on the server.
If the server and the local machine happen to be the same, you can use e.g. shinyFiles to
pick a path:
library(shiny)
library(shinyFiles)
ui <- fluidPage(
titlePanel("Input"),
mainPanel(
shinyFilesButton("file", "Choose File", "Choose a file", multiple = FALSE),
verbatimTextOutput("file")
)
)
server <- function(input, output, session) {
roots <- getVolumes()
shinyFileChoose(input, "file", roots = roots)
file <- reactive(parseFilePaths(roots, input$file))
output$file <- renderPrint(file())
}
shinyApp(ui = ui, server = server)

How to select a directory and output the selected directory in R Shiny

Please is there any simple way how to allow the user of R Shiny application (locally, not on server) to select a directory from a computer and then output the path? I cannot find an easy way such as fileInput for selecting files.
I want the user to be able to search the whole PC for folders and then select the folder, and the path to this folder will be displayed in the Shiny app, such as
C:\users\Jane\folder. In the answer below, I am able to search only the current working directory for folders, not the whole PC and the path to the folder is not displayed in the Shiny app.
You could consider the shinyFiles package.
On server side you use
shinyDirChoose(input, id = 'folder', ...) and then can access the chosen folder via input$folder.
Reproducible example:
library(shiny)
library(shinyFiles)
shinyApp(
shinyUI(bootstrapPage(
shinyDirButton('folder', 'Select a folder', 'Please select a folder', FALSE)
)),
shinyServer(function(input, output) {
shinyDirChoose(input, 'folder', roots=c(wd='.'), filetypes=c('', 'txt'))
observe({
print(input$folder)
})
})
)
Some folks are asking about how to choose your directory differently. You can do this by changing the specification for roots as I do below.
library(shiny)
library(shinyFiles)
ui <- fluidPage(
shinyDirButton('folder', 'Select a folder', 'Please select a folder', FALSE)
)
server <- function(input, output){
volumes = getVolumes() # this makes the directory at the base of your computer.
observe({
shinyDirChoose(input, 'folder', roots=volumes, filetypes=c('', 'txt'))
print(input$folder)
})
}
shinyApp(ui=ui, server=server)
Just add up one side note for this question:
I was trying to apply this function to my codes, but I kept getting object of type ‘closure’ is not subsettable error. I tried multiple ways and finally figured it out using GitHub discussion page.
I figured the issue is coming from getVolumes function. Instead of using getVolumes(), getVolumes()() helped me resolve the error. I still don't totally understand why, but hopefully it helps other to solve this mysterious error.

Upload a user picked directory in R Shiny

I have an R shiny app that requires multiple files (all found within the same folder) to be uploaded. I also know the names of the files to look for.
Is there any way to upload these files other than via fileInput(..., multiple = TRUE)? Ideally, I would have the user upload the whole directory.
You can use the library shinyFiles to let the user pic a folder somewhere on their local disk. Then in the server you can use the user input to load all the files that you need from this folder.
Example
library(shiny)
library(shinyFiles)
### UI
ui <- fluidPage(
shinyDirButton('directory_select', 'Select a directory', title='Select a directory'),
textOutput('directory_name')
)
### Server
server <- function(input, output, session) {
volumes <- getVolumes()
shinyDirChoose(input, 'directory_select', roots=volumes, session=session)
dirname <- reactive({parseDirPath(volumes, input$directory_select)})
## Observe input dir. changes
observe({
if(!is.null(dirname)){
print(dirname())
output$directory_name <- renderText(dirname())
## Load files here
# csv <- read.csv(paste0(dirname(), '/filename1.csv'))
# rdata <- load(paste0(dirname(), '/filename2.Rdata'))
# etc.
}
})
}
shinyApp(ui = ui, server = server)

Copying file on upload and paste it to www folder location

I want to upload a file in Shiny and copy it to a WWW folder. My code is uploading file, but it is not copying file to WWW folder location. How can I do this? Am I doing wrong? Thanks.
Following file "ui.R" is also in www folder:
library(shiny)
shinyApp(
ui=shinyUI(bootstrapPage(
fileInput("upload", "Upload", multiple = FALSE)
)),
server=shinyServer(function(input, output, session){
observe({
if (is.null(input$upload)) return()
file.copy(input$upload$datapath, "\\C:\\Users\\'XXX XXX'\\Documents\\R\\win-library\\3.4\\shiny\\www\\")
})
})
)
Believe it's a simple issue with the string mentioned in the output path. I was able to get the code below working without issues.
If I try to upload a file called temp.R using the app, then it is being renamed to 0.R as the complete file name has not been specified in file.copy. Provide the complete file name if you want it to work irrespective of the name in the user's system, e.g file.copy(input$upload$datapath, "C:\\NotBackedUp\\user_upload.R", overwrite = TRUE).
You can retrieve the original name using input$upload$name.
library(shiny)
shinyApp(
ui=shinyUI(bootstrapPage(
fileInput("upload", "Upload", multiple = FALSE)
)),
server=shinyServer(function(input, output, session){
observe({
if (is.null(input$upload)) return()
file.copy(input$upload$datapath,
"C:\\NotBackedUp", overwrite = TRUE)
})
})
)

Read multiple files in ShinyR and select the required files to read

I haven't found this question anywhere.
I have to read all the files present in a folder and to display them in Shiny application file upload screen. Here, user will be allowed to select one or more than one files by check-box and those files are to be processed.
Is there any example script of sample script relevant to above posted in github or else where?
Dummy example (copy / paste and execute):
This example allows a user to read files in a folder and list them in a selectizeInput.. You can read the files and process in the way you desire.. I know there're no checkboxs but you can use other input but selectizeInput (was easier for me).
library(shiny)
ui <- fluidPage(
selectizeInput(inputId = 'select_input', label = 'Choose your files...', choices = '*', multiple = TRUE),
verbatimTextOutput('debug')
)
server <- function(input, output, session) {
observe({
files <- list.files()
updateSelectizeInput(session = session, inputId = 'select_input', choices = files)
})
output$debug <- renderPrint({input$select_input})
}
shinyApp(ui, server)

Resources