我想从数据帧的每一行生成带有子文档的1个markdown文档,或者从数据帧生成nrows数量的markdown文档.降价文档是template.Rmd.
我认为它应该可以创建一个for循环,但是当我尝试这样做时,by(dataFrame, 1:nrow(dataFrame), function(row) knit(file = "/Users/path/template.Rmd"))
我得到一个错误,输入意外结束.
Quitting from lines 23-26 (Preview-e0d353674d36.Rmd)
Error in knit(file = "/Users/path/template.Rmd") :
unused argument (file = "/Users/path/template.Rmd")
Calls: <Anonymous> ... eval -> eval -> tapply -> lapply -> FUN -> FUN -> knit
Execution halted
Run Code Online (Sandbox Code Playgroud)
我尝试使用@Yihui解决的同样很棒的方法来编程引用带有knitr-expand的文本:R knitr:可以以编程方式修改块标签吗?
从该解决方案中,我们有两个.Rmd文件,我的报告和模板我的报告如下所示:
# My report
```{r}
data(mtcars)
cyl.levels <- unique(mtcars$cyl)
```
## Generate report for each level of cylinder variable
```{r, include=FALSE}
src <- lapply(cyl.levels, function(ncyl) knit_expand(file = "template.Rmd"))
```
`r knit(text = unlist(src))`
Run Code Online (Sandbox Code Playgroud)
模板看起来像:
```{r, results='asis'}
cat("### {{ncyl}} cylinders")
```
```{r mpg-histogram-{{ncyl}}cyl}
hist(mtcars$mpg[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
```{r weight-histogam-{{ncyl}}cyl}
hist(mtcars$wt[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
Run Code Online (Sandbox Code Playgroud)
此解决方案为每个级别的柱面生成单个降价文档,其中包含子文档(在标题级别2).但是,我正在尝试创建一个获取.csv的报表,然后创建并修改数据框并为另一个数据帧的每一行生成内容.
我认为我坚持的是如何使用{{ncyl}}中的值以编程方式引用数据库的行.我希望能够使用{{ncyl}}的级别来对数据帧mtcars中的相关行进行处理(假设此示例中只有行==级别{{ncyl}}).
虽然data(mtcars)
行数确实比cylyinder的行数多,但R将{{ncyl}}的值存储为整数.因此,您可以调用mtcars$gear[[{{ncyl}}]]
并获取{{ncyl}}行的齿轮值.
为什么然后,当我们将它添加到我们的template.Rmd中时,它会失败?
原谅我,它不会失败,它会给我们,gear <- mtcars$gear[[{{ncyl}}]]
但我们不能创造一大块装备,就像```{r this-gear-{{gear}}}
.
这有效
```{r}
gear <- mtcars$gear[[{{ncyl}}]]
gear
```
```{r, results='asis'}
cat("### {{ncyl}} cylinders")
```
```{r mpg-histogram-{{ncyl}}cyl}
hist(mtcars$mpg[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
```{r weight-histogam-{{ncyl}}cyl}
hist(mtcars$wt[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
Run Code Online (Sandbox Code Playgroud)
这不起作用
```{r}
gear <- mtcars$gear[[{{ncyl}}]]
gear
```
```{r, results='asis'}
cat("### {{ncyl}} cylinders")
```
```{r mpg-histogram-{{ncyl}}cyl}
hist(mtcars$mpg[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
```{r weight-histogam-{{ncyl}}cyl}
hist(mtcars$wt[mtcars$cyl == {{ncyl}}],
main = paste({{ncyl}}, "cylinders"))
```
```{r {{gear}}}
gear
```
Run Code Online (Sandbox Code Playgroud)
给出错误
Quitting from lines 10-12 (Preview-e0d32d687661.Rmd)
Error in eval(expr, envir, enclos) : object 'gear' not found
Calls: <Anonymous> ... knit_expand -> inline_exec -> withVisible -> eval -> eval
Execution halted
Run Code Online (Sandbox Code Playgroud)
我想我正在接近主要问题"我如何为数据帧的每一行创建一个降价文档?" 编织扩展功能有问题.
有人可以帮助我理解:1.如何解决主要问题2.为什么{{gear}}在template.Rmd中不起作用?
所以,我仍然不明白(2),但我认为@daroczig让我接近理解解决主要问题的一种方法.我不认为这是一个问题太独特,我认为有一种方法可以解决它没有brew
或pander
或rapport
.在任何情况下,我采用brew方法并使用几行数据帧执行某些操作.它抛出一个错误.注意我没有对这段代码做任何明智的事情,只是限制mtcars
为3行,所以我没有得到太多的输出,然后在 for
循环中创建另一个,蹩脚的数据帧.
# My report
<%
mtcars1 <- mtcars[1:3,]
mtcars1$type <- c('red','blue','green')
t.levels <- unique(mtcars1$type)
for (ty in t.levels) {
p <- subset(mtcars1,type == ty)
x <- rep(p, 4)
short <- paste0(p$gear, p$mpg)
%>
### <%= short %> blah
<%=
hist(x$mpg, main = paste(short, "blah"))
%>
<% } %>
Run Code Online (Sandbox Code Playgroud)
这只是对@daroczig下面提出的解决方案的一点点修改.如果我们命名demo.brew
并从中调用它,它就可以工作 Pandoc.brew('demo.brew', output = tempfile(), convert = 'html')
.做一个愚蠢的例子.
(3)有没有一个如何在没有酿造的情况下做到这一点的例子?我很好奇.
回答(3)是的.这适用于调用变量而不是行号的for循环
varlist <- unique(df$variable)
for (var in varlist) {
try(knit2html(input= '/Users/path/template.Rmd',
output=paste0('/Users/path/template',var,'.html')))
Run Code Online (Sandbox Code Playgroud)
适用于1:nrow()的循环没有.
pander
基于我上面的评论的替代解决方案:
# My report
<%
cyl.levels <- unique(mtcars$cyl)
for (ncyl in cyl.levels) {
%>
### <%= ncyl %> cylinders
<%=
hist(mtcars$mpg[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders"))
hist(mtcars$wt[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders"))
%>
<% } %>
Run Code Online (Sandbox Code Playgroud)
要生成此文件(名为demo.brew
),请运行:
Pandoc.brew('demo.brew')
Run Code Online (Sandbox Code Playgroud)
或者获取 MS Word 文档:
Pandoc.brew('demo.brew', output = tempfile(), convert = 'docx')
Run Code Online (Sandbox Code Playgroud)
更新:我刚刚意识到您需要针对类别的单独文档。为此,我建议尝试一下我的另一个包,rapport
它专注于精确的统计报告模板。快速示例:
<!--head
meta:
title: Demo for @Jessi
author: daroczig
description: This is a demo
packages: ~
inputs:
- name: ncyl
class: integer
standalone: TRUE
required: TRUE
head-->
### <%= ncyl %> cylinders
<%=
hist(mtcars$mpg[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders"))
hist(mtcars$wt[mtcars$cyl == ncyl], main = paste(ncyl, "cylinders"))
%>
Run Code Online (Sandbox Code Playgroud)
所以上面的文档 ( demo.rapport
) 是一个rapport模板,它有一个用于元数据和输入的 YAML 标头(其作用类似于 R 函数中的参数/参数),然后正文可以包含 markdown 和语法为 的 Rbrew
代码pander
。现在您可以通过简单的调用轻松调用此报告模板,例如 4 个气缸:
> rapport('demo.rapport', ncyl = 4)
### _4_ cylinders


Run Code Online (Sandbox Code Playgroud)
要为所有气缸生成 MS Word 文件,请尝试以下操作:
for (ncyl in (2:4)*2) {
rapport.docx('/home/daroczig/projects/demo.rapport', ncyl = ncyl)
}
Run Code Online (Sandbox Code Playgroud)