ошибка при запуске блестящего приложения "не удается открыть соединение" - PullRequest
0 голосов
/ 11 ноября 2018

Я пытаюсь загрузить данные из файла .RData на мой компьютер, и я пытаюсь запустить блестящее приложение для этого. Мой код ниже, но когда я запускаю его, я получаю сообщение об ошибке «Не удается открыть соединение» .. Почему эта ошибка?

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)

Пример данных:

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

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Как говорит Вишеш, я думаю, что вам может понадобиться использовать readRDS вместо load, но вот приложение shiny, которое допускает все три: csv, rds или rda.

Во-первых, быстрая настройка отладки, поэтому у нас есть три типа файлов для тестирования:

write.csv(mtcars, file="mt.csv")
saveRDS(mtcars, file="mt.rds")
save(mtcars, file="mt.rda")

(Конечно, не требуется для производственного приложения.)

Теперь приложение:

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)

Если вы выберете файл CSV или RDS в fileInput, он автоматически отобразит таблицу. Если он оканчивается на .rda или .rdata (без учета регистра), то он создаст селектор для выбора объекта в файле rda (поскольку они действительно хранят среды с именованными объектами, а не одним объектом).

Демо: с CSV или RDS:

shiny demo with RDS file

С файлом RDA (в котором есть один объект, mtcars:

shiny demo with RDA file

Некоторые другие изменения в вашем коде:

  • вместо использования if (is.null(...)), я использую методологию более shiny -esque req(...); это немного более удобно, когда дела идут не так, как вы (разработчик),
  • Я намеренно isolate сделал несколько вещей, которые могли бы остаться не изолированными, но я хотел ясного пути реактивности; возможно, если A зависит от B, а C зависит как от A, так и от B, что при обновлении A, C будет обновляться, а затем B будет обновляться, вызывая повторное обновление C ... возможно, головокружение, но следствие множества путей зависимости .
  • Поскольку это допускает оба типа хранилищ (один объект и несколько), мне нужно двухэтапное извлечение данных: rawdat() может быть средой (RDA) или фактическим объектом; dat() всегда будет объектом или NULL (если RDA и имя объекта не выбраны).
  • Мне не нужно else return(NULL) в output$rda_objname, у меня его просто есть для ясности и явного кода в этом примере; Скорее всего, этого не будет в моем рабочем коде.
  • Я также часто использую return; технически, это не требуется ни в одном из этих применений, опять же, я просто говорю прямо для этого примера.
0 голосов
/ 11 ноября 2018

Я бы рекомендовал использовать readRDS для чтения файлов RData. Кроме того, вам необходимо указать элемент fileInput UI, который пользователь может использовать для просмотра файла данных.

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)

Ссылка, которую вы упомянули в комментарии, объясняет использование req, которое предотвращает ошибку в вашем приложении, когда оно загружается и пользователь еще не выбрал источник данных.

...