I Am creating a dynamic update in R shiny with the following code using the iris dataset
write.csv(iris, file = "iris.csv", row.names = F)
# to create a local version of iris dataset
# next create UI
ui <- fluidPage(
fileInput("file", "Browse",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
selectInput(inputId = "Speciesname", label = "Name",choices =
NULL,selected = NULL),
tableOutput("data")
)
#Create server
server <- function(input, output,session) {
df = reactive({
req(input$file)
return(read.csv(input$file$datapath))
})
observe({
choices1 = unique(df()$Species)
updateSelectInput(session,"Speciesname", choices = choices1)
})
output$data <- renderTable({
req(input$Speciesname)
df[as.character(input$Speciesname), ]
}, )
}
#Run app
shinyApp(ui, server)
I am able to read the file in. The subsetting however is showing the following error and the shiny app
Warning: Error in [: object of type 'closure' is not subsettable
[No stack trace available]
I am unable to understand or sort this error out. The code runs when I dont use a local copy of the dataset but use the built in R iris dataset. I request someone to guide me here
This should do the job
library(shiny)
write.csv(iris, file = "iris.csv", row.names = F)
# to create a local version of iris dataset
# next create UI
ui <- fluidPage(
fileInput("file", "Browse",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
selectInput(inputId = "Speciesname", label = "Name",choices =
NULL,selected = NULL),
tableOutput("data")
)
#Create server
server <- function(input, output,session) {
df = reactive({
req(input$file)
return(read.csv(input$file$datapath))
})
observe({
choices1 = unique(df()$Species)
updateSelectInput(session,"Speciesname", choices = choices1)
})
output$data <- renderTable({
req(input$Speciesname)
df()[df()$Species %in% input$Speciesname,]
})
}
#Run app
shinyApp(ui, server)
Related
I am trying to create a Shiny app to allow the user to upload a file and select a method. I would like the output to be returned/changed only when both the file is uploaded/changed and the method is selected/changed. In other words, I want the app to be silent when only one of the input variables is changed. Below I attached a demo code that will change the output when a file is modified/uploaded. I tried req(file, method), but it does not work after the file is uploaded (e.g., upload/update another file). Any suggestions will be appreciated.
Code to create two CSV files for the shiny app demonstration.
df <- data.frame(obs = 1:11)
df2 <- data.frame(obs = 10:20)
write.csv(df, file = "uploaddf.csv", row.names = F)
write.csv(df2, file = "uploaddf2.csv", row.names = F)
Shiny app demo
library(shiny)
ui <- fluidPage(
fluidRow(
column(5, fileInput(inputId = 'file',
label = 'Upload file',
multiple = FALSE)),
column(5, selectInput(inputId = 'method',
label = 'Select method',
list(`Method` = list("Method1", "Method2"))))
),
br(),
textOutput("printoutput")
)
server <- function(input, output, session) {
file <- reactive({
req(input$file)
filestr <- input$file
file <- read.csv(filestr$datapath, header = T)
return(file)
})
method <- reactive({
req(input$method)
method <- input$method
return(method)
})
observeEvent(file(), {
op <- paste0(sum(file()), method())
output$printoutput <- renderText({ op })
})
}
shinyApp(ui, server)
I'd suggest using bindEvent along with an actionButton to wait for the user input:
df <- data.frame(obs = 1:11)
df2 <- data.frame(obs = 10:20)
write.csv(df, file = "uploaddf.csv", row.names = F)
write.csv(df2, file = "uploaddf2.csv", row.names = F)
library(shiny)
ui <- fluidPage(
fluidRow(
column(5, fileInput(inputId = 'file',
label = 'Upload file',
multiple = FALSE)),
column(5, selectInput(inputId = 'method',
label = 'Select method',
list(`Method` = list("Method1", "Method2"))))
),
fluidRow(
column(5, actionButton(inputId = 'run', label = 'Render output', icon = icon("arrows-rotate")))
),
br(),
textOutput("printoutput")
)
server <- function(input, output, session) {
file <- reactive({
req(input$file)
filestr <- input$file
read.csv(filestr$datapath, header = T)
})
output$printoutput <- renderText({paste0(sum(file()), req(input$method))}) |> bindEvent(input$run)
}
shinyApp(ui, server)
PS: please try to avoid wrapping renderXXX functions in observers - they already are reactive.
Below I have an R Shiny code to upload an input file to the application. All csv files that'll be uploaded will have a column 'carname'. I want to have a dropdown that's able to access and select choices in that column. How do I access the uploaded file in the ui?
Error: Error in data$carname : object of type 'closure' is not subsettable
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 = data$carname, selected = "Nissan Sentra"),
),
mainPanel(
plotOutput('plot'),
)
)
# Define server code ####
server <- function(input, output) {
data <- reactive({
req(input$filedata)
read.csv(input$filedata$datapath, skip = 15, header = F)
})
output$plot <- renderPlot({
if (is.null(data())) {
return(NULL)
}
plot_probe(input$cars) #Plotting function in global
})
}
shinyApp(ui = ui, server = server)
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 the choice argument in selectInput, because as #gdevaux mentioned, you cannot use in this way data from server in UI.
I have added session parameter to server function - it is necessary for update* functions.
I have added updateSelectInput() inside observer - it will update selectInput if data() won't be NULL.
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.
You cannot access the uploaded file from the UI.
But you can create an UI element from the server, and send it to the UI with the functions renderUI and UIOutput.
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")),
uiOutput("ui_select")
),
mainPanel(
plotOutput('plot'),
)
)
# Define server code ####
server <- function(input, output) {
data <- reactive({
req(input$filedata)
read.csv(input$filedata$datapath, skip = 15, header = F)
})
# UI element for select input
output$ui_select <- renderUI({
req(data())
selectInput("cars", "Select car:", choices = data()$carname, selected = "Nissan Sentra")
})
output$plot <- renderPlot({
if (is.null(data())) {
return(NULL)
}
plot_probe(input$cars) #Plotting function in global
})
}
shinyApp(ui = ui, server = server)
I want to create a shiny app where one can upload a csv file and then select columns of that file. The problem is that after uploading a file, my code fails to update the column names for possible choices. Here is a reproducible example. Thank you!
ui <- fluidPage(
fileInput("file1",
"Please choose a csv File",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
div(style="display:inline-block", selectInput('var',
'Select the first var',
"") )
)
server <- function( input, output, session ) {
data <- reactive({
inFile <- input$file1
req(inFile)
validate(need(ext == "csv", "Please upload a csv file"))
df = read.csv(inFile$datapath,
header = input$header,
sep = input$sep,
quote = input$quote)
colnames <- names(df)
df
})
output$contents <- renderTable( {
updateSelectInput(session,
inputId = 'var',
label = 'Select the first var',
choices = colnames)
} ) }
shinyApp(ui = ui, server = server)
Some of your reactive expression aren't right, lets split things out to make it easier to follow. In particular use observeEvent to watch the file input.
library(shiny)
ui <- fluidPage(
fileInput("myfileinput", "Please choose a csv File", multiple = FALSE, accept = c("text/csv", "text/comma-separated-values,text/plain", ".csv")),
selectInput('myselectinput','Select the first var', ""),
tableOutput('mytable')
)
server <- function(input, output, session) {
#Reactive to store loaded data
reactives <- reactiveValues(
mydata = NULL
)
#Observe file being selected
observeEvent(input$myfileinput, {
#Store loaded data in reactive
reactives$mydata <- read.csv(file = input$myfileinput$datapath)
#Update select input
updateSelectInput(session, inputId = 'myselectinput', label = 'Select the first var', choices = colnames(reactives$mydata))
})
#Data table
output$mytable <- renderTable({
reactives$mydata
})
}
shinyApp(ui = ui, server = server)
I have a simple shiny app and when I press a button a .csv file is saved in the directory where the file app.R is.
I want to be able to read this csv file and render the information in a table on my shiny app.
This is a similiar example about what I would like to do
df <- data.frame(no =c(1:3),money=c(9999:10001),penalty=c(999:1001))
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV File",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
),
tags$hr(),
checkboxInput("header", "Header", TRUE),actionButton("sort","Do Sorting")
),
mainPanel(
tableOutput("contents"),tableOutput("sortedcontents")
)
)
)
server <- function(input, output) {
rawInputData = reactive({
rawData = input$file1
if(!is.null(rawData)) {
data = read.csv(rawData$datapath);
} else {
return(NULL);
}
});
output$contents <- renderTable({
newData = rawInputData()
if(is.null(newData))
return();
newData;
})
sorting = reactive({
if(input$sort){
newData = rawInputData()
newData$moneysort <- ifelse(newData$money >=10000, 1, 0)
newData$penaltysort <- ifelse(newData$penalty >=1000, 1, 0)
}
newData
})
output$sortedcontents <- renderTable({
newData = sorting()
if(is.null(newData))
return();
newData;
})
}
}
shinyApp(ui, server)
Instead to have the opportunity to choose the file with a fileInpunt() I would like to avoid this step and automatically check a specific directory to look for the csv called "myData.csv" and render this csv in a table.
Here is an example of just reading data from local directory and rendering in shiny.
library(shiny)
write.csv(iris, 'iris.csv')
df = read.csv('iris.csv')
shinyApp(
ui = fluidPage(
fluidRow(
column(12,
tableOutput('iris_table')
)
)
),
server = function(input, output) {
output$iris_table <- renderTable(df)
}
)
This example uses a slight modification from this shiny TableOutput reference.
I supposed to read file from fileInput but when I ran the app I got this error:
Warning: Error in fread: input= must be a single character string containing a file name, a system command containing at least one space, a URL starting 'http[s]://', 'ftp[s]://' or 'file://', or, the input data itself containing at least one \n or \r
My Shiny Code:
library(shiny)
library(data.table)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file","Operation Record",
multiple = TRUE,
buttonLabel = "Browse...",
placeholder = "No file selected",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
)
),
mainPanel(
DTOutput("table")
)
)
)
server <- function(input, output) {
output$table <- renderDT({
originalDataset <- fread(input = input$file$datapath,encoding = "UTF-8",
select = c("Date","ID","Type","EMail","ClientType"))
return(originalDataset)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Any suggestions?Thank you in advance.
When you run the app, input$file is NULL, until you select a file. You need a req:
server <- function(input, output) {
output$table <- renderDT({
req(input$file)
originalDataset <- fread(input = input$file$datapath,encoding = "UTF-8",
select = c("Date","ID","Type","EMail","ClientType"))
return(originalDataset)
})
}