Search code examples
rr-markdownpowerpoint

Using R Markdown to print one graph per slide, without text box


I am working with survey data in R and trying to present question results by different groups. Sample markdown file:

---
title: "sample_results"
output:
  powerpoint_presentation: default 
  #  reference_doc: reference.pptx
date: "2023-09-20"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
pacman::p_load(tidyverse, ggplot2, janitor, tools, purrr, ggtext)
```

   

```{r, echo = FALSE, message=FALSE}
# Build DF 

df <- data.frame(
  grp1 = c("A", "B","A", "A", "A", "C", "C", "A"),
  grp2 = c("R","D","R","D","R","D","R","D"),
  q1 = c("Agree", "Disagree", "Disagree", "Agree", "Disagree", "Disagree", "Disagree", "Disagree"), 
  q2 = c("A lot", "A lot","A lot", "A little","A lot", "A little","A lot", "A little")
  
)

qs <- colnames(df)[3:4]

```


```{r, echo=FALSE, message=FALSE, warnings=FALSE}
# Results by group for questions 

myplots1 <- list()

for(i in qs) {
  title <- i
  df2 <-  df %>% 
  group_by(df[[i]], grp1, .drop = F) %>% 
  tally() %>%   
    rename(q = 1) 
  
  myplots1[[i]] <- ggplot(df2) + geom_bar(aes(x = q, y = n), 
                      position = position_dodge2(), 
                      stat = "identity")  + 
   facet_wrap(~grp1, scales = "free")  + 
            geom_text(data = subset(df2, n != 0), aes(x=q, y = n, label = n), vjust = -.5)  + 
     theme(axis.text.x = element_text(angle = 45, vjust =1 ,  hjust=1)) + 
    ggtitle(i)
 

  
}



myplots2 <- list()

for(i in qs) {
  title <- i
  df2 <-  df %>% 
  group_by(df[[i]], grp2, .drop = F) %>% 
  tally() %>%   
    rename(q = 1) 
  
  myplots2[[i]] <- ggplot(df2) + geom_bar(aes(x = q, y = n), 
                      position = position_dodge2(), 
                      stat = "identity")  + 
   facet_wrap(~grp2, scales = "free")  + 
            geom_text(data = subset(df2, n != 0), aes(x=q, y = n, label = n), vjust = -.5)  + 
     theme(axis.text.x = element_text(angle = 45, vjust =1 ,  hjust=1)) + 
    ggtitle(i)
 

  
}

```

--- 

# Responses for Q1 by grp 1 

--- 


```{r,  echo=FALSE, fig.keep='all', results = 'asis',  width='100%', height='100%', warnings=FALSE, dpi=300}
# Results by Zone for main questions  -- for slides 
ys <- names(myplots1)
walk(ys, function(y) {
      one_plot <- myplots1[[y]]
      print(one_plot)
            cat('\n\n' )
    })

```




--- 

# Responses for Q1 by grp 2

--- 


```{r,  echo=FALSE, fig.keep='all', results = 'asis',  width='100%', height='100%', warnings=FALSE, dpi=300}
# Results by grp2 for main questions  -- for slides 
ys2 <- names(myplots2)
walk(ys2, function(y) {
      one_plot <- myplots2[[y]]
      print(one_plot)
            cat('\n\n' )
    })

```

The output I get is unexpected. The first slide in each group appears to render correctly, but the second and each after will have a textbox. How can I eliminate that? I have tried using a reference slide, but have not had success.

enter image description here

enter image description here


Solution

  • One option to fix your issue would be to explicitly start a new slide for each plot by adding cat('##\n') at the start of the for loops:

    ---
    title: "sample_results"
    output:
      powerpoint_presentation: default 
      #  reference_doc: reference.pptx
    date: "2023-09-20"
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    pacman::p_load(tidyverse, ggplot2, janitor, tools, purrr, ggtext)
    ```
    
    ```{r, echo = FALSE, message=FALSE}
    # Build DF
    
    df <- data.frame(
      grp1 = c("A", "B", "A", "A", "A", "C", "C", "A"),
      grp2 = c("R", "D", "R", "D", "R", "D", "R", "D"),
      q1 = c("Agree", "Disagree", "Disagree", "Agree", "Disagree", "Disagree", "Disagree", "Disagree"),
      q2 = c("A lot", "A lot", "A lot", "A little", "A lot", "A little", "A lot", "A little")
    )
    
    qs <- colnames(df)[3:4]
    ```
    
    
    ```{r, echo=FALSE, message=FALSE, warnings=FALSE}
    # Results by group for questions
    
    myplots1 <- list()
    
    for (i in qs) {
      title <- i
      df2 <- df %>%
        group_by(df[[i]], grp1, .drop = F) %>%
        tally() %>%
        rename(q = 1)
    
      myplots1[[i]] <- ggplot(df2) +
        geom_bar(aes(x = q, y = n),
          position = position_dodge2(),
          stat = "identity"
        ) +
        facet_wrap(~grp1, scales = "free") +
        geom_text(data = subset(df2, n != 0), aes(x = q, y = n, label = n), vjust = -.5) +
        theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
        ggtitle(i)
    }
    
    
    
    myplots2 <- list()
    
    for (i in qs) {
      title <- i
      df2 <- df %>%
        group_by(df[[i]], grp2, .drop = F) %>%
        tally() %>%
        rename(q = 1)
    
      myplots2[[i]] <- ggplot(df2) +
        geom_bar(aes(x = q, y = n),
          position = position_dodge2(),
          stat = "identity"
        ) +
        facet_wrap(~grp2, scales = "free") +
        geom_text(data = subset(df2, n != 0), aes(x = q, y = n, label = n), vjust = -.5) +
        theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
        ggtitle(i)
    }
    ```
    
    # Responses for Q1 by grp 1 
    
    ```{r,  echo=FALSE, fig.keep='all', results = 'asis',  width='100%', height='100%', warnings=FALSE, dpi=300}
    # Results by Zone for main questions  -- for slides
    ys <- names(myplots1)
    walk(ys, function(y) {
      one_plot <- myplots1[[y]]
      cat("##\n")
      print(one_plot)
      cat("\n\n")
    })
    ```
    
    # Responses for Q1 by grp 2
    
    ```{r,  echo=FALSE, fig.keep='all', results = 'asis',  width='100%', height='100%', warnings=FALSE, dpi=300}
    # Results by grp2 for main questions  -- for slides
    ys2 <- names(myplots2)
    walk(ys2, function(y) {
      one_plot <- myplots2[[y]]
      cat("##\n")
      print(one_plot)
      cat("\n\n")
    })
    ```
    

    enter image description here