I am trying to generate an HTML report, using knitr, based on an R script that has for loops. I want to generate markdown comments from the comments within the for loop, bu
One solution that worked for me, is provided by how to create a loop that includes both a code chunk and text with knitr in R. By using Both results='asis'
and two spaces in front of \n
at the end of each loop.
example:
Without two spaces:
```{r, results='asis'}
headers <- list("We","are","your","friends")
for (i in headers){
cat("\n##H ", i, " \n")
cat("comment",i)
}
Output (html):
As you can see, the comments and headings get messed together
Solution:
With two spaces: cat(" \n")
at the end of the loop
for (i in headers){
cat("\n##H ", i, "\n")
cat("comment",i)
cat(" \n")# <---------------------------------
}
note: cat(" \n")
needs to be at the very end, it does not work even if you plot or calculate something it in the loop.
I think you can obtain what you want in knitr with the code chunk option results='asis' that you can specify after "#+" in an R script to be passed to spin (but the code looks less "clean" than the interesting brew solution proposed by @daroczig):
#+ results='asis', echo = FALSE
for (i in 1:5) {
cat("## This is a heading for ", i, "\n")
cat("<!-- This is a comment for ", i, "-->\n")
print(i)
}
If this is test.R script and that you do spin("test.R"), the resulting md file will look like that :
## This is a heading for 1
<!-- This is a comment for 1 -->
[1] 1
## This is a heading for 2
<!-- This is a comment for 2 -->
[1] 2
## This is a heading for 3
<!-- This is a comment for 3 -->
[1] 3
## This is a heading for 4
<!-- This is a comment for 4 -->
[1] 4
## This is a heading for 5
<!-- This is a comment for 5 -->
[1] 5
I have (re)implemented some features of knitr
independently from @Yihui based on brew
in my pander package that could help with such (and similar) issues if you do not want to run brew
before knit
ting. Quick demo:
> Pandoc.brew(text = "# Demonstrating a nice loop
+ <% for (i in 1:5) { %>
+ ## This is a header for <%=i%>
+ #' This is a comment for <%=i%>
+ <% } %>")
# Demonstrating a nice loop
## This is a header for _1_
#' This is a comment for _1_
## This is a header for _2_
#' This is a comment for _2_
## This is a header for _3_
#' This is a comment for _3_
## This is a header for _4_
#' This is a comment for _4_
## This is a header for _5_
#' This is a comment for _5_
Please note that you could also pass a file to Pandoc.brew
(no need to use such troublesome setup with the text
argument with real-life problems), and that you could also use <% ... %>
tags for e.g. conditionals (like showing or not rendering part of a report). And most importantly: there is a huge difference between <% ... %>
(unprocessed R commands) and <%= ... %>
(results are processed by pander
) tags. The latter means that all returned R objects are transformed to Pandoc's markdown, e.g.:
> Pandoc.brew(text = "# Demonstrating a conditional
+ <% for (i in 1:5) { %>
+ ## This is a header for <%=i%>
+ <% if (i == 3) { %>
+ Hey, that's **almost** <%=pi%>, that's between <%=3:4%>! Wanna fit a model to _celebrate_?
+ <%= lm(mpg ~ hp, mtcars) %>
+ <% }} %>")
# Demonstrating a conditional
## This is a header for _1_
## This is a header for _2_
## This is a header for _3_
Hey, that's **almost** _3.142_, that's between _3_ and _4_! Wanna fit a model to _celebrate_?
--------------------------------------------------------------
Estimate Std. Error t value Pr(>|t|)
----------------- ---------- ------------ --------- ----------
**hp** -0.06823 0.01012 -6.742 1.788e-07
**(Intercept)** 30.1 1.634 18.42 6.643e-18
--------------------------------------------------------------
Table: Fitting linear model: mpg ~ hp
## This is a header for _4_
## This is a header for _5_