使用 xaringan 和 plotly 以编程方式在 R 中生成幻灯片

Programmatically generate slides in R with xaringan and plotly

我最近开始使用 xaringan,它非常好用。感谢一辉的大礼包。我想知道的一个问题是,是否可以在 for 循环中以编程方式生成幻灯片,每张幻灯片都包含一个 plotly plot?我知道我可以像这样生成 ggplots 幻灯片,其中 ggplot_list 是 ggplots 列表:

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  print(p)
}
```

这非常有效。

我还可以通过调用 ggplotly(ggplot_list[[1]]) 来包含单独的 plotly plots,这也很完美。

但我似乎无法将两者结合起来工作,天真地执行以下操作会为我生成空白幻灯片。

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  ggplotly(p)
}
```

更新:这里我提供了一个我迄今为止尝试过的最小示例。

---
title: "xaringan + plotly + loop?"
subtitle: "Does it work?"
author: "Fenfen Kan"
date: "2017/13/32"
output:
  xaringan::moon_reader:
    lib_dir: libs
    nature:
      highlightStyle: github
      highlightLines: true
      countIncrementalSlides: false
---

```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)
```

# Several boring ggplots

```{r, message=FALSE, warning=FALSE}
library(ggplot2)
library(plotly)

p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point(aes(color=Species))

p2 <- ggplot(iris, aes(Petal.Length, Petal.Width)) +
  geom_point(aes(color=Species))

p3 <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point(aes(color=Species))

ggplot_list <- list(p1, p2, p3)
```


---
# Invididual plotly works

```{r}
ggplotly(p1)
```

---
# ggplot slides in loop also works

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  print(p)
}
```

---
# plotly in loop doesn't work

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  ggplotly(p)
}
```

# print(ggplotly(p)) in loop doesn't work either
```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  print(ggplotly(p))
}
```

我最近在 knitr 尝试做类似的事情时想出了一个解决方案。我将它添加到上面的示例中。请参阅最后一节 - 它循环生成 3 个 plotly 幻灯片。

---
title: "xaringan + plotly + loop?"
subtitle: "Does it work?"
author: "Fenfen Kan"
date: "2017/13/32"
output:
  xaringan::moon_reader:
    lib_dir: libs
    nature:
      highlightStyle: github
      highlightLines: true
      countIncrementalSlides: false
---

```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)
```

# Several boring ggplots

```{r, message=FALSE, warning=FALSE}
library(ggplot2)
library(plotly)
library(knitr)

p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point(aes(color=Species))

p2 <- ggplot(iris, aes(Petal.Length, Petal.Width)) +
  geom_point(aes(color=Species))

p3 <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
  geom_point(aes(color=Species))

ggplot_list <- list("p1"=p1, "p2"=p2, "p3"=p3)
```


---
# Invididual plotly works

```{r}
ggplotly(p1)
```

---
# ggplot slides in loop also works

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  print(p)
}
```

---
# plotly in loop doesn't work

```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  ggplotly(p)
}
```

# print(ggplotly(p)) in loop doesn't work either
```{r, message=FALSE, warning=FALSE, results='asis'}
for (p in ggplot_list) {
  cat("\n\n---\n")
  print(ggplotly(p))
}
```

# generate chunks, then explicitly calling `knit` works! 

```{r create-markdown-chunks-dynamically, include=FALSE}

out = NULL
for (p_name in names(ggplot_list)) {
  knit_expanded <- paste0("\n\n---\n## Plot: ", p_name, "\n\n```{r results='asis', echo=FALSE, warning=FALSE, message=FALSE}\n\nggplotly(ggplot_list[['", p_name, "']])\n\n```")
  out = c(out, knit_expanded)
}

```

<!--- knit those table chunk statements --> 
`r paste(knit(text = out), collapse = '\n')`