Альтернативный текст и вывод ggplot в векторизованной функции в выводе Rmarkdown - PullRequest
0 голосов
/ 04 мая 2020

Допустим, у меня есть набор данных с несколькими переменными, которые я хочу изучить, нанося на график их распределения, например, в виде гистограммы. Я создаю отчет Rmarkdown и автоматизирую это построение в векторной функции. Достаточно просто:

---
title: "Doc title"
output: html_notebook
---

```{r setup}
library(tidyverse, magrittr)

opts_knit$set(root.dir = ROOT_DIR)
opts_chunk$set(results = 'asis', warning = FALSE)
```

```{r dataset}
set.seed(303574)

dataset <- tibble(
  var_1 = sample.int(4, 20, replace = TRUE),
  var_2 = sample.int(7, 20, replace = TRUE)
)
```

# Histograms

```{r plot}
dataset %>% iwalk(
  ~{
    dataset %$% qplot(.x, xlab = .y, geom = "bar") %>% print()
  }
)
```

Когда я вяжу этот документ, я получаю ожидаемый результат. Теперь я хочу создать раздел, добавив заголовок для каждой переменной, таким образом разделив графики в разных разделах (в данном случае, с вкладкой для каждой переменной).

Это то, что я ожидал отрисовать вывод, который я намереваюсь:

---
title: "Doc title"
output: html_notebook
---

```{r setup}
library(tidyverse, magrittr)

opts_knit$set(root.dir = ROOT_DIR)
opts_chunk$set(results = 'asis', warning = FALSE)
```


```{r dataset}
set.seed(303574)

dataset <- tibble(
  var_1 = sample.int(4, 20, replace = TRUE),
  var_2 = sample.int(7, 20, replace = TRUE)
)
```


# Histograms {.tabset}

```{r plot, results='asis'}
dataset %>% iwalk(
  ~{
    paste0("## ", .y) %>% cat(fill = TRUE)
    dataset %$% qplot(.x, xlab = .y, geom = "bar") %>% print()
  }
)
```

Однако происходит то, что оба заголовка отображаются за до любого из графиков. В результате у меня есть одна пустая вкладка на переменную, за исключением последней, где все графики отображаются полностью (в этом минимальном примере одна пустая вкладка и другая с двумя графиками вместо графика на вкладке).

Как заставить knitr чередовать рендеринг текста и сюжетов? Я пробовал с for l oop, то есть:

for (var in dataset %>% colnames()) {

  paste("##", var) %>% cat(fill = TRUE)
  qplot(dataset[[var]], xlab = var, geom = "bar") %>% print()
}

Но это тоже не сработало.

Спасибо большое!

PS: Обратите внимание, что этот вопрос похож на этот ; однако разница в том, что я пытаюсь добавить автоматически отображаемые заголовки.

Обновление (2020-05-06):

Как выясняется, это происходит только при выводе это ноутбук (т. е. html_notebook); при рендеринге в html_document графики располагаются правильно, и это больше не проблема.

1 Ответ

1 голос
/ 04 мая 2020

Вы можете сделать это, используя функцию из этого ответа: { ссылка }. Проблема в том, что knitr не выведет правильный источник Markdown, чтобы делать то, что вы хотите, поэтому вам нужно делать то, что он должен делать. Итак, определите эту функцию:

encodeGraphic <- function(g) {
  png(tf1 <- tempfile(fileext = ".png"))  # Get an unused filename in the session's temporary directory, and open that file for .png structured output.
  print(g)  # Output a graphic to the file
  dev.off()  # Close the file.
  txt <- RCurl::base64Encode(readBin(tf1, "raw", file.info(tf1)[1, "size"]), "txt")  # Convert the graphic image to a base 64 encoded string.
  myImage <- htmltools::HTML(sprintf('<img src="data:image/png;base64,%s">', txt))  # Save the image as a markdown-friendly html object.
  return(myImage)
}

Затем вы можете получить желаемый результат, используя этот код. Мне нужно было вставить несколько дополнительных символов новой строки, но в остальном это в основном то, что у вас было, запустить encodeGraphic:

```{r plot, results='asis'}
dataset %>% iwalk(
  ~{
    paste0("\n## ", .y, "\n") %>% cat()
    dataset %$% qplot(.x, xlab = .y, geom = "bar") %>%
      encodeGraphic() %>% cat()
  }
)
```
...