Dynamic creation of tabs in Rmarkdown does not work for ggplot while it does for plotly

I've been willing to dynamically create tab contents in rmarkdown.

I've created an in_tabs that seems to work for everything but ggplot plots.

The way it works is that it creates the Rmd code necessary to display nested lists in tabs.

The following reproducible example shows the issue:

---                                                                                                                                    
title: "test"                                                                                                                          
output: html_document                                                                                                                  
---                                                                                                                                    
                                                                                                                                       
```{r setup, include = FALSE}                                                                                                          
library(ggplot2)                                                                                                                       
library(plotly)                                                                                                                        
l1 <- list(p1 = data.frame(x=1:10, y=1:10))                                                                                            
l2 <- list(p2 = data.frame(x=100:110, y=100:110))                                                                                      
gplot <- function(data) {                                                                                                              
    p <- ggplot(data) + aes(x=x, y=y) + geom_point() + geom_line()                                                                     
    return(p)                                                                                                                          
}                                                                                                                                      
gplotly <- function(data) {                                                                                                            
    p <- ggplot(data) + aes(x=x, y=y) + geom_point() + geom_line()                                                                     
    return(ggplotly(p))                                                                                                                
}                                                                                                                                      
```                                                                                                                                    
                                                                                                                                       
```{r, code, include = FALSE}                                                                                                          
in_tabs <- function(l, labels = names(l), level, knit = TRUE, close_tabset = FALSE) {                                                  
    if(is.null(labels)) {                                                                                                              
        stop("labels are NULL, it is required not to be so that the tabs have proper names")                                           
    }                                                                                                                                  
    names(l) <- labels                                                                                                                 
    rmd_code <- lapply(seq_along(l), FUN = function(i) obj_to_rmd(l[[i]], name = names(l)[i], level = level + 1L))                     
    if(isTRUE(getOption("knitr.in.progress"))) {                                                                                       
        res <- knitr::knit(text = unlist(rmd_code), quiet = TRUE)                                                                      
        cat(res)                                                                                                                       
    } else {                                                                                                                           
        if(!knit) {                                                                                                                    
            cat(unlist(rmd_code))                                                                                                      
        } else {                                                                                                                       
            return(l)                                                                                                                  
        }                                                                                                                              
    }                                                                                                                                  
    if(close_tabset) {                                                                                                                 
        cat(paste(get_section(level), "{.unlisted .unnumbered .toc-ignore .tabset}", "\n"))                                            
    }                                                                                                                                  
}                                                                                                                                      
                                                                                                                                       
get_section <- function(level) {                                                                                                       
    paste(rep("#", times = level), collapse = "")                                                                                      
}                                                                                                                                      
                                                                                                                                       
get_tabset <- function(obj) {                                                                                                          
    ifelse(inherits(obj, "list"), "{.tabset}", "")                                                                                     
}                                                                                                                                      
                                                                                                                                       
obj_to_rmd <- function(obj, parent_name = "l", name, level) {                                                                          
    section_code <- sprintf("%s %s %s\n", get_section(level), name, get_tabset(obj))                                                   
    if(!inherits(obj, "list")) {                                                                                                       
            rmd_code <- c("```{r, echo = FALSE}\n",                                                                                    
                          sprintf("%s$`%s`\n", parent_name, name),                                                                     
                          "```\n",                                                                                                     
                          "\n")                                                                                                        
    } else {                                                                                                                           
        rmd_code <- c("\n",                                                                                                            
                      lapply(X = seq_along(obj),                                                                                       
                             FUN = function(i) obj_to_rmd(obj[[i]], sprintf("%s$`%s`", parent_name, name), names(obj)[i], level + 1L)))
    }                                                                                                                                  
    return(c(section_code, rmd_code))                                                                                                  
}                                                                                                                                      
```                                                                                                                                    
                                                                                                                                       
                                                                                                                                       
# plot 1 {.tabset}                                                                                                                     
```{r, plot-01, results = "asis"}                                                                                                      
in_tabs(lapply(l1, FUN = gplot), labels = names(l1), level = 1L)                                                                       
```                                                                                                                                    
                                                                  
# plot 2 {.tabset}                                                
```{r, plot-02, results = "asis"}                                 
in_tabs(lapply(l2, FUN = gplot), labels = names(l2), level = 1L)  
```                                                               
                                                                  
# plot 3 {.tabset}                                                
```{r, plot-03, results = "asis"}                                 
in_tabs(lapply(l1, FUN = gplotly), labels = names(l1), level = 1L)
```                                                               
                                                                  
# plot 4 {.tabset}                                                
```{r, plot-04, results = "asis"}                                 
in_tabs(lapply(l2, FUN = gplotly), labels = names(l2), level = 1L)
```   

The output I get is:

You can see the issue that the first plot is actually identical the the second plot while it should not !!!

enter image description here

When using plotly (or anything else I have tested) it works as expected as shown on plots 3 and 4

enter image description here

Could you help me fix it, I am happy with testing for the class of the object obj_to_rmd receives.

PS: rmd code in_tabs generates can be seen by running in_tabs(..., knit = FALSE). For instance

in_tabs(lapply(l1, FUN = gplot), labels = names(l1), level = 1L, knit = FALSE)
## p1 
 ```{r, echo = FALSE}
 plot(l$`p1`)
 ```

NB: this is a cross posting of r - Dynamic creation of tabs in Rmarkdown does not work for ggplot while it does for plotly - Stack Overflow hopefully I'll get more luck in here

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.