R语言 如何在Map中定义多个闪亮的输出元素或应用?

pbpqsu0x  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(105)

我想为列表中的每个 Dataframe 创建tabPanel元素。这看起来应该可以使用do.callmap函数,但它会产生一个错误。
“[[:尝试在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)
f45qwnt8

f45qwnt81#

问题似乎是内部map创建renderDataTable。看起来当它去渲染数据时,它再也找不到它了。这看起来像是因为renderDataTable将数据值存储为未求值的表达式,而不是存储数据本身。文档中说它接受“一个返回 Dataframe 或矩阵的表达式”,而不是在map()中沿着传递的数据本身。一种可能的解决方法是

output$tabs <- renderUI(
  do.call(
    tabsetPanel,
    map(names(dat), function(x) tabPanel(x, renderDataTable(dat[[x]])))
  )
)
gijlo24d

gijlo24d2#

在导入tidyverse时,使用rlangsplice operator!!!)可能会稍微增加可读性:
在动态点中实现的拼接操作符!!!将参数列表注入到函数调用中。它属于注入操作符家族,提供与do.call()相同的功能。

output$tabs <- renderUI(
    tabsetPanel(
        !!!unname(
            imap(dat, \(df, df_name) tabPanel(df_name, renderDataTable(df)))
        )
    )
)

烦人的是,你需要unname()你的列表,否则你的应用程序将显示:
错误:制表符都应该是未命名的参数,但有些是命名的:iris、mtcars
我不知道为什么需要一个未命名的列表。
然而,我无法想象有多少shiny应用程序需要导入整个tidyverse。我想我更喜欢MrFlick的answer

相关问题