generate markdown comments within for loop

2019-01-10 21:30发布

问题:

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, but I am not sure if it's possible.

Here is simple example, this is in test.R:

for (i in 1:5) {
    ## This is a heading for `i`
    #' This is a comment for `i`
    print(i)    
}

Then i use spin to generate a Rmd file: spin('test.R')

However, the Rmd file looks like the following.

```{r }
for (i in 1:5) {
    ## This is a heading for `i`
    #' This is a comment for `i`
    print(i)    
}
```

The markdown comments within the R chunk are not compiled into HTML. Is it possible?

Thanks, Peter

回答1:

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


回答2:

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.



回答3:

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 knitting. 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_?

--------------------------------------------------------------
     &nbsp;        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_