Reading in a File in R Shiny

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:

  1. In UI part I passed "" to the choice argument in selectInput, because as @gdevaux mentioned, you cannot use in this way data from server in UI.
  2. I have added session parameter to server function - it is necessary for update* functions.
  3. I have added updateSelectInput() inside observer - it will update selectInput if data() won't be NULL.
  4. As @gdevaux did, I have changed your choices = data$carname into choices = data()$carname. It is because data as a reactive you need to use as a function.

Read a file after taking user input(selection) in Shiny

  1. (Since changed) Make the block containing file.path(.) a reactive block and assign it to something so that other reactive components can use it. In your case, you changed it to Output_loc, so other blocks will refer to it as Output_loc().

  2. Similarly, you cannot put output$... <- assignments or render* calls inside an observe or observeEvent block. So we'll move your output$fileselection_statement outside of the observeEvent.

  3. renderPrint is its own rendering function, on the same level as renderTable. You cannot nest them. In this case, I'm just going to remove them from inside the renderTable call, they make no sense there.

  4. This case did not need selectfile <- reactive(get(input$selectfile)), there is no apparent gain in that indirection. Just use input$selectfile. Removed.

  5. After fixing all of the above, it is also the case that you were updating the selectInput every time the selectInput was changed, which is incorrect (and completely disallows any real use of this). Instead, you want to update it when the Updated_Output_files_list() changes.

  6. 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 because selectInput displays the name but returns the value (full path). There is rarely a time when I think not specifying full.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



Leave a reply



Submit