Reading in a file in R Shiny
There is a good example here http://shiny.rstudio.com/gallery/file-upload.html. But for completeness, I've included the working answer below. The key point is that you should reference the file using file$datapath
, and also to check if input is NULL (when user hasn't uploaded a file yet).
server.R
#server.R
library(shiny)
shinyServer(function(input, output) {
observe({
file1 = input$file1
file2 = input$file2
if (is.null(file1) || is.null(file2)) {
return(NULL)
}
data1 = read.csv(file1$datapath)
data2 = read.csv(file2$datapath)
output$plot <- renderPlot({
plot(data1[,1],data2[,2])
})
})
})
ui.R
library(shiny)
#ui.R
# Define UI for random distribution application
shinyUI(fluidPage(
# Application title
titlePanel("ORR Simulator"),
# Sidebar with controls to select the random distribution type
# and number of observations to generate. Note the use of the
# br() element to introduce extra vertical spacing
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Select the XXX.csv file',
accept=c('text/csv','text/comma-separated-values,text/plain','.csv')),
tags$hr(),
fileInput('file2', 'Select the YYY.csv file',
accept=c('text/csv','text/comma-separated-values,text/plain','.csv')),
tags$hr(),
numericInput("S", "Number of simulations to run:", 100)
),
mainPanel(
plotOutput("plot")
)
))
)
R+Shiny: read file and use its content
This code loads the file straight into the output table and doesn't really store the raw table anywhere. This snippet of code is actually loading the file:
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
You can use this outside of the renderTable({}) to load the file just as a normal variable and do whatever you want with it.
However, if you set this code straight into the server function, it won't work - since this is a user input, you should set this variable as reactive, so I would do something like this:
df = reactive({
req(input$file1)
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
return(df)
})
Then you can call df() and do whatever you want with it. Ofc it would be nice to add try statements or some checks to make sure the file can be loaded properly, like the in the renderTable({}).
So the server side should look like this:
server <- function(input, output) {
df = reactive({
req(input$file1)
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
return(df)
})
output$contents <- renderTable({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, head of that data file by default,
# or all rows if selected, will be shown.
req(input$file1)
# when reading semicolon separated files,
# having a comma separator causes `read.csv` to error
tryCatch(
{
df <- read.csv(input$file1$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
},
error = function(e) {
# return a safeError if a parsing error occurs
stop(safeError(e))
}
)
if(input$disp == "head") {
return(head(df))
}
else {
return(df)
}
})
}
Read file in Shiny App
Simply replace data$path
with data$datapath
. Shiny uses datapath
to access the actually file address when using fileInput
.
For future reference, I find that an easy way to debug shiny inputs is assign(..., envir = globalenv())
to save an input to the global environment for inspection outside of the app.
Your example app functions with that single change:
ui <- fluidPage(
fileInput("file","import file"),
tableOutput("tb")
)
server <- function(input,output){
output$tb <-renderTable({
data <- input$file
# assign('datainput', data, envir = globalenv()) ## writes data to global environment as "datainput" for inspection.
if(is.null(data)){return()}
read.table(data$datapath,sep="")
})
}
shinyApp(ui=ui, server=server)
How do I make a Shiny app read continuously from a file?
By using invalidateLater() function we can do this.
require(shiny)
ui <- fluidPage(
h5(textOutput("calc1"))
)
server <- function(input, output, session) {
df <- reactive({
invalidateLater(120000, session) # equivalent milliseconds for 2 minutes
x1 <- 42
df.data <- read.csv("data.csv")
df.data$y2 <- df.data$y1/x1
return(df.data)
})
output$calc1 <- renderText({
az <- nrow(df())
aa <- az - 5
y5m <- mean(df()$y2[aa:az], na.rm = TRUE)
})
}
shinyApp(ui=ui, server=server)
How to read a csv file in Shiny?
I added comments to the faulty steps.
library(shiny)
ui <- fluidPage(
titlePanel("Case Referrals"),
sidebarLayout(
sidebarPanel(
fileInput("file", "Select a file"),
# you cannot call data() in your ui.
# You would have to wrap this in renderUI inside of your server and use
# uiOutput here in the ui
sliderInput("period", "Time period observed:", min = 1, max = 10, value = 5)
),
mainPanel(
DT::dataTableOutput("table")
)
)
)
# Define the server logic
server <- function(input, output) {
input_file <- reactive({
if (is.null(input$file)) {
return("")
}
# actually read the file
read.csv(file = input$file$datapath)
})
output$table <- DT::renderDataTable({
# render only if there is data available
req(input_file())
# reactives are only callable inside an reactive context like render
data <- input_file()
data <- subset(data, dateCreated >= input$period[1] & dateCreated <= input$period[2])
data
})
}
shinyApp(ui = ui, server = server)
How to access R Shiny Input(uploaded) file in another input module?
This is not necessary and also I would say not recommend in this case to use renderUI
. updateSelectInput()
will be faster (Make R Shiny Dashboards Faster with updateInput, CSS, and JavaScript) and require less rewriting of code:
library(shiny)
ui <- fluidPage(
headerPanel("Webpapp"),
sidebarPanel(
fileInput(inputId = "filedata",
label = "Upload the Raw Data File",
accept = c("text/csv", "text/comma-separated-values,text/plain",
".csv")),
selectInput("cars", "Select car:", choices = "", selected = "Nissan Sentra"),
),
mainPanel(
plotOutput('plot'),
)
)
# Define server code ####
server <- function(session, input, output) {
data <- reactive({
req(input$filedata)
read.csv(input$filedata$datapath, skip = 15, header = F)
})
observe({
req(data())
updateSelectInput(session, "cars", choices = data()$carname)
})
output$plot <- renderPlot({
if (is.null(data())) {
return(NULL)
}
plot_probe(input$cars) #Plotting function in global
})
}
shinyApp(ui = ui, server = server)
What I have changed:
- In UI part I passed
""
to thechoice
argument inselectInput
, because as @gdevaux mentioned, you cannot use in this way data fromserver
inUI
. - I have added
session
parameter toserver
function - it is necessary forupdate*
functions. - I have added
updateSelectInput()
insideobserver
- it will updateselectInput
ifdata()
won't beNULL
. - As @gdevaux did, I have changed your
choices = data$carname
intochoices = data()$carname
. It is becausedata
as areactive
you need to use as a function.
Read a file after taking user input(selection) in Shiny
(Since changed) Make the block containing
file.path(.)
areactive
block and assign it to something so that other reactive components can use it. In your case, you changed it toOutput_loc
, so other blocks will refer to it asOutput_loc()
.Similarly, you cannot put
output$... <-
assignments orrender*
calls inside anobserve
orobserveEvent
block. So we'll move youroutput$fileselection_statement
outside of theobserveEvent
.renderPrint
is its own rendering function, on the same level asrenderTable
. You cannot nest them. In this case, I'm just going to remove them from inside therenderTable
call, they make no sense there.This case did not need
selectfile <- reactive(get(input$selectfile))
, there is no apparent gain in that indirection. Just useinput$selectfile
. Removed.After fixing all of the above, it is also the case that you were updating the
selectInput
every time theselectInput
was changed, which is incorrect (and completely disallows any real use of this). Instead, you want to update it when theUpdated_Output_files_list()
changes.Also, instead of repeatedly concatenating the path together to create the file to be read, I use
list.files(..., full.names=TRUE)
. This will be a named vector, where the values are the full path and filename, but the names will be just the filename (no leading path). This useful becauseselectInput
displays the name but returns the value (full path). There is rarely a time when I think not specifyingfull.names=TRUE
is the right thing (I cannot think of any right now).
Here's a working copy. It is not perfectly-awesome, there are still areas where some grooming might be in order.
server <- function(input, output, session) {
# Location for Outputs
Output_DIR <- "K:/Outputs/"
Output_loc <- reactive({
year_N_ME_DATE <- format(input$ME_DATE, "%Y")
month_N_ME_DATE <- format(input$ME_DATE, "%m")
month_T_ME_DATE <- months(input$ME_DATE)
file.path(Output_DIR,
paste0(month_N_ME_DATE, ". ", month_T_ME_DATE, " ", year_N_ME_DATE),
"/")
})
# alternative
# Output_loc <- reactive({
# file.path(Output_DIR, format(Sys.Date(), format = "%m. %b %Y"))
# })
# Output Path
output$Output_path <- renderPrint({ req(Output_loc()) })
# files list
Updated_Output_files_list <- reactive({
lf <- list.files(Output_loc(), full.names = TRUE)
names(lf) <- basename(lf)
# in this example, 'lf' is now:
# c(iris.csv = "K:/Outputs/05. May 2020/iris.csv", mtcars.csv = "K:/Outputs/05. May 2020/mtcars.csv")
# ... the *name* will be displayed in the selectInput, but the
# *full path* will be the value of the selection
lf
})
output$fileselection_statement <- renderText({
paste0('You have selected: ', input$selectfile)
})
observeEvent(Updated_Output_files_list(), {
updateSelectInput(session, "selectfile", choices = Updated_Output_files_list())
})
output$selected_table <- renderTable({
req(input$selectfile)
read.csv(input$selectfile)
})
}
How can I read an input file into shiny?
You have a few options here. I assume you know how to read the file into R using read.csv
or something similar.
You can put the input the read.csv
in one of three places:
1) Globlal.r: If you have a global.r
file you can use read.csv
there and the data will be directly available to both the ui
and the server
functions. Typically you do not need to do this but it is an option.
For the next two options the data will be directly available to the server
side, but must be passed to the ui
side through one of the render
functions.
2)Server.r but NOT in shinyServer: In this case the read.csv
is located in server.r
file but outside of the shinyServer()
function. The file will be read in one time per session and will not change. This is a common place to read in data.
3) Server.r and in shinyServer: In this case the read.csv
is part of theshinySever()
function. This is a good place to read the data if you want some degree of reactivity to be involved. For example, if the user chooses which data to input or if the data file is constantly updating (stock prices maybe) and you want to check the data file periodically for updates while the user is working.
Note: You also need to consider where the data is stored. You can put it in a subdirectory of your app directory and then read it is using a relative (not absolute) path. This is helpful if you are testing your app on your desktop, but are going to deploy it elsewhere and don't wish to rewrite the code to take the new directory structure into account.
R Shiny: How to read different CSV file based of user input?
input$input_type
is the name of the file, but to specify the complete path we need to paste some strings together. read.csv
can be used like this:
read.csv(paste0('~/Test/', input$input_type, '.csv'))
Sample Shiny App:
library(shiny)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(selectInput("input_type","Select Month:", c("Oct 2021", "Nov 2021")),
actionButton('load_csv', 'Load csv')),
mainPanel(dataTableOutput('dt'))
)
)
server <- function(input, output, session) {
data <- eventReactive(input$load_csv, {
read.csv(paste0('~/Test/', input$input_type, '.csv'))
})
output$dt <- renderDataTable({
req(data())
datatable(
data()
)}
)
}
shinyApp(ui, server)
Related Topics
Geom_Density to Match Geom_Histogram Binwitdh
Why Is Subsetting on a "Logical" Type Slower Than Subsetting on "Numeric" Type
Subset Data.Table by Logical Column
Can't Run Rcpp Function in Foreach - "Null Value Passed as Symbol Address"
Get the Index of the Values of One Vector in Another
Using R to Download Newest Files from Ftp-Server
How to Find Common Rows Between Two Dataframe in R
In R, How to Check If Two Variable Names Reference the Same Underlying Object
Change Plotly Chart Y Variable Based on Selectinput
Overlay Geom_Points() on Geom_Boxplot(Fill=Group)
Time Series Plot with X Axis in "Year"-"Month" in R
Using R Convert Data.Frame to Simple Vector
Skip Some Rows in Read.CSV in R
Can 'Ddply' (Or Similar) Do a Sliding Window
How to Manually Change the Key Labels in a Legend in Ggplot2