如何为R中的每一行数据帧生成markdown文档

时间:2014-08-20 14:25:59

标签: r knitr

我想从数据帧的每一行生成带有子文档的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

我尝试使用@Yihui解决的同样很棒的方法来编程引用带有knitr-expand的文本:R knitr: Possible to programmatically modify chunk labels?

从该解决方案中,我们有两个.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))`

模板看起来像:

```{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"))
```

此解决方案为每个级别的柱面生成一个带有子文档(在标题级别2)的单个降价文档。但是,我正在尝试创建一个获取.csv的报表,然后创建并修改数据帧并为另一个数据帧的每一行生成内容。

我认为我坚持的是如何使用{{ncyl}}中的值以编程方式引用数据库的行。我希望能够使用{{ncyl}}的级别来对数据帧mtcars中的相关行进行处理(假设此示例中只有行==级别{{ncyl}})。< / p>

虽然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"))
```

这不起作用

```{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
```

给出错误

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

我认为我正在接近主要问题“我如何为数据帧的每一行创建一个降价文档?”编织扩展功能有问题。

有人可以帮助我理解: 1.如何解决主要问题 2.为什么{{gear}}在template.Rmd?

中不起作用

所以,我仍然不明白(2),但我认为@daroczig让我接近理解解决主要问题的一种方法。我认为这不是问题的独特之处,我认为有一种方法可以在没有brewpanderrapport的情况下解决问题。在任何情况下,我采用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"))
%>

<% } %>

这只是对@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'))) 

适用于1:nrow()的循环没有的地方。

1 个答案:

答案 0 :(得分:2)

使用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"))
%>

<% } %>

要酿造此文件(名为demo.brew),请运行:

Pandoc.brew('demo.brew')

或者例如MS Word文档:

Pandoc.brew('demo.brew', output = tempfile(), convert = 'docx')

更新:我刚刚意识到您需要单独的类别文档。为此,我建议我的另一个软件包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"))
%>

所以上面的文档(demo.rapport)是一个rapport模板,它有一个YAML标头用于元数据和输入(其作用类似于R函数中的参数/参数),然后正文可以包含使用brew的{​​{1}}语法中的markdown和R代码。现在,您可以通过简单的调用轻松调用此报告模板,例如4缸:

pander

要为所有柱面生成MS Word文件,请尝试以下操作:

> rapport('demo.rapport', ncyl = 4)

### _4_ cylinders

![](plots/rapport--home-daroczig-projects-demo.rapport-6-1.png)
![](plots/rapport--home-daroczig-projects-demo.rapport-6-2.png)