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)
Related
I am working on a shiny app where the user uploads a number of csv files based on which some output is created. The files to upload are produced by an external application and all lie in the same folder. I want the user to be able to select all files in the folder for upload and I am currently using
shiny::fileInput() with the option multiple = TRUE in the shiny App.
The problem I have is that the output folder contains a file that can be quite large and that is not required for the analysis in the app. The app works fine if the user just deselects that file in the upload menu. But I was wondering if there is a way that I can tell the app to ignore a certain file (based on the file name), so that even if the user selects all files in the folder for upload, the large file is not uploaded while all the other selected files still are.
I know that you can set a maximum file size in the options (shiny.maxRequestSize) but this does not seem to solve my problem, as the upload then ends with an error if the large file is selected.
Here is a minimal example of the app:
library(shiny)
options(shiny.maxRequestSize = 30*1024^2)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
# Upload menu is created here:
fileInput(
inputId = "upload",
label = "Upload Files",
buttonLabel = "Select files...",
multiple = TRUE
)
),
mainPanel(
tableOutput(outputId = "files")
)
)
)
server <- function(input, output, session) {
output$files <- renderTable(
input$upload[, c("name", "size")]
)
}
shinyApp(ui, server)
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)
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)
})
})
)
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)
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