r - 在循环中呈现动态加载的 UI 仅显示最后一个值
问题描述
我有一个闪亮的应用程序,它可以动态加载任意数量的outputPlot
UI。在下面的示例中,我只是对字母表的前三个字母进行迭代。
为了在动态加载的 UI 中渲染绘图,我这样调用renderPlot
了一个循环:
for (a in LETTERS[1:3]) {
output[[paste0('p',a)]] <- renderPlot(plot.df(df, a))
}
但结果是所有三个 outputPlot (pA
和pB
)pC
都用. 在我看来,是在循环完成后呈现的,并且. 相反,输出 UI和应该分别用、和呈现。但在查看输出时显然不是这种情况。plot.df(df, 'C'))
renderPlot
a = 'C'
pA
pB
pC
plot.df(df, 'A')
plot.df(df, 'B')
plot.df(df, 'C')
如果输出 UI 是一个模块并且在循环调用中,我以前已经成功了callModule
,这会以某种方式强制评估参数。但我现在试图避免为我的输出 UI 创建一个单独的模块。
完全可重现的例子
library(shiny)
library(dplyr)
# Define UI for application that draws a histogram
ui <- fluidPage(
plotOutput('pltA'),plotOutput('pltB'),plotOutput('pltC'),
tags$hr(),
tags$div(id='placeholder')
)
col <- c(A='#66bd63', B='#fdae61', C='#74add1')
plot.df <- function(df, a) {
#browser()
df <- filter(df, letter==a)
if (nrow(df) == 0) return()
plot(df$i, df$y, type='p', col=col[a], pch=19, main=a)
}
# Define server logic required to draw a histogram
server <- function(input, output, session) {
my_data <- reactiveVal(data.frame())
autoInvalidate <- reactiveTimer(2000)
# Generate some random data and assign to one of three different letters:
observe({
autoInvalidate()
a <- sample(LETTERS[1:3], 1)
data.frame(y=rnorm(5), letter=a) %>%
bind_rows(isolate(my_data())) %>%
group_by(letter) %>%
mutate(i=seq_along(y)) %>%
my_data
})
# Proof of function making a plot.
output$pltA <- renderPlot(plot.df(my_data(), 'A'))
output$pltB <- renderPlot(plot.df(my_data(), 'B'))
output$pltC <- renderPlot(plot.df(my_data(), 'C'))
# Dynamically load output UIs.
observe({
let <- unique(my_data()$letter)
if (is.null(let)) return()
for (l in let) {
if (is.null(session$clientData[[paste0('output_p',l,'_hidden')]])) {
insertUI('#placeholder', 'beforeEnd', ui=plotOutput(paste0('p',l)))
}
}
})
# Update dynamically loaded plots
observe({
df <- my_data()
if (nrow(df) == 0) return()
for (a in LETTERS[1:3]) {
cat('Updating ', a, '\n')
output[[paste0('p',a)]] <- renderPlot(plot.df(df, a))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
解决方案
你必须使用local
(见这里)。
for (a in LETTERS[1:3]) {
local({
aa <- a
output[[paste0('p',aa)]] <- renderPlot(plot.df(df, aa))
})
}
推荐阅读
- dart - Dart:如何解决这个问题?
- python - 为什么字符串乘以整数和变量乘以整数不一样?
- php - 如何在访客用户购买之前为他设置邮政编码?WooCommerce
- spring - 无法使用 React 和 Spring Security 对用户进行身份验证
- java - 在构造函数中等待用户输入
- asp.net-core - Aspnetcore 身份验证关联失败
- excel - 用户表单列表框点击代码不会触发
- azure - Web 部署到 Azure 失败“无法创建 SSL/TLS 安全通道”
- jquery - 如何在 Jquery 中格式化带有 000 前缀的数字?
- javascript - 无法调用其类型缺少调用签名的表达式。输入“事件发射器”
' 没有兼容的调用签名