简体   繁体   中英

error running shiny app “can not open connection”

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

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:

带有RDS文件的闪亮演示

With an RDA file (that has a single object in it, mtcars :

带有RDA文件的闪亮演示

Some other changes from your code:

  • instead of using if (is.null(...)) , I'm using the more shiny -esque req(...) methodology; it's a little more user-friendly when things don't go as you (the dev) intended;
  • I've intentionally isolate da 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 or NULL (if RDA and an object name is not selected).
  • I don't need the else return(NULL) in output$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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM