Search code examples
htmlrr-markdownsjplot

knit sjplot as html output


I am using sjPlot::tab_xtab to create some tables in rmarkdown (they look great!). However, the tables are generated as individual html pages in my browser, and not as a single html file. Similar to this problem here.

According to the documentation, we can use sjtab to knit tables into a html file: (this is what I want)

```{r}
library(dplyr)
library(sjPlot)
library(sjmisc)
data(efc)
 
efc %>% 
  group_by(e16sex, c172code) %>% 
  select(e42dep, n4pstu, e16sex, c172code) %>% 
  sjtab(fun = "xtab")
```

I don't know how to incorporate this sjtab into my user function to generate the plots. I also looked through this documentation, but could not find the solution. Right now, I have to take a screen shot of each table that appears my browser and paste the tables together. :(

Problem: I want to have all the tables in a single file (html, pdf or word) so that I can scroll down the file to view all the tables at once.

Could someone please let me know how I can render each of the tables into a single html file?

Here is the code from my rmarkdown file. It should run with no error.

---
title: "testChi"
author: "g"
date: "10/15/2021"
output:
  pdf_document: default
  word_document: default
  html_document: default
---



```{r setup, include=FALSE, error=FALSE, warning=FALSE}
library(magrittr)
library(dplyr)
library(readr)
library(pander)



# cols <- svy_final %>% select(matches("Q44_[[:digit:]]")) %>% names(.)
cols <- mtcars %>% select(matches("mpg|cyl|disp")) %>% names(.)

create_plots <- function(dat,title_name) {

  # school <- enquo()
 for (i in cols) {
    plt <- sjPlot::tab_xtab(
      var.row =  dat$gear,
      var.col = dat[[i]],
      show.row.prc = TRUE,
      var.labels = c("gear size", i),
      title = title_name
    )
    # return(out)
    print(plt)
  }
}

```




```{r loop_print, results = 'asis',error=FALSE, warning=FALSE, message=FALSE}

create_plots(mtcars, 'gear and stuff') %>% pander()


```

Solution

  • I got your markdown running and I can see the problem.

    For me the workaround below worked. It is basically your code, just that each plot isn't called in the loop, but saved to a list. Afterwards you just call each plot separately from the list l[[1]], l[[2]], l[[3]] without using a loop.

    Your problem seems to appear whenever you call the plots inside a loop.

    ---
    title: "testChi"
    author: "g"
    date: "10/15/2021"
    output:
      html_document: default
    ---
    
    ``````{r packages, include = F}
    library(magrittr)
    library(dplyr)
    library(readr)
    library(pander)
    ```
    
    
    ```{r tables, , print = F, echo = F, results="asis"}
    
    cols <- mtcars %>% select(matches("mpg|cyl|disp")) %>% names(.)
    dat <- mtcars
    title_name <- 'gear and stuff'
    
    l = list()
    i = 1;
    
    for (x in cols) {
          plt <- sjPlot::tab_xtab(
          var.row =  dat$gear,
          var.col = dat[[x]],
          show.row.prc = TRUE,
          var.labels = c("gear size", x),
          title = title_name)
          l[[i]] <- plt
          i = i+1
    }
    
    l[[1]]
    l[[2]]
    l[[3]]
    
    ```
    

    The result ( all plots below each other):

    enter image description here

    Here is also a version without having to call each element separately:

    ---
    title: "testChi"
    author: "g"
    date: "10/15/2021"
    output:
      html_document: default
    ---
    
    ``````{r packages, include = F}
    library(magrittr)
    library(dplyr)
    library(readr)
    library(pander)
    ```
    
    
    ```{r tables, , print = F, echo = F, results="asis"}
    
    cols <- mtcars %>% select(matches("mpg|cyl|disp")) %>% names(.)
    dat <- mtcars
    title_name <- 'gear and stuff'
    
    i = 1;
    c <- character()
    
    for (x in cols) {
          plt <- sjPlot::tab_xtab(
          var.row =  dat$gear,
          var.col = dat[[x]],
          show.row.prc = TRUE,
          var.labels = c("gear size", x),
          title = title_name)
          c <-  paste(c, plt$knitr)
    }
    
    knitr::raw_html(c)
    
    
    ```
    

    I think in general you have to avoid separate print statements on the return object of tab_xtab(), since it is always a whole html page. While $knitr from the return object isn't a whole html page, but instead only the html code for the tables.

    Another version to fit exactly the initial example with a function:

      ---
    title: "testChi"
    author: "g"
    date: "10/15/2021"
    output:
      html_document: default
    ---
    
    
    
    ```{r setup, include=FALSE, error=FALSE, warning=FALSE}
    library(magrittr)
    library(dplyr)
    library(readr)
    library(pander)
    
    
    cols <- mtcars %>% select(matches("mpg|cyl|disp")) %>% names(.)
    
    create_plots <- function(dat,title_name) {
    
     c <- character()
     for (i in cols) {
        plt <- sjPlot::tab_xtab(
          var.row =  dat$gear,
          var.col = dat[[i]],
          show.row.prc = TRUE,
          var.labels = c("gear size", i),
          title = title_name
        )
      c <-  paste(c, plt$knitr)
    
     }
     knitr::raw_html(c)
    
    }
    
    ```
    
    ```{r loop_print, results = 'asis',error=FALSE, warning=FALSE, message=FALSE}
    create_plots(mtcars, 'gear and stuff')
    ```
    
    ```{r loop_print2, results = 'asis',error=FALSE, warning=FALSE, message=FALSE}
    create_plots(mtcars, 'other stuff')
    ```