[英]R Add column into data.frame, that is in list of data.frames
[英]R Shiny: How to expand a reactive containing a list of data.frames with an uploaded data.frame?
我为此苦苦挣扎了几个小时:
在我的应用程序中,启动应用程序时会加载一个简单的测试数据集df
。 然后,用户可以通过文件上传添加更多数据集,然后从下拉菜单(此处为selectInput
)选择他喜欢继续使用的数据集。
我没有做的事情:
启动应用程序后,反应式df_list
应该只包含初始数据集df
并且下拉菜单应该只包含值c("", "df")
。 通过上传(或其他方式)添加数据集后,应展开df_list
(以及相应的下拉菜单)。 这样我就有了一个列表,其中包含用户可以从 select 中获取的所有可用数据集。
但我只设法创建了两个场景:下拉菜单包含df
但添加数据集后我无法展开df_list
。 或者在我添加数据集之前下拉菜单保持空白,因此用户必须先添加数据集才能使用测试数据集。
我的代码示例:我通过创建 data.frame df_upload
的 actionButton 来“模拟”文件上传。 以下示例不尝试使用附加数据集df_upload
df_list
library(shiny)
# df available from start
df <- data.frame(Var = 1:10)
ui <- fluidPage(
selectInput("select", label = "Select data", choices = c("")),
actionButton("upload", "Simulate Upload"),
tableOutput("tabdata")
)
server <- function(input, output, session) {
# reactive that lists all datasets
df_list <- reactive({list(df = df)})
# 'upload' of second df
df_upload <- eventReactive(input$upload, {
data.frame(Var = 11:20)
})
# observes if df_list() gets expanded to update choices
observeEvent(df_list(), {
updateSelectInput(session = session,
inputId = "select",
choices = c("", names(df_list())))
})
# output of selected dataset
output$tabdata <- renderTable({
req(df_list())
df_list()[[input$select]]
})
}
shinyApp(ui, server)
这是我尝试过的许多事情之一(这成功添加了df_upload
,但在启动应用程序后最初无法在下拉菜单中显示df
):
library(shiny)
# df available from start
df <- data.frame(Var = 1:10)
ui <- fluidPage(
selectInput("select", label = "Select data", choices = c("")),
actionButton("upload", "Simulate Upload"),
tableOutput("tabdata")
)
server <- function(input, output, session) {
# reactive that lists all datasets
df_list <- reactive({
df_list <- list(df = df)
# check if there is an uploaded df, and if yes add it to df_list
# does not work, because it does not give me df_list only containing df
# in case no dataset was added yet.
# is.null is not the proper way, because if df_upload does not exist yet,
# it does not yield NULL. I also tried it unsuccessfully
# with exists("df_upload()")
if (!is.null(df_upload())) {
df_list[[2]] <- df_upload()
names(df_list)[2] <- "df_upload"
}
return(df_list)
})
# 'upload' of second df
df_upload <- eventReactive(input$upload, {
data.frame(Var = 11:20)
})
# observes if df_list() gets expanded to update choices
observeEvent(df_list(), {
updateSelectInput(session = session,
inputId = "select",
choices = c("", names(df_list())))
})
# output of selected dataset
output$tabdata <- renderTable({
req(df_list())
df_list()[[input$select]]
})
}
shinyApp(ui, server)
基于@Limey 的评论使用 reactiveValues 的简单解决方案:
library(shiny)
# df available from start
df <- data.frame(Var = 1:10)
reactlog::reactlog_enable()
ui <- fluidPage(
selectInput("select", label = "Select data", choices = c("df")),
actionButton("upload", "Simulate Upload"),
tableOutput("tabdata")
)
server <- function(input, output, session) {
# empty reactiveValues rv to store all datasets in
rv <- reactiveValues()
# store the test df in rv
rv$df <- df
# 'upload' of second df and storing it in rv
observeEvent(input$upload, {
rv$df_upload <- data.frame(Var = 11:20)
})
# update selectInput choices
observe({
updateSelectInput(session = session,
inputId = "select",
choices = names(rv),
selected = "df")
})
# output of selected dataset
output$tabdata <- renderTable({
rv[[input$select]]
})
}
shinyApp(ui, server)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.