r - 在 RMarkdown 代码块中循环



我有一个这样的文档:

```{r, include = F}
require(data.table)
dt <- data.table(
A = c(1, 4, 1, 4, 2, 4, 8),
B = c(2, 2, 3, 4, 3, 1, 5)
)
```

```{r, echo = F}
col <- "A"
knitr::asis_output(paste0("### Column ", col, "n"))
knitr::asis_output("Countsn")
dt[, .(n = .N), by = col]
knitr::asis_output("Statisticsn")
summary(dt[, get(col)])
```

```{r, echo = F}
col <- "B"
knitr::asis_output(paste0("### Column ", col, "n"))
knitr::asis_output("Countsn")
dt[, .(n = .N), by = col]
knitr::asis_output("Statisticsn")
summary(dt[, get(col)])
```

虽然这工作正常,但显然,这是非常重复的。我尝试使用循环而不是复制粘贴,如下所示:

```{r, echo = F}
for (col in c("A", "B")) {
knitr::asis_output(paste0("### Column ", col, "n"))
knitr::asis_output("Countsn")
dt[, .(n = .N), by = col]
knitr::asis_output("Statisticsn")
summary(dt[, get(col)])
}
```

但是,这根本不打印任何输出。如何在 RMarkdown 文档中循环并生成降价和 R 输出?

您需要一个print语句才能获得summary结果。您的代码将更改为以下内容,其中仅将print语句添加到summary输出中:

```{r, echo = F}
for (col in c("A", "B")) {
print(knitr::asis_output(paste0("### Column ", col)))
print(knitr::asis_output("Counts"))
print(dt[, .(n = .N), by = col])
print(knitr::asis_output("Statistics"))
print(summary(dt[, get(col)]))
}
```

这将产生以下结果:

## [1] "### Column A"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
## [1] "Counts"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
##    A n
## 1: 1 2
## 2: 4 3
## 3: 2 1
## 4: 8 1
## [1] "Statistics"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.500   4.000   3.429   4.000   8.000 
## [1] "### Column B"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
## [1] "Counts"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
##    B n
## 1: 2 2
## 2: 3 2
## 3: 4 1
## 4: 1 1
## 5: 5 1
## [1] "Statistics"
## attr(,"class")
## [1] "knit_asis"
## attr(,"knit_cacheable")
## [1] NA
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   3.000   2.857   3.500   5.000

打印时,您可能希望重新格式化和删除属性。

编辑

根据@user2554330的建议,这里有一个使用knitr::knit_print的示例:

```{r, echo = F}
for (col in c("A", "B")) {
knitr::knit_print(paste0("### Column ", col))
knitr::knit_print("Counts")
knitr::knit_print(dt[, .(n = .N), by = col])
knitr::knit_print("Statistics")
knitr::knit_print(summary(dt[, get(col)]))
}
```

给出以下输出

## [1] "### Column A"
## [1] "Counts"
##    A n
## 1: 1 2
## 2: 4 3
## 3: 2 1
## 4: 8 1
## [1] "Statistics"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.500   4.000   3.429   4.000   8.000 
## [1] "### Column B"
## [1] "Counts"
##    B n
## 1: 2 2
## 2: 3 2
## 3: 4 1
## 4: 1 1
## 5: 5 1
## [1] "Statistics"
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   3.000   2.857   3.500   5.000

编辑 2

以下替代解决方案将更紧密地打印 SO 所要求的内容。 它全局删除"##"前缀,并将其重新添加到data.frame中(即仅在需要的地方)。它还使用cat代替knitr::knit_print以避免打印数组索引(即[1])。

```{r, echo = F, comment=NA}
for (col in c("A", "B")) {
cat(paste0("Column ", col), "n")
cat("Countsn")
## Add comment prefix
tdf <- as.data.frame(dt[, .(n = .N), by = col]) ## Convert to data.frame for printing
rownames(tdf) <- paste("## ", 1:nrow(tdf))      ## Add comments for printing.
knitr::knit_print(tdf)
cat("Statisticsn")
## Add comment prefix
knitr::knit_print(summary(dt[, get(col)]))
}
```

下面的输出是SO要求的更多内容(基于对这篇文章的评论)。 它以"##"作为data.frame输出前缀,但摘要输出没有"##"前缀;如果需要,可以添加它。

Column A 
Counts
A n
##  1 1 2
##  2 4 3
##  3 2 1
##  4 8 1
Statistics
Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
1.000   1.500   4.000   3.429   4.000   8.000 
Column B 
Counts
B n
##  1 2 2
##  2 3 2
##  3 4 1
##  4 1 1
##  5 5 1
Statistics
Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
1.000   2.000   3.000   2.857   3.500   5.000 

最新更新