我想为列表中的每个 Dataframe 创建tabPanel
元素。这看起来应该可以使用do.call
和map
函数,但它会产生一个错误。
“[[:尝试在integerOneIndex中选择少于一个元素”
我发现这个问题似乎是相关的,我试图用alist()
Package 我所有的列表参数,但这也不起作用。Shiny:使用do.call运行渲染族函数
这是一个最小的reprex。
library(tidyverse)
library(shiny)
ui <- fluidPage(
uiOutput("tabs")
)
server <- function(input, output) {
dat <- lst(iris, mtcars)
if (FALSE) {
# this works, but would like to replicate with do.call and map
output$tabs <- renderUI(
tabsetPanel(
tabPanel("iris", renderDataTable(dat$iris)),
tabPanel("mtcars", renderDataTable(dat$mtcars)),
)
)
} else {
# doesn't work
output$tabs <- renderUI(
do.call(
tabsetPanel,
map2(names(dat), map(dat, renderDataTable), tabPanel)
)
)
}
}
shinyApp(ui = ui, server = server)
2条答案
按热度按时间f45qwnt81#
问题似乎是内部
map
创建renderDataTable。看起来当它去渲染数据时,它再也找不到它了。这看起来像是因为renderDataTable
将数据值存储为未求值的表达式,而不是存储数据本身。文档中说它接受“一个返回 Dataframe 或矩阵的表达式”,而不是在map()
中沿着传递的数据本身。一种可能的解决方法是gijlo24d2#
在导入
tidyverse
时,使用rlang
splice operator(!!!
)可能会稍微增加可读性:在动态点中实现的拼接操作符
!!!
将参数列表注入到函数调用中。它属于注入操作符家族,提供与do.call()
相同的功能。烦人的是,你需要
unname()
你的列表,否则你的应用程序将显示:错误:制表符都应该是未命名的参数,但有些是命名的:iris、mtcars
我不知道为什么需要一个未命名的列表。
然而,我无法想象有多少
shiny
应用程序需要导入整个tidyverse
。我想我更喜欢MrFlick的answer。