如何在 R Notebook 中并排获取控制台输出和绘图?

How to get console output and plot side by side in a R Notebook?

在 R Notebook 中,有一个函数可以在控制台中绘制许多图并打印汇总统计信息。 我想在 HTML 输出上并排显示绘图和控制台输出( 汇总统计信息)。

这是一个非常简单的例子:

---
title: "Example"
output: html_notebook
---


```{r}
mapply(FUN = function(.x) {
  plot(.x)
  summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```

以上代码的输出如下:

如您所见,绘图是一个接一个,控制台输出位于中间位置。

预期输出如下:

我浏览了这些 SO 主题但没有成功:

请注意,我真的在尝试获取 console 输出,如果可能的话,我想避免使用许多转换来获取 grob 或图片,因为有时是相关的我的实际输出的方法不存在。 可以不使用 R Notebook,而是使用 RMarkdown。

高效,但不准确

对于示例设置,我建议使用 pandoc 语法对多列拆分操作以轻松适应它们 side-by-side。这样我们就可以调用我们想要的具体内容了。

---
title: "R Notebook"
output:
  html_document:
---

```{r, echo = F}
il <- split(iris, iris$Species)
```

:::: {.columns}

::: {.column width="60%"}
```{r, echo = F, results = F}
lapply(il, plot)
```
:::

::: {.column width="40%"}
```{r, echo = F}
lapply(il, summary)
```
:::

::::

这样的输出如下:

低效,但准确

不过,据我了解,您可能需要完全符合说明的结果。我不知道如何在一次调用中拆分控制台输出和绘图。我们可以做的是操纵 RMarkdown 输出,使其 显示 它们来自单个调用。请注意,这是低效的,我建议将生成图表和摘要输出的函数分解为单独的函数,以便像第一个示例一样使用。

---
title: "R Notebook"
output:
  html_document:
---

```{r, results = F, fig.show = "hide"}
mapply(FUN = function(.x) {
  plot(.x)
  summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```

:::: {.columns}

::: {.column width="60%"}
```{r, echo = F, results = F}
mapply(FUN = function(.x) {
  plot(.x)
  summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```
:::

::: {.column width="40%"}
```{r, echo = F, fig.show = "hide"}
mapply(FUN = function(.x) {
  plot(.x)
  summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```
:::

::::

结果看起来非常接近您想要的输出:

我们仅通过 运行 相同的函数(假设它是您提到的函数)来实现,在第一种情况下隐藏绘图和文本输出,但保留代码,然后仅保留绘图左列,右列仅输出文本。

希望对您有所帮助。

它并不完美。例如,我没有添加屏幕尺寸的处理程序。但是,我可以。不过,你必须让我知道你在找什么。

这在 R Markdown 中使用 Javascript。这个引擎是内置的。但是,我添加了代码供您检查(您应该选择):names(knitr::knit_engines$get()).

此外,在 setup 块中,我添加了 options(width = 75)。这将影响所有块输出。您可以更改它以使其成为特定于块的选项。但是,默认值为 80,因此您可能不会注意到差异。我这样做是因为对于三个组中的两个,Species 换行到下一行。但是,versicolor就不一样了。这是执行统一性的一部分。

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)

# confirm engine for 'js' (it was #37 for me)
names(knitr::knit_engines$get())

# set the output width for chunks' render
# this is to keep the summaries even (versicolor was doing its own thing)
options(width = 75)
library(tidyverse)
```

样式不是一个块。这在设置和下一个块之间进行。

<style>
.setupCols {
  display:flex;
  flex-direction:row;
  width: 100%;
}
.setupCols p{
  display:flex;
  flex-direction: column;
  width: 45%;
}

.setupCols pre {
  display:flex;
  flex-direction: column;
  width: 55%
}
.setupCols pre code {
  font-size: 85%;
}
</style>

接下来是您 mapply 调用之前和之后的一些代码。

<div class="setupCols">

```{r graphOne}
mapply(FUN = function(.x) {
  plot(.x)
  summary(.x)
}, split(iris, iris$Species), SIMPLIFY = FALSE)
```

</div>

在任何时间点在此块之后,您将添加一个样式块。如果您希望它多次应用,请将此块移至末尾。如果您只希望它应用于块(我命名)graphOne,则将其设为下一个块。

```{r styler,results='asis',engine='js'}

// search for class and tags
elem = document.querySelector('div.setupCols > pre > code');
// remove hashtags
elem.innerHTML = elem.innerHTML.replace(/#{2}/g, '');
// add newlines between summaries
elem.innerHTML = elem.innerHTML.replace(/\s{9}\n/g, '<br /><br />')

```

如果你运行内联这个块,你将不会得到任何输出。但是,当您 knit.

时,您会看到此输出

我也在这里添加了一些文字,但它看起来是这样的:

如果您想查看 Javascript 在做什么,您可以添加 eval = Fknit。这就是它的样子:

如果我遗漏了什么或者您有任何问题,请告诉我。

似乎非常有效,如果您有足够的 HTML 和 Javascript 知识,感觉应该是这条路。然而,这不是我的情况,所以现在我坚持使用内置 knitr 功能。

我想提议将其作为对 but it told me "edit queue is full". So here is an idea from what he proposed and R markdown cookbook - section 16.4 的编辑。

原理是在 mapply(FUN = ) 中调用另一个 .Rmd 文件中的另一个 Rmarkdown 脚本或一个包含制作此类文件所需元素的向量。 通过这样做,R notebook 丢失,“经典”.Rmd 被创建并且不可能看到它下面的块的输出。事实上,如果您尝试 运行 块,它会发送以下错误:Error in setwd(opts_knit$get("output.dir")) : character argument expected。但是,如果您单击 knit.

,它会生成一个 HTML 文件

这是 .Rmd 文件:

---
title: "Example"
output:
  html_document
---

```{r, echo=FALSE, results='asis'}
out <- mapply(function(x) {
  knitr::knit_child(text = c(
    '',
    ':::: {.columns}',
    '',
    '::: {.column width="40%"}',
    '```{r}',
    'plot(x)',
    '```',
    ':::',
    '',
    '::: {.column width="60%"}',
    '```{r}',
    'summary(x)',
    '```',
    ':::',
    '',
    '::::'
  ), envir = environment(), quiet = TRUE)
}, split(iris, iris$Species), SIMPLIFY = TRUE)

cat(unlist(out), sep = '\n')
```

以及输出:

然而,这对我来说似乎很“hacky”并且为 text 参数编写 c() 向量很容易出错。