将多个选项卡框动态添加到shinydashboard

将多个选项卡框动态添加到shinydashboard,r,shiny,shinydashboard,R,Shiny,Shinydashboard,我想以编程方式添加一组带有面板的选项卡框。 不幸的是,我只能找到添加面板而不是添加多个框的解决方案 此代码不起作用;-) 库(ShinydaShashboard) tabs.all似乎魔法随着for循环消失了。里面的任何东西都不能直接输出 此代码段通过在my\u框中累积代码实现了预期的效果: output$tabs <- renderUI({ counter <- 1 my_boxes <- "" for (tabs.content in tabs.

我想以编程方式添加一组带有面板的选项卡框。 不幸的是,我只能找到添加面板而不是添加多个框的解决方案

此代码不起作用;-)

库(ShinydaShashboard)

tabs.all似乎魔法随着for循环消失了。里面的任何东西都不能直接输出

此代码段通过在
my\u框中累积代码实现了预期的效果:

 output$tabs <- renderUI({
    counter <- 1
    my_boxes <- ""

    for (tabs.content in tabs.all){
      counter <- counter +1
      tabs <- lapply(1:length(tabs.content), function(i) tabPanel(tabs.content[[i]]$Title, tabs.content[[i]]$Content))

      my_boxes <-paste0(my_boxes,do.call(tabBox, tabs)) 
    }
    HTML(my_boxes)
  })


output$tabs这很旧,但基本上你有两个主要问题:你的数据组织得非常糟糕,而且你在循环的每个周期都会覆盖你的作业

数据结构 您有一个名为
tabs的列表。所有
都包含两个列表。这两个列表中的每一个都包含
三张未命名的名单。这三个未命名列表中的每一个都包含另外两个命名列表。最后,在两个命名列表的最终集合中,每个列表都有一个字符向量。您的实际数据向下五层

列表不是邪恶的,只是被滥用了。列表最好用来保存保存数据的东西,而不是保存数据本身。像您这样的数据非常适合作为数据帧。您已经有了明确定义的变量用作列,对于每一行,项目都是相互关联的,所有内容都是“矩形”的

产出分配 第二个大问题是在循环的每个周期中覆盖
lappy
的输出。为了便于解释,让我们举一个简单的例子:

for (foo in seq(nrow(mtcars))){     #seq(nrow()) is safer than 1:X 
print(paste("cyl:",mtcars$cyl[foo],"disp:",mtcars$disp[foo],sep=" "))
}

Output:
[1] "cyl: 6 disp: 160"
[1] "cyl: 6 disp: 160"  
[1] "cyl: 4 disp: 108"  
[1] "cyl: 6 disp: 258"  
您可以看到循环的每个周期
paste()
的输出都是长度为1的字符向量。如果要按
栏中的方式分配输出
r$> str(tabs.all)
List of 2
 $ :List of 3
  ..$ :List of 2
  .. ..$ Title  : chr "Tab1"        
  .. ..$ Content: chr "Tab1 content"
  ..$ :List of 2
  .. ..$ Title  : chr "Tab2"
  .. ..$ Content: chr "Tab2 content"
  ..$ :List of 2
  .. ..$ Title  : chr "Tab3"
  .. ..$ Content: chr "Tab3 content"
 $ :List of 3
  ..$ :List of 2
  .. ..$ Title  : chr "Tab21"
  .. ..$ Content: chr "Tab21 content"
  ..$ :List of 2
  .. ..$ Title  : chr "Tab22"
  .. ..$ Content: chr "Tab22 content"
  ..$ :List of 2
  .. ..$ Title  : chr "Tab23"
  .. ..$ Content: chr "Tab23 content"
for (foo in seq(nrow(mtcars))){     #seq(nrow()) is safer than 1:X 
print(paste("cyl:",mtcars$cyl[foo],"disp:",mtcars$disp[foo],sep=" "))
}

Output:
[1] "cyl: 6 disp: 160"
[1] "cyl: 6 disp: 160"  
[1] "cyl: 4 disp: 108"  
[1] "cyl: 6 disp: 258"  

library(shiny)
library(tidyverse)
library(shinydashboard)

tabs_all <- tribble(
  ~Title,  ~Content,
  "Tab1", "Tab1 Content",
  "Tab2", "Tab2 Content",
  "Tab3", "Tab3 Content",
  "Tab21", "Tab21 Content",
  "Tab22", "Tab22 Content",
  "Tab23", "Tab23 Content")


ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(

    uiOutput("tabs")

  )
)

server <- function(input, output, session) {
  output$tabs <- renderUI({
    my_boxes <- list()

    for (rows in seq(nrow(tabs_all))){
      my_boxes[rows] <- tagList(
        tabPanel(title=tabs_all$Title[rows], tabs_all$Content[rows])
      )
    }

    do.call(tabBox, my_boxes)
  })
}

shinyApp(ui, server)