r-包含未在闪亮中完全生成的反应项目的列表



我修复了一个错误,但我不明白为什么会发生这种情况。有人能帮忙澄清吗?

我正在构建一个交互式数据浏览器应用程序,每个图都包含在自己的模块中。在我的第一种方法("旧版本不起作用"(下,我首先建立一个查找列表,然后使用它来显示正确的控件和绘图。

但是,在单击地物选择列表中的所有选项之前,不会显示任何绘图。

我通过切换到没有中间查找列表的"有效的新版本"来解决这个问题。但不明白为什么会发生这种事。

下面是可复制的最小示例,很抱歉长度太长。

# required packages
library(shiny)
library(tidyverse)
## ui ----
ui = fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput("plot_controls"),
width=3
),
mainPanel(
selectInput("selected_plot", "Select figure:", choices = c("Histogram", "Scatter")),
plotOutput("plot_plot", height = "700px"),
width=9
)))
## server ----
server = function(input, output, session) {
data(starwars)
### modules ----
fig_histogram = callModule(figure_histogram_plot, "histogram", datafile = starwars)
fig_scatter = callModule(figure_Scatter_Plot, "scatter", datafile = starwars)
module_list = list( fig_histogram, fig_scatter )
### old version that does not work ----
resource.map_text_to_plot = reactive({
map = list("Histogram" = module_list[[1]]$plot(), "Scatter" = module_list[[2]]$plot())
})
output$plot_plot = renderPlot({ resource.map_text_to_plot()[input$selected_plot] })
resource.map_text_to_control = reactive({
map = list("Histogram" = module_list[[1]]$control, "Scatter" = module_list[[2]]$control)
})
output$plot_controls = renderUI({ resource.map_text_to_control()[input$selected_plot] })
### new version that works ----
# output$plot_controls = renderUI({
#   for(module in module_list)
#     if(module$text == input$selected_plot)
#       return(module$control)
# })
# 
# output$plot_plot = renderPlot({
#   for(module in module_list)
#     if(module$text == input$selected_plot)
#       return(module$plot())
# })
}
shinyApp(ui = ui, server = server)

图形模块如下:

### histogram - server ----
figure_histogram_plot = function(input, output, session, datafile){
text = "Histogram"
control = sliderInput(session$ns("num_bins"), "Number of bins", min = 5, max = 50, value = 30)
plot = reactive({
p = ggplot(data = datafile) + geom_histogram(aes_string(x = "height"), bins = input$num_bins)
return(p)
})
return(list(text = text, plot = plot, control = control))
}
### scatter - server ----
figure_Scatter_Plot = function(input, output, session, datafile){
text = "Scatter"
control = radioButtons(session$ns("plot_design"), "Plot design", choices = c("points", "lines", "both"))
plot = reactive({
p = ggplot(data = datafile)
if(input$plot_design != "lines")
p = p + geom_point(aes_string( x = "mass", y = "height" ))
if(input$plot_design != "points")
p = p + geom_line(aes_string( x = "mass", y = "height" ))
return(p)
})
return(list(text = text, plot = plot, control = control))
}

所以我认为问题在于何时评估反应性元素。当你使用()来"调用"一个反应性元素时,它就不再是真正的反应性了。设置列表时,请使用

resource.map_text_to_plot = reactive({
map = list("Histogram" = module_list[[1]]$plot, 
"Scatter" = module_list[[2]]$plot)
map
})

设置renderPlot时,使用

output$plot_plot = renderPlot({ 
resource.map_text_to_plot()[[input$selected_plot]]() })

请注意,我们从列表中删除了(),并将其放在render函数中。

此外,在绘制第一个绘图之前,您的控件不会被初始化,因此input$plot_design值可能为NULL,并且您似乎没有在第一次绘图时检查导致问题的原因(您很可能会短暂地看到错误(

最新更新