问题
I am trying to load the data from .RData file on my computer and I am trying to run a shiny application for that. My code is below, but when I run it I get error "Can not open connection".. Why this error?
library(shiny)
ui <- fluidPage(
tableOutput("table")
)
server <- function(input, output, session) {
dataset <- reactive({
if (inFile == "")
return(NULL)
get(inFile$file1, load("E:/RProjects/Dashboard/gender1.RData"))
})
output$table <- renderTable({
if (is.null(dataset()))
return(NULL)
head(dataset(), 10)
})
}
shinyApp(ui, server)
Sample data:
structure(list(Gender = c("Male", "Male", "Male", "Male", "Male",
"Male", "Male", "Male", "Male", "Male"), Height = c(73.847017017515,
68.7819040458903, 74.1101053917849, 71.7309784033377, 69.8817958611153,
67.2530156878065, 68.7850812516616, 68.3485155115879, 67.018949662883,
63.4564939783664), Weight = c(241.893563180437, 162.3104725213,
212.7408555565, 220.042470303077, 206.349800623871, 152.212155757083,
183.927888604031, 167.971110489509, 175.92944039571, 156.399676387112
), BMI = c(0.0443566151469252, 0.0343082174614673, 0.0387343292394288,
0.0427654457094595, 0.0422547891767963, 0.033653156898047, 0.0388739862001733,
0.0359564180086832, 0.039169072415755, 0.0388404008602306), probability = c(5.77831234737499e-06,
0.605952546493327, 2.62595199514618e-05, 0.000362873417265588,
0.00461190097404834, 0.911068673692331, 0.0496119303175197, 0.352335117615303,
0.139124546478089, 0.343426515632885)), row.names = c(NA, 10L
), class = "data.frame")
回答1:
As Vishesh says, I think you might be needing to use readRDS
instead of load
, but here's a shiny
app that allows all three: csv, rds, or rda.
First, quick debugging setup so we have three types of files to test with:
write.csv(mtcars, file="mt.csv")
saveRDS(mtcars, file="mt.rds")
save(mtcars, file="mt.rda")
(Certainly not needed for a production app.)
Now the app:
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("file1", "Choose CSV, rda, or rds File"),
tags$hr(),
checkboxInput("header", "Header (if CSV)", TRUE),
uiOutput("rda_objname")
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
file1_ <- reactive({
req(input$file1)
# might also work with input$file1$type, which is something like
# 'application/vnd.ms-excel', though for me in testing this was
# blank for RDS/RDA ...
a <- input$file1
a$ext <- tolower(tools::file_ext(input$file1$name))
# ... though length==1 since we did not do multiple = TRUE
a$ext <- ifelse(a$ext == "rdata", "rda", a$ext)
a
})
rawdat <- reactive({
req(file1_())
inFile <- file1_()
# if we ever do fileInput(..., multiple = TRUE), this will need to
# be on a vector of length > 1
if ("csv" == inFile$ext) {
return( read.csv(inFile$datapath, header = input$header) )
} else if ("rds" == inFile$ext) {
return( readRDS(inFile$datapath) )
} else if (inFile$ext == "rda") {
e <- new.env(parent = emptyenv())
load(inFile$datapath, envir = e)
return( e )
} else return( NULL )
})
output$rda_objname <- renderUI({
# this only displays a select-input if the input file is valid and
# an Rdata-looking file, otherwise the select-input is absent
req(file1_())
inFile <- file1_()
if (inFile$ext == "rda") {
obj <- isolate(ls(envir = rawdat()))
selectInput("objname", "RDA object name",
choices = c("Select object name ...", obj))
} else return( NULL )
})
dat <- reactive({
req(rawdat())
inFile <- isolate(file1_())
if (inFile$ext == "rda") {
req(input$objname, input$objname %in% ls(envir = rawdat()))
return( get(input$objname, envir = rawdat()) )
} else return( rawdat() )
})
output$contents <- renderTable({
req(dat())
dat()
})
}
shinyApp(ui, server)
If you select a CSV or RDS file in the fileInput
, then it will automatically render the table. If it ends in .rda
or .rdata
(case-insensitive), then it will create a selector to choose which object within the rda file (since they really store environments with named objects, not a single object).
Demo: with CSV or RDS:
With an RDA file (that has a single object in it, mtcars
:
Some other changes from your code:
- instead of using
if (is.null(...))
, I'm using the moreshiny
-esquereq(...)
methodology; it's a little more user-friendly when things don't go as you (the dev) intended; - I've intentionally
isolate
d a few things that might stand to not be isolated, but I wanted a clear path of reactivity; it is possible if A depends on B and C depends on both A and B that, when A updates, C will update, then B will update, causing C to update again ... dizzying, perhaps, but a consequence of multiple dependency paths. - Because this accepts both types of storage (one object and multi), I need a two-step to retrieve the data:
rawdat()
might be an environment (RDA) or an actual objecvt;dat()
will always be an object orNULL
(if RDA and an object name is not selected). - I don't need the
else return(NULL)
inoutput$rda_objname
, I just have it there for clarity and explicit code in this example; I likely would not have it in my production code. - I also use
return
a lot here; technically, it is not required in any of these uses, again I'm just being explicit for this example.
回答2:
I'd recommend using readRDS
for reading RData files. Also, you need to specify a fileInput
UI element which the user can use to browse to the data file.
library(shiny)
ui <- fluidPage(
fileInput("file", label = "Rdata"),
tableOutput("table")
)
server <- function(input, output, session) {
dataset <- reactive({
req(input$file)
inFile <- input$file
readRDS(inFile$datapath)
})
output$table <- renderTable({
if (is.null(dataset()))
return(NULL)
head(dataset(), 10)
})
}
shinyApp(ui, server)
The link you mentioned in the comment explains the usage of req
which prevents error in your app when the it loads and the user hasn't yet selected the data source.
来源:https://stackoverflow.com/questions/53245947/error-running-shiny-app-can-not-open-connection