rtabsquarto

Nested tabs in Quarto document


I would like to create nested tabs in a Quarto document. I wrote a custom function called nested_tabs which takes the names of a nested list for the tab names and should plot the graphs at each corresponding tab. Unfortunately, output is not expected. Somehow it doesn't show graph but the path of graph. Here is some simple reproducible example code:

---
title: "test"
format: html
---

```{r}
#| echo: false
#| message: false
#| warning: false
library(tidyverse)

# example list
example_list <- list(
  tab1 = list(test1.1 = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width))+
                geom_point(),
              test1.2 = ggplot(iris, aes(x = Petal.Length, y = Sepal.Width))+
                geom_point()),
  tab2 = list(test2 = ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length))+
                geom_point())
)

# function
nested_tabs <- function(nested_list) {
 
  main_tab <- names(nested_list)
 
  cat(':::: {.panel-tabset} \n') # main tab
  
  for (i in main_tab) {
    id <- which(main_tab == i)
    cat("##", as.character(i), "\n\n")
 
    cat("::: {.panel-tabset} \n\n") # sub tab
 
    for (j in 1:length(names(nested_list[[id]]))) {
      cat("###", names(nested_list[[id]])[j], "\n\n")
      cat("```{r}\n")
      base::print(nested_list[[id]][[j]])
      cat("\n```\n\n")
    }
    cat("\n:::\n\n")
  }
  cat("::::")
}
```


```{r}
#| results: asis
#| echo: false
#| message: false
#| warning: false

nested_tabs(example_list)
```

Output:

enter image description here

As you can see, the tabs are working but not the output. So I was wondering if anyone knows how we can make these nested tabs?


Solution

  • Instead of your inner for loop, you can purrr::iwalk() over your example_list[[i]] as shown here. Optionally, you may also set the fig-width / fig-height of your as-is-chunk.

    out1

    Code

    ---
    title: "test"
    format: html
    ---
    
    ```{r}
    #| echo: false
    #| message: false
    #| warning: false
    library(ggplot2)
    
    # example list
    example_list <- list(
      tab1 = list(test1.1 = ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width))+
                    geom_point(),
                  test1.2 = ggplot(iris, aes(x = Petal.Length, y = Sepal.Width))+
                    geom_point()),
      tab2 = list(test2 = ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length))+
                    geom_point())
    )
    
    # function
    nested_tabs <- function(nested_list) {
      main_tab <- names(nested_list)
      cat(':::: {.panel-tabset} \n') # main tab
      for (i in main_tab) {
        id <- which(main_tab == i)
        cat("##", as.character(i), "\n\n")
        cat("::: {.panel-tabset} \n\n") # sub tab
        purrr::iwalk(example_list[[i]], ~ { # source: https://stackoverflow.com/a/73368297/28479453
          cat('###', .y, '\n\n')
          print(.x)
          cat('\n\n')
        })
        cat("\n:::\n\n")
      }
      cat("::::")
    }  
    
    ```       
    ```{r}
    #| results: asis
    #| echo: false
    #| message: false
    #| warning: false
    #| fig-width: 14
    #| fig-height: 6    
    nested_tabs(example_list)    
    ```