доступ к reactiveValues ​​в reactiveValuesToList

Вместо того, чтобы указывать отдельные fileInput переменные, я хотел бы использовать reactiveValues для хранения загруженных фреймов данных CSV, каким-либо образом управлять ими, а затем сохранять их для последующего доступа. Мой план состоит в том, чтобы назвать каждый фрейм данных по его имени файла и добавить его к reactiveValue rvTL. Мои вопросы:

  • Как я могу получить доступ к отдельным фреймам данных в списке, который я создал с помощью reactiveValuesToList(rvTL)?
  • Следующий шаг, как создать selectInput меню для доступа к отдельным фреймам данных, загруженным fileInput

Чтобы изучить эту концепцию, я использовал ответ Дина Аттали и сделал rvTL таким же, как его переменная values. R блестящий : Как обновить реактивный фрейм данных каждый раз при нажатии кнопки действия без создания нового реактивного фрейма данных?

Я просмотрел много примеров кода на reactiveValues, но все еще не понял. В большинстве примеров используется какая-то разновидность reactiveValuesToList(input) R Shiny: сохранить / сохранить значения реактивных входов после изменения выбора, я действительно не вижу здесь логики. Любая помощь / предложения будут оценены!

library(shiny)
runApp(shinyApp(
  ui=(fluidPage(
    titlePanel("amend data frame"),

    mainPanel(
      fileInput("file", "Upload file", multiple=T),
      tabsetPanel(type="tabs",
          tabPanel("tab1",        
                    numericInput("Delete", "Delete row:", 1, step = 1),
                    actionButton("Go", "Delete!"),
                    verbatimTextOutput("df_data_files"),
                    verbatimTextOutput("values"),
                    verbatimTextOutput("rvTL"),
                   tableOutput("rvTL_out")
          ),
          tabPanel("tab2", 
                  tableOutput("df_data_out")
          )
    )))),

  server = (function(input, output) {
    values <- reactiveValues(df_data = NULL) ##reactiveValues
    rvTL <- reactiveValues(rvTL = NULL)

    observeEvent(input$file, {
      values$df_data <- read.csv(input$file$datapath)
      rvTL[[input$file$name]] <- c(isolate(rvTL), read.csv(input$file$datapath))
    })

    observeEvent(input$Go, {
      temp <- values$df_data[-input$Delete, ]
      values$df_data <- temp
    })

    output$df_data_files <- renderPrint(input$file$name)
    output$values <- renderPrint(names(values))
    output$rvTL <- renderPrint(names(reactiveValuesToList(rvTL))[1] )
    output$rvTL_out <- renderTable(reactiveValuesToList(rvTL)[[1]])
    output$df_data_out <- renderTable(values$df_data)

    })
  ))

person seraphim711    schedule 30.03.2017    source источник


Ответы (1)


Это действительно так просто, как вы думали. Вы тоже были близки, просто попали в какие-то синтаксические ловушки. Я внес следующие изменения:

  • тот c(isolate(.. звонок все испортил, я избавился от него. Это приводило к этим "Warning: Error in as.data.frame.default: cannot coerce class "c("ReactiveValues", "R6")" to a data.frame" ошибкам.
  • Кроме того, вы слишком часто использовали имя rvTL, что сбивает с толку и может привести к конфликтам, поэтому я переименовал несколько из них.
  • Я также добавил список имен загруженных файлов (lfnamelist), чтобы отслеживать, что было загружено. Я мог бы использовать для этого names(rvTL$dflist), но в то время мне это не приходило в голову - и я также, это полезный пример того, как организовать связанные реактивные значения в одно объявление.
  • А затем я добавил обработанный selectInput, чтобы вы могли проверить, что сохраняется в списке reactiveValue.

Итак, вот скорректированный код:

library(shiny)
runApp(shinyApp(
  ui=(fluidPage(
    titlePanel("amend data frame"),

    mainPanel(
      fileInput("file", "Upload file", multiple=T),
      tabsetPanel(type="tabs",
                  tabPanel("rvTL tab",        
                           numericInput("Delete", "Delete row:", 1, step = 1),
                           uiOutput("filesloaded"),
                           actionButton("Go", "Delete!"),
                           verbatimTextOutput("df_data_files"),
                           verbatimTextOutput("values"),
                           verbatimTextOutput("rvTL_names"),
                           tableOutput("rvTL_out")
                  ),
                  tabPanel("values tab", 
                           tableOutput("df_data_out")
                  )
      )))),

  server = (function(input, output) {
    values <- reactiveValues(df_data = NULL) ##reactiveValues
    rvTL <- reactiveValues(dflist=NULL,lfnamelist=NULL)

    observeEvent(input$file, {
      req(input$file)
      values$df_data <- read.csv(input$file$datapath)
      rvTL$dflist[[input$file$name]] <-read.csv(input$file$datapath)
      rvTL$lfnamelist <- c( rvTL$lfnamelist, input$file$name )
    })

    observeEvent(input$Go, {
      temp <- values$df_data[-input$Delete, ]
      values$df_data <- temp
    })

    output$df_data_files <- renderPrint(input$file$name)
    output$values <- renderPrint(names(values))
    output$rvTL_names <- renderPrint(names(rvTL$dflist))
    output$rvTL_out <- renderTable(rvTL$dflist[[input$lftoshow]])
    output$df_data_out <- renderTable(values$df_data)
    output$filesloaded <- renderUI(selectInput("lftoshow","File to show",choices=rvTL$lfnamelist))

  })
))

А вот скриншот:

введите здесь описание изображения

person Mike Wise    schedule 30.03.2017
comment
Еще раз спасибо за столь четкое объяснение! Теперь я вижу, что мне нужно инициализировать reactiveValues как списки (rvTL$dflist), чтобы хранить другие вещи. Это именно то, к чему я стремился! Думаю, я был немного зациклен на использовании reactiveValuesToList, не понимая этого. Ваше здоровье! - person seraphim711; 30.03.2017