Got error in fread function when building shiny app - r

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)
})
}

Related

Detect columns in an uploaded csv in R shiny app

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)

RShiny and Modules output. Object of type environment is not subsettable

Dear people of sackoverflow,
I am currently trying to create an app where a user can upload a dataset from various sources. I tried to isolate the code for the upload in a separate Shiny module. However, R throws an error saying that an environment object is not subsettable. I am fairly new to shiny so would appreciate any advice regarding the use of modules too. :)
library(shiny)
fileInputUI <- function(id){
ns <- NS(id)
fileInput(
inputId = ns("file"),
label = "Select a file"
)
}
fileInputServer <- function(id){
moduleServer(id, function(input, output, session){
dataset <- reactive({
req(input$file)
# Get file extension and datapath
ext <- tools::file_ext(input$file$name)
datapath <- input$file$datapath
# Need reactive values to store input data in
read_data_options <- reactiveValues()
read_data_options$sep <- NULL
if(ext == "csv"){
choices_sep <- c(",", ";", "", "\\t")
names(choices_sep) <- c("Comma (,)", "Semicolon (;)", "White space ( )", "Tab separated (\\t)")
showModal(
ui = modalDialog(
selectInput(
inputId = NS(id, "sep"),
label = "Which separator is used for your data",
choices = names(choices_sep),
selected = ""
),
# Input is required so no dismiss button
footer = tagList(
modalButton("Dismiss"),
actionButton(
inputId = NS(id, "submit_csv"),
label = "Submit")
),
easyClose = TRUE
)
)
# Set input value from submit button
observeEvent(
eventExpr = input$submit_csv,
handlerExpr = {
read_data_options$sep <- choices_sep[input$sep]
removeModal()
read.csv(
file = datapath,
sep = read_data_options$sep
)
}
)
} else {
NULL
}
})
dataset
})
}
# Shiny App
ui <- fluidPage(
fileInputUI("test"),
tableOutput("head_data")
)
server <- function(input, output, session) {
dataset <- fileInputServer("test")
output$head_data <- renderTable(head(dataset()))
}
shinyApp(ui, server)
I used modalDialog because I figured it to be the simplest approach to asking users about additional inputs to the read function for example the separator in case of read.csv or the startRow for read.xlsx etc.
Thanks for your replies

How to read csv file and render UI?

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.

Error in R shiny subsetting dataframe based on CSV file

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)

Download file from server to local directory using Shiny

I am not sure if I am understanding this correctly. Where should the data set that I want to download be in RStudio server? I do not want to deploy yet, so I am not using the Shiny server, but I want to use the download functionality and save the data set as a file in a local directory.
I have uploaded a file using Shiny fileInput and I have saved the file using copy.file(). I was told that the uploaded file is saved to the server. The file is called 0.tsv. Afterwards, I read that file and download it. The GUI works, but the file doe not get written to a file and saved to the local directory. My question is: is there any thing missing in my approach?
library(shiny)
ui <- fluidPage(
titlePanel('File download'),
sidebarLayout(
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("data")),
radioButtons("filetype", "File type:",
choices = c( "tsv")),
downloadButton('downloadData', 'Download')
),
mainPanel(
tableOutput('table')
)
)
)
function(input, output) {
datasetInput <- reactive({
# Fetch the appropriate data object, depending on the value
# of input$dataset.
data <- read.table("home/user/0.tsv")
switch(input$dataset,
"data" = data)
})
output$table <- renderTable({
datasetInput()
})
# downloadHandler() takes two arguments, both functions.
# The content function is passed a filename as an argument, and
# it should write out data to that filename.
output$downloadData <- downloadHandler(
# This function returns a string which tells the client
# browser what name to use when saving the file.
filename = function() {
paste(input$dataset, input$filetype, sep = ".")
},
# This function should write data to a file given to it by
# the argument 'file'.
content = function(file) {
sep <- switch(input$filetype, "tsv" = "\t")
# Write to a file specified by the 'file' argument
write.table(datasetInput(), file, sep = sep,
row.names = FALSE)
}
)
}
shinyApp(ui = ui, server = server)
ui <- fluidPage(
titlePanel('File download'),
sidebarLayout(
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("data")),
radioButtons("filetype", "File type:",
choices = c( "tsv")),
downloadButton('downloadData', 'Download')
),
mainPanel(
tableOutput('table')
)
)
)
function(input, output) {
datasetInput <- reactive({
# Fetch the appropriate data object, depending on the value
# of input$dataset.
data <- read.table("home/user/0.tsv")
switch(input$dataset,
"data" = data)
})
output$table <- renderTable({
datasetInput()
})
# downloadHandler() takes two arguments, both functions.
# The content function is passed a filename as an argument, and
# it should write out data to that filename.
output$downloadData <- downloadHandler(
# This function returns a string which tells the client
# browser what name to use when saving the file.
filename = function() {
paste(input$dataset, input$filetype, sep = ".")
},
# This function should write data to a file given to it by
# the argument 'file'.
content = function(file) {
sep <- switch(input$filetype, "tsv" = "\t")
# Write to a file specified by the 'file' argument
write.table(datasetInput(), file, sep = sep,
row.names = FALSE)
}
)
}
shinyApp(ui = ui, server = server)
Thanks very much for your response. Below is the correct way to do it. This works fine.
server <- function(input, output) {
# Reactive value for selected dataset ----
datasetInput <- reactive({
switch(input$dataset,
"params" = params)
})
# Table of selected dataset ----
output$table <- renderTable({
datasetInput()
})
# Downloadable csv of selected dataset ----
output$downloadData <- downloadHandler(
filename = function() {
paste(input$dataset, ".csv", sep = "")
},
content = function(file) {
write.table(datasetInput(), file, row.names = FALSE)
}
)
}

Resources