我试图将在一个渲染函数中创建的数据帧访问到另一个渲染函数中。
有两个服务器输出,即lvi和Category,在lvi中我创建了Data1数据帧,而Category I已经创建了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)
答案 0 :(得分:3)
一旦反应块执行完毕,其中的所有元素都将消失,就像一个函数一样。唯一幸存的是从该块“返回”的内容,该块通常是该块中的最后一个表达式(或在实数function
中时,在return(...)
中是某个表达式)。如果您将反应性(并观察)块视为“功能”,则您可能会意识到,该功能的外部唯一了解该功能的内部 是该函数是否以某种方式显式返回它。
请牢记这一点,进入一个render
/反应块内部的框架的方法是不在该反应块内部进行计算:而是在其自己的数据中创建该框架-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过滤的框架同时进行……您现在可能不会单独使用它,但是通常最好将“加载/生成帧”与“渲染成漂亮的东西”分开。这样,如果您需要了解有关所加载数据的某些知识,则不必(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)
虽然此代码稍长一些,但它也将“数据加载/整理”分组在一起,并将“将数据渲染成漂亮的东西”分组在一起。而且,如果您需要查看早期数据或过滤后的数据,就可以了。
(附带说明:您可能会因此而受到的性能影响是,您现在拥有更多的数据副本。只要您不处理“大”数据,这都不是什么大问题。)