使用Reactive()创建动态数量的FlexDashboard选项卡

发布于 2025-01-25 23:13:04 字数 2126 浏览 4 评论 0原文

我想知道是否可以在FlexDashboard中创建许多标签,这些选项卡会根据某些用户输入而更改。作为玩具示例,我正在尝试绘制用户选择数据集的每个数字列的直方图,每个数字列都可以使用自己的直方图。如果用户更改数据集,则仪表板应更新和增加选项卡中的选项卡数,如果新选择的数据集中的数字列的数量更改。为简单起见,我只包含两个数据集。

---
title: "Reactive GGPlot Tabs"
output: 
  flexdashboard::flex_dashboard:
    theme: 
      version: 4
      bootswatch: cosmo
runtime: shiny
---

```{r}
pacman::p_load(tidyverse, shiny, flexdashboard)
```

Sidebar {.sidebar}
-------------------------------------

<h5>Required Input</h5>

```{r}
selectInput(inputId = "dataset", label = "Data:",
            choices = c('mtcars', 'iris'), selected = 'iris')


dataset = reactive({
  set = as.character(input$dataset)
  if(set=='iris'){data = iris} else{data = mtcars}
  return(data)
  })
```



```{r setup}
chart = reactive({
data = dataset()

num_cols <- unlist(lapply(data, is.numeric))
data = data[,num_cols] # only keep numeric columns for histogram

labels <- data %>% names # these will serve as labels for each tab

chart <- purrr::map(.x = data, ~ggplot(data, aes(x=.x))+geom_histogram()+theme_bw()) %>% setNames(labels) # assign names to each element to use later as tab titles

return(chart)
})
```



## Column {.tabset .tabset-fade}


```{r}
out <- reactive({
  lapply(seq_along(chart()), function(i) {
  
  a1 <- knitr::knit_expand(text = sprintf("### %s\n", names(chart())[i])) # tab header, auto extracts names of `chart`, %s indicates string
  
  a2 <- knitr::knit_expand(text = "\n```{r, message = F, warning = F}") # start r chunk
  
  a3 <- knitr::knit_expand(text = sprintf("\nchart()[[%d]]", i)) # extract graphs by "writing" out `chart[[1]]`, `chart[[2]]` etc. to be rendered later, %d indicates integer variable
  
  a4 <- knitr::knit_expand(text = "\n```\n") # end r chunk
  
  paste(a1, a2, a3, a4, collapse = '\n') # collapse together all lines with newline separator
})
  })
```

`r reactive({knitr::knit(text = paste(out(), collapse = '\n'))})`

运行此代码时,仪表板将显示Markdown块代码,但不会呈现图或选项卡。

我能够看到该代码在没有反应性的情况下使用该代码工作,但是根据所选数据集,我需要标签数来增加/减少。另外,我不允许使用facet_wrap

这可能吗?

I am wondering if it is possible to create a number of tabs in flexdashboard which change according to some user input. As a toy example, I am trying to plot histograms of every numeric numeric column of a user-selected dataset, with each numeric column getting its own tab for a histogram. If the user changes the dataset, the dashboard should update and increase/decrease the number of tabs in the tabset, if the number of numeric columns in the newly selected dataset changes. For simplicity, I only included two datasets.

---
title: "Reactive GGPlot Tabs"
output: 
  flexdashboard::flex_dashboard:
    theme: 
      version: 4
      bootswatch: cosmo
runtime: shiny
---

```{r}
pacman::p_load(tidyverse, shiny, flexdashboard)
```

Sidebar {.sidebar}
-------------------------------------

<h5>Required Input</h5>

```{r}
selectInput(inputId = "dataset", label = "Data:",
            choices = c('mtcars', 'iris'), selected = 'iris')


dataset = reactive({
  set = as.character(input$dataset)
  if(set=='iris'){data = iris} else{data = mtcars}
  return(data)
  })
```



```{r setup}
chart = reactive({
data = dataset()

num_cols <- unlist(lapply(data, is.numeric))
data = data[,num_cols] # only keep numeric columns for histogram

labels <- data %>% names # these will serve as labels for each tab

chart <- purrr::map(.x = data, ~ggplot(data, aes(x=.x))+geom_histogram()+theme_bw()) %>% setNames(labels) # assign names to each element to use later as tab titles

return(chart)
})
```



## Column {.tabset .tabset-fade}


```{r}
out <- reactive({
  lapply(seq_along(chart()), function(i) {
  
  a1 <- knitr::knit_expand(text = sprintf("### %s\n", names(chart())[i])) # tab header, auto extracts names of `chart`, %s indicates string
  
  a2 <- knitr::knit_expand(text = "\n```{r, message = F, warning = F}") # start r chunk
  
  a3 <- knitr::knit_expand(text = sprintf("\nchart()[[%d]]", i)) # extract graphs by "writing" out `chart[[1]]`, `chart[[2]]` etc. to be rendered later, %d indicates integer variable
  
  a4 <- knitr::knit_expand(text = "\n```\n") # end r chunk
  
  paste(a1, a2, a3, a4, collapse = '\n') # collapse together all lines with newline separator
})
  })
```

`r reactive({knitr::knit(text = paste(out(), collapse = '\n'))})`

When this code is run, the dashboard displays the markdown chunk code, but does not render plots or tabs.

I am able to sightly modify this code to work without reactive, but I need the number of tabs to increase/decrease according to the chosen dataset. Also, I am not allowed to use facet_wrap.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文