Reputation: 5983
I have a document that's something like this:
```{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("Counts\n")
dt[, .(n = .N), by = col]
knitr::asis_output("Statistics\n")
summary(dt[, get(col)])
```
```{r, echo = F}
col <- "B"
knitr::asis_output(paste0("### Column ", col, "\n"))
knitr::asis_output("Counts\n")
dt[, .(n = .N), by = col]
knitr::asis_output("Statistics\n")
summary(dt[, get(col)])
```
Whilst this works fine, obviously, this is very repetitive. I tried to use a loop rather than the copy-paste, like so:
```{r, echo = F}
for (col in c("A", "B")) {
knitr::asis_output(paste0("### Column ", col, "\n"))
knitr::asis_output("Counts\n")
dt[, .(n = .N), by = col]
knitr::asis_output("Statistics\n")
summary(dt[, get(col)])
}
```
This however prints no output at all. How can I loop in an RMarkdown document and produce both markdown and R output?
Upvotes: 1
Views: 534
Reputation: 5532
You need a print
statement for the summary
results. Your code would change to the following where only the print
statement was added to the summary
output:
```{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)]))
}
```
This produces the following results:
## [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
You may want to reformat and remove attributes when printing.
Edit
At the suggestion from @user2554330 here is an example using 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)]))
}
```
which gives the following output
## [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
Edit 2
The following alternate solution will more closely print what the SO is asking for. It removes the "## " prefix globally and adds it back in for the data.frame
(i.e. only where needed). It also uses cat
in place of knitr::knit_print
to avoid printing the array indexes (i.e. [1]
).
```{r, echo = F, comment=NA}
for (col in c("A", "B")) {
cat(paste0("Column ", col), "\n")
cat("Counts\n")
## 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("Statistics\n")
## Add comment prefix
knitr::knit_print(summary(dt[, get(col)]))
}
```
The output below is more of what the SO is asking for (based on comments to this post). It prefixes the data.frame
output with "## " but the summary output does not have the "## " prefix; this can be added if needed.
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
Upvotes: 1