我有几个变量,每个变量都有一个值,我在R Shiny应用程序中使用valueBox显示这些变量。变量名称是固定的,但是值可以变化。
以下是一些虚拟数据来说明我的问题:
variable <- c("a", "b", "c", "d", "e")
value <- c(5, 120, -1/3, 67, 2)
df <- data.frame(variable, value)
这是闪亮的应用程序代码,可提供所需的输出。
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Test App"),
dashboardSidebar(),
dashboardBody(
fluidRow(valueBoxOutput("value_box_a")),
fluidRow(valueBoxOutput("value_box_b")),
fluidRow(valueBoxOutput("value_box_c")),
fluidRow(valueBoxOutput("value_box_d")),
fluidRow(valueBoxOutput("value_box_e"))
)
)
server <- function(input, output) {
variable <- c("a", "b", "c", "d", "e")
value <- c(5, 120, -1/3, 67, 2)
df <- data.frame(variable, value)
output$value_box_a <- renderValueBox({
valueBox("a", df$value[df$variable == "a"])
})
output$value_box_b <- renderValueBox({
valueBox("b", df$value[df$variable == "b"])
})
output$value_box_c <- renderValueBox({
valueBox("c", df$value[df$variable == "c"])
})
output$value_box_d <- renderValueBox({
valueBox("d", df$value[df$variable == "d"])
})
output$value_box_e <- renderValueBox({
valueBox("e", df$value[df$variable == "e"])
})
}
shinyApp(ui, server)
这是所需的输出:
我没有单独渲染所有valueBox,而是尝试在循环中使用一个函数。考虑到它们之间的相似性,这似乎是有道理的。
这是我的尝试,不起作用:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Test App"),
dashboardSidebar(),
dashboardBody(
fluidRow(valueBoxOutput("value_box_a")),
fluidRow(valueBoxOutput("value_box_b")),
fluidRow(valueBoxOutput("value_box_c")),
fluidRow(valueBoxOutput("value_box_d")),
fluidRow(valueBoxOutput("value_box_e"))
)
)
server <- function(input, output) {
variable <- c("a", "b", "c", "d", "e")
value <- c(5, 120, -1/3, 67, 2)
df <- data.frame(variable, value)
for (var_name in variable) {
output[[paste0("value_box_",var_name)]] <- renderValueBox({
valueBox(var_name, df$value[df$variable == var_name])
})
}
}
shinyApp(ui, server)
这是我尝试的输出:
任何人都可以建议如何实现我想要的吗?
答案 0 :(得分:2)
这是一个棘手的错误。发生这种情况的原因是,Shiny(缺乏更好的语言)不会像我们习惯的那样执行代码,而是以某种方式存储了代码的缓存。
解决方案是通过将Shiny分配给新变量来强制Shiny为每个循环评估var_name
的内容:
for (var_name in variable) {
local({ ## here
v1 <- var_name ## here
output[[paste0("value_box_",var_name)]] <- renderValueBox({
valueBox(v1, df$value[df$variable == v1])
})
}) ## and closing here
}
您还可以使用insertUI
加倍创建动态控件。然后,您不必在ui
中创建valueBoxOutput,而只需从server
即时创建它们即可。