【问题标题】:Object not found R Shiny找不到对象 R 闪亮
【发布时间】:2020-01-29 05:55:44
【问题描述】:

我正在尝试将在一个渲染函数中创建的数据框访问到另一个渲染函数中。

有两个服务器输出,lvi 和 Category,在 lvi 中我创建了 Data1 数据框,Category 我创建了 Data2 数据框。我想选择 Data1 ID 匹配的 Data2。

我正在按照以下步骤来实现我的目标,但我收到错误“找不到对象 Data1”。

我的用户界面是

ui <- fluidPage(
  # App title ----
  titlePanel("Phase1"),
  fluidPage(
    column(4,
           # Input: Select a file ----
           fileInput("file1", "Import file1")
    ) 
  ),
  fluidPage(
    column(4,
           # Input: Select a file ----
           fileInput("file2", "Import File2")
    ) 

  ),
    # Main panel for displaying outputs ----
    mainPanel( 
      # Output: Data file ----
      dataTableOutput("lvi"),
      dataTableOutput("category")
    )
  )

我的服务器代码是

server <- function(input, output) {
  output$lvi <- renderDataTable({
    req(input$file1)
    Data1 <- as.data.frame(read_excel(input$file1$datapath, sheet = "Sheet1"))    
  })

  output$category <- renderDataTable({        
    req(input$file2)        
    Data2 <- as.data.frame(read_excel(input$file2$datapath, sheet = "Sheet1"))
    Data2 <- Data2[,c(2,8)]
    Data2 <- Data2[Data1$ID == "ID001",]        
  })        
}
shinyApp(ui, server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    一旦反应块执行完毕,其中的所有元素都会消失,就像函数一样。唯一幸存的是从该块中“返回”的内容,它通常是块中的最后一个表达式(或者,在真正的function 中,return(...) 中的某些东西)。如果您将反应(和观察)块视为“函数”,您可能会意识到函数外部的东西唯一知道函数内部发生了什么是函数是否以某种方式显式返回它。

    考虑到这一点,在一个 render/reactive 块内获取帧的方法是不在该反应块内计算它:相反,在它自己的 data-reactive 块中创建该帧并使用它在render 和另一个render 中。

    试试这个(未经测试):

    server <- function(input, output) {
    
      Data1_rx <- eventReactive(input$file1, {
        req(input$file1, file.exists(input$file1$datapath))
        as.dataframe(read_excel(input$file1$datapath, sheet = "Sheet1"))
      })
    
      output$lvi <- renderDataTable({ req(Data1_rx()) })
    
      output$category <- renderDataTable({        
        req(input$file2, file.exists(input$file2$datapath),
            Data1_rx(), "ID" %in% names(Data1_rx()))
        Data2 <- as.data.frame(read_excel(input$file2$datapath, sheet = "Sheet1"))
        Data2 <- Data2[,c(2,8)]
        Data2 <- Data2[Data1_rx()$ID == "ID001",]        
      })        
    }
    shinyApp(ui, server)
    

    但是既然我们已经走上了“更好的设计”和“最佳实践”的道路,让我们把 data2 和 data2-filtered 框架分开......你现在可能不会单独使用它,但它是通常最好将“加载/生成帧”与“渲染成美丽的东西”分开。这样,如果您需要了解有关您加载的数据的一些信息,您不必 (a) 在其他地方重新加载它,效率低下;或者 (b) 尝试进入闪亮的 DataTable 对象的内部并手动获取它。 (两者都是非常糟糕的想法。)

    因此,一个稍微好一点的解决方案可能从以下开始:

    server <- function(input, output) {
    
      Data1_rx <- eventReactive(input$file1, {
        req(input$file1, file.exists(input$file1$datapath))
        as.dataframe(read_excel(input$file1$datapath, sheet = "Sheet1"))
      })
      Data2_rx <- eventReactive(input$file2, {
        req(input$file2, file.exists(input$file2$datapath))
        dat <- as.dataframe(read_excel(input$file2$datapath, sheet = "Sheet1"))
        dat[,c(2,8)]
      })
      Data12_rx <- reactive({
        req(Data1_rx(), Data2_rx())
        Data2_rx()[ Data1_rx()$ID == "ID001", ]
      })
    
      output$lvi <- renderDataTable({ req(Data1_rx()); })
      output$category <- renderDataTable({ req(Data12_rx()); })
    }
    shinyApp(ui, server)
    

    虽然这段代码有点长,但它也将“数据加载/修改”和“将数据渲染成美丽的东西”组合在一起。如果您需要查看早期数据或过滤后的数据,都可以。

    (旁注:您可能会从中看到的一个性能损失是您现在有更多的数据副本浮动。只要您不处理“大”数据,这并不是什么大问题。)

    【讨论】:

      猜你喜欢
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-21
      • 2019-12-21
      • 1970-01-01
      • 2020-04-04
      相关资源
      最近更新 更多