I am working on a shiny app that requires a Excel with multiple sheets as an input. It was working well with the xlsx library and read.xlsx function. However, it returns the following error:
java.lang.IllegalArgumentException: Cell index must be >= 0
I've now switched to gdata and read.xls, but I get a file path error every time I run the model.
I wonder if anyone dealt with this problem before and if there are any simple solutions to fix this problem.
EDIT:
The following code
library(shiny)
library(xlsx)
ui <- fluidPage(
fileInput("uploadFile", "XLSX file"),
verbatimTextOutput("summary")
)
server <- function(input, output) ({
dataset<-reactive({
inFile <- input$uploadFile
dat<-read.xlsx(inFile$datapath, 1)
return(dat)
})
output$summary <- renderText({summary(dataset())})
})
shinyApp(ui, server)
Returns:
Error : package ‘rJava’ could not be loaded
If, instead I use
library(shiny)
library(readxl)
ui <- fluidPage(
fileInput("uploadFile", "XLSX file"),
verbatimTextOutput("summary")
)
server <- function(input, output) ({
dataset<-reactive({
inFile <- input$uploadFile
dat<-read_excel(inFile$datapath, sheet = 1)
return(dat)
})
output$summary <- renderText({summary(dataset())})
})
shinyApp(ui, server)
I get:
Error: Missing file extension.
(Using readxl)
The datapath column from input$uploadFile is a path to a temp file which has no extension. So read_excel() does not know what format it is.
Use read_xlsx() instead:
dat <- read_xlsx(inFile$datapath, sheet = 1)
I just tried this and it worked fine for me.
library(shiny)
library(readxl)
runApp(
list(
ui = fluidPage(
titlePanel("Use readxl"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx")
)
),
mainPanel(
tableOutput('contents'))
)
),
server = function(input, output){
output$contents <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
file.rename(inFile$datapath,
paste(inFile$datapath, ".xlsx", sep=""))
read_excel(paste(inFile$datapath, ".xlsx", sep=""), 1)
})
}
)
)
Also, see this.
https://shiny.rstudio.com/gallery/file-upload.html
Related
I am trying to upload an xlsx file using shiny rstudio. But the data can't be read in. Can anyone help me figure it out?
ui <- fluidPage(titlePanel("AFSI Data Reformat"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx"))),
mainPanel(
tableOutput('file2'))))
Server(function(input, output) {
output$file2 <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
read_excel(paste(inFile$datapath, ".xlsx", sep=""), 1)})
When I clicked 'Run App', and the tried to upload an
xlsx file, it shows nothing was read in, 'No file uploaded'.
Works fine for me after removing the instruction that adds a second ".xlsx" extension to file name :
ui <- fluidPage(titlePanel("AFSI Data Reformat"),
sidebarLayout(sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx"))
),
mainPanel(tableOutput('file2'))))
server <- function(input, output) {
output$file2 <- renderTable({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
readxl::read_excel(inFile$datapath)
})
}
shinyApp(ui, server)
With the outputs I can upload a spreadsheet and use the filename as a reference for some functions in my application. However, I can't "transport" this name to the "checkboxGroupInput" function (where it says "Sheet_Name"). How could I make the sheet name auto-fill in the field after upload? Thanks.
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(readxl)
library(tidyverse)
library(readxl)
library(stringr)
ui <- fluidPage(
br(),
fileInput("archive", "Upload file", accept = c(
".xlsx")),
textOutput("my_archive"),
# Itens Selection
checkboxGroupInput("additem", "Select Items", names(BancoEA))
)
server <- function(input, output) {
# Upload Data Sheet
csv <- reactive({
inFile <- input$archive
if (is.null(inFile))
return(NULL)
df<- read.xlsx(inFile$datapath, header=T)
return(df)
})
# Remove Extension Name
output$my_archive <- renderText({
# Test if file is selected
if (!is.null(input$x$datapath)) {
return(sub(".xlsx$", "", basename(input$archive$name)))
} else {
return(NULL)
}
})
}
# App
shinyApp(ui, server)
As #arashHaratian pointed out, you can use updateChecGroupInput() inside an observer to update the choices based on the uploaded file.
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(readxl)
library(tidyverse)
library(readxl)
library(stringr)
ui <- fluidPage(
br(),
fileInput("archive", "Upload file", accept = c(
".xlsx")),
#textOutput("my_archive"),
# Itens Selection
checkboxGroupInput("additem", "Select Items", choices = NULL)
)
server <- function(input, output, session) {
# Upload Data Sheet
csv <- reactive({
req(input$archive)
inFile <- input$archive
df <- read_xlsx(inFile$datapath)
return(df)
})
#reactive value that will hold the name of the file
reactive_my_path <- reactive({
# Test if file is selected
req(input$archive)
return(sub(".xlsx$", "", basename(input$archive$name)))
})
# output$my_archive <- renderText({
# reactive_my_path()
# })
observe({
input$archive
#update the choices in input$additem
updateCheckboxGroupButtons(session,
"additem",
paste('Column names in:', reactive_my_path()),
choices = names(csv()))
})
}
# App
shinyApp(ui, server)
Another solution would be to directly render the input with renderUI inside the server and uiOutput inside the ui.
In my Shiny app, I can upload an xlsx file and select sheet by typing the sheet's name:
library(shiny)
library(openxlsx)
runApp(
list(
ui = fluidPage(
titlePanel("openxlsx - choose sheet"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx"))),
mainPanel(tableOutput('contents'),
textInput("tab1", "Type in sheet name:", "Sheet1")))),
server = function(input, output,session){
output$contents <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
file.rename(inFile$datapath,paste(inFile$datapath, ".xlsx", sep=""))
read.xlsx(paste(inFile$datapath, ".xlsx", sep=""), sheet=input$tab1)
})}))
I would prefer to be able to use a drop-down menu to select a sheet. I know I can use openxl package to get the sheets names, but I am not sure how to implement that in Shiny. Any help will be appreciated.
In the UI:
uiOutput("dropdownUI")
In the server:
Workbook <- eventReactive(input$file1, {
loadWorkbook(input$file1$datapath)
})
Sheets <- eventReactive(Workbook(), {
names(Workbook())
})
output$dropdownUI <- renderUI({
req(Sheets())
selectInput("sheet", "Choose a sheet", Sheets())
})
Dat <- eventReactive(input$sheet, {
read.xlsx(Workbook(), sheet = input$sheet)
})
output$contents <- renderTable({
req(Dat())
Dat()
})
I want to upload a dataframe, call r scipt and apply a function that updates the dataframe, then download it. Can anyone help me?
Let's say this is the function I need to call
Identify_IP(dataframe)
return(dataframe')
This is Shiny App
library(shiny)
source('InflectionP2.R', local = TRUE)
runApp(
list(
ui = fluidPage(
titlePanel("Upload your file"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xls file',
accept = c(".XLS")),
actionButton("btn", "Update Table")
),
mainPanel(
tableOutput('what'))
)
),
server = function(input, output, session){
dataframe <- reactive({
inFile <- input$file1
if (is.null(input$file1))
return(NULL)
Identify_IP(read.table(inFile$datapath, header=input$header, sep=input$sep, quote=input$quote))
})
observeEvent(input$btn, {output$what <- renderTable({dataframe})})
}
)
)
This is what I get
Warning: Error in as.data.frame.default: cannot coerce class "c("reactiveExpr", "reactive")" to a data.frame
As, I am new to shiny apps need some assistance, uploading excel file and generating table output in shiny app works fine, but can't able to download the plot to a pdf format
Here is my code
library(shiny)
library(openxlsx)
library(lattice)
runApp(
list(
ui = fluidPage(
titlePanel("plots"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx")),
tags$hr(),
downloadButton('down',"download plot")
),
mainPanel(
tableOutput('contents'),
plotOutput('plot'))
)
),
server = function(input, output){
output$contents <- renderTable({
inFile <- input$file1
if(is.null(inFile))
return(NULL)
else
read.xlsx(inFile$datapath)
})
plotInput <- reactive({
df <- input$file1
xyplot(df[,2]~df[,1],df(),xlim=c(0,10),ylim=c(0,100),type = "b")
})
output$plot <- renderPlot({
print(plotInput())
})
output$down <- downloadHandler(
filename = function(){paste("plot",".pdf",sep=".") },
content = function(file) {
pdf(file)
xyplot(df[,2]~df[,1],df(),xlim=c(0,10),ylim=c(0,100),type = "b")
dev.off()
}
)
}
)
)
The problem was that in some parts of your code you were accessing a dynamic data frame via df() but you had never defined it.
In this kind of problem, it is best to create a reactive data frame, say, df which contains the uploaded data and is passed to other reactive parts of the code via df().
Full example:
library(shiny)
library(openxlsx)
library(lattice)
runApp(
list(
ui = fluidPage(
titlePanel("plots"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx")),
tags$hr(),
downloadButton('down',"download plot")
),
mainPanel(
tableOutput('contents'),
plotOutput('plot'))
)
),
server = function(input, output){
df <- reactive({
inFile <- input$file1
req(inFile) # require that inFile is available (is not NULL)
# (a user has uploaded data)
# read.xlsx(inFile$datapath)
head(iris, 10)
})
output$contents <- renderTable({
# access uploaded data via df()
df()
})
plotInput <- reactive({
df <- df()
xyplot(df[,2]~df[,1], df ,xlim=c(0,10),ylim=c(0,100),type = "b")
})
output$plot <- renderPlot({
plotInput()
})
output$down <- downloadHandler(
filename = function(){paste("plot",".pdf",sep=".") },
content = function(file) {
pdf(file)
#xyplot(df[,2]~df[,1],df(),xlim=c(0,10),ylim=c(0,100),type = "b")
# you have to print the plot so that you can open pdf file
print(plotInput())
dev.off()
}
)
}
)
)