可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to iterate over a list of result-sets in my R markdown file. When I produce the output I want to include some text like headers with the name of the result set.
One hacky solution I have found is to hardcode the html output directly in the documentation like this
## All results
```{r loopResults, echo=FALSE, results='asis'}
results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))
for(res in names(results)) {
cat(paste("<h3>Results for: ", res, "</h3>>"))
plot(results[[res]]$x, results[[res]]$y)
}
This doesn't seem to be the right way to do things, especially since I want to create PDF documents via pandoc at time and would have to change the hard-coded expressions. (I have currently convenience functions like h3(text, type)).
Is there a better way of doing this?
回答1:
I would use a combination of brew
and knitr
to achieve this. I would create a brew template called doc.brew
which looks like this
<% for (res in names(results)) { -%>
### Results for: <%= res %>
```{r}
plot(results[["<%= res %>"]]$x, results[["<%= res %>"]]$y)
```
<% } %>
You can now run the following code to get your desired output
results = list(
result1 = data.frame(x=rnorm(3), y=rnorm(3)),
result2=data.frame(x=rnorm(3), y=rnorm(3))
)
brew::brew('doc.brew', 'doc.Rmd')
knit2html('doc.Rmd')
回答2:
A possibility is to make your markdown file generate markdown instead of HTML. For example :
## All results
```{r loopResults, echo=FALSE, results='asis'}
results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))
for(res in names(results)) {
cat(paste("Results for: ", res,"\n"))
cat("=========================\n")
plot(results[[res]]$x, results[[res]]$y)
cat("\n")
}
```
If you apply the knit()
function to it in R, you will get the following Markdown file :
## All results
Results for: result1
=========================
![plot of chunk loopResults](figure/loopResults1.png)
Results for: result2
=========================
![plot of chunk loopResults](figure/loopResults2.png)
And you should be able to use pandoc
to produce HTML or LaTeX from this file ?
回答3:
Following https://gist.github.com/yihui/3145751 you can write a child template for inclusion and loop over that.
foosub.Rmd
Results for `r res`
---------------------------
```{r}
plot(results[[res]]$x, results[[res]]$y)
```
foo.Rmd
```{r loopResults, include=FALSE}
results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))
out=NULL
for(i in 1:length(results)) {
res = names(results)[i]
out = c(out, knit_child('foosub.Rmd', sprintf('foosub-%d.txt', i)))
}
```
`r paste(out, collapse = '\n')`
The code chunk in the master file doesn't produce any output itself, it just renders the child documents, one for each of your results, and stores it all up in out
(which is why it has include=FALSE
). All the formatted output is collected in the out
variable and inserted by the last line.
Its a bit awkward, but it does encourage modularity, but it doesn't seem as simple as being able to do:
```{r}
for(i in 1:10){
```
Plot `r i`
-----------
```{r}
plot(1:i)
}
```
which you cant.
回答4:
An alternative solution with pander:
<% for (res in names(results)) { %>
### Results for: <%= res %>
<%=
plot(results[[res]]$x, results[[res]]$y)
%>
<% } %>
And just Pandoc.brew
this in one run to get what you were up to:
> Pandoc.brew('doc.brew')
### Results for: result1
![](/tmp/Rtmp4yQYfD/plots/568e18992923.png)
### Results for: result2
![](/tmp/Rtmp4yQYfD/plots/568e6008ed8f.png)
Or generate HTML/docx/etc. in one run:
> Pandoc.brew('doc.brew', output = tempfile(), convert = 'html')
> Pandoc.brew('doc.brew', output = tempfile(), convert = 'docx')