在knitr报告顶部创建使用稍后定义的变量的摘要

时间:2014-05-09 17:30:52

标签: r knitr r-markdown

在代码本身计算这些值之前,是否有一种标准方法可以在编写的knitr报告中尽早包含变量的计算值?目的是在报告的顶部创建一个执行摘要。

例如,像这样的东西,其中variable1和variable2直到稍后才定义:

---
title: "Untitled"
output: html_document
---

# Summary
The values from the analysis are `r variable1` and `r variable2`

## Section 1

In this section we compute some values. We find that the value of variable 1 is `r variable1`

```{r first code block}
variable1 <- cars[4, 2]
```

## Section 2

In this section we compute some more values. In this section we compute some values. We find that the value of       variable 2 is `r variable2`

```{r second code block}
variable2 <- cars[5, 2]
```

5 个答案:

答案 0 :(得分:6)

一个简单的解决方案是在新的Rgui会话中简单地knit()文档两次。

第一次,内联R代码会触发一些关于无法找到的变量的投诉,但将被评估,它们返回的变量将留在全球工作空间。第二次,内联R代码将找到这些变量,并在没有投诉的情况下替换它们的值:

knit("eg.Rmd")
knit2html("eg.Rmd")

## RStudio users will need to explicitly set knit's environment, like so:    
# knit("eg.Rmd", envir=.GlobalEnv)
# knit2html("eg.Rmd", envir=.GlobalEnv)

enter image description here


注1:在此答案的早期版本中,我建议您执行knit(purl("eg.Rmd")); knit2html("eg.Rmd")。这具有(次要的)优点,即第一次不运行内联R代码,但具有错过 knitr 缓存功能的(可能是主要的)缺点。

注意2(对于Rstudio用户): RStudio需要显式envir=.GlobalEnv,因为as documented here默认情况下在单独的进程和环境中运行knit() 。它的默认行为旨在避免触摸全局环境中的任何内容,这意味着第一次运行不会让所需的变量位于第二次运行可以找到它们的任何地方。

答案 1 :(得分:4)

这是另一种使用brew + knit的方法。我们的想法是让knitr首先传递文档,然后通过brew运行它。您可以通过引入brew步骤作为文档挂钩来自动执行此工作流程,该挂钩在knitr完成其魔术之后运行。请注意,您必须使用brew标记<%= variable %>来打印值。

---
title: "Untitled"
output: html_document
---

# Summary

The values from the analysis are <%= variable1 %> and 
<%= variable2 %>

## Section 1

In this section we compute some values. We find that the value of variable 1 
is <%= variable1 %>


```{r first code block}
variable1 = cars[6, 2]
```


## Section 2

In this section we compute some more values. In this section we compute 
some values. We find that the value of  variable 2 is <%= variable2 %>

```{r second code block}
variable2 = cars[5, 2]
```

```{r cache = F}
require(knitr)
knit_hooks$set(document = function(x){
  x1 = paste(x, collapse = '\n')
  paste(capture.output(brew::brew(text = x1)), collapse = '\n')
})
```

答案 2 :(得分:3)

使用ref.label chunk选项变得非常简单。见下文:

--- 
title: Report
output: html_document
---

```{r}
library(pixiedust)
options(pixiedust_print_method = "html")
```

### Executive Summary 

```{r exec-summary, echo = FALSE, ref.label = c("model", "table")}
```

Now I can make reference to `fit` here, even though it isn't yet defined in the script. For example, a can get the slope for the `qsec` variable by calling `round(coef(fit)[2], 2)`, which yields 0.93.

Next, I want to show the full table of results. This is stored in the `fittab` object created in the `"table"` chunk.

```{r, echo = FALSE}
fittab
```

### Results

Then I need a chunk named `"model"` in which I define a model of some kind.

```{r model}
fit <- lm(mpg ~ qsec + wt, data = mtcars)
```

And lastly, I create the `"table"` chunk to generate `fittab`.

```{r table}
fittab <- 
  dust(fit) %>%
  medley_model() %>% 
  medley_bw() %>% 
  sprinkle(pad = 4,
           bg_pattern_by = "rows")
```

答案 3 :(得分:1)

我在knitr工作,以下两遍系统适合我。我有两个(不可见的)代码块,一个在顶部,一个在底部。底部的那个保存了我在文本中实际计算它们之前需要包含的任何变量的值(statedata.R)。顶部块将变量值设置为尚未定义的突出显示,然后(如果存在)它从存储文件中获取实际值。

脚本需要编织两次,因为值只能在一次通过后才可用。请注意,第二个块会在第二次传递结束时删除已保存的状态文件,因此必须重新计算影响已保存变量的脚本的任何后续更改(以便我们不会意外地报告旧值从早期的剧本运行。)

---
title: "Untitled"
output: html_document
---
```{r, echo=FALSE, results='hide'}
# grab saved computed values from earlier passes
if (!exists("variable1")) {
        variable1 <- "UNDEFINED"
        variable2 <- "UNDEFINED"
        if (file.exists("statedata.R")) {
                source("statedata.R")
        }
}

# Summary
The values from the analysis are `r variable1` and `r variable2`

## Section 1

In this section we compute some values. We find that the value of variable 1 is `r variable1`

```{r first code block}
variable1 <- cars[4, 2]
```

## Section 2

In this section we compute some more values. In this section we compute some values. We find that the value of       variable 2 is `r variable2`

```{r second code block}
variable2 <- cars[5, 2]
```
```{r save variables for summary,echo=FALSE,results='hide'}
if (!file.exists("statedata.R")) {
        dump(c("variable1","variable2"), file="statedata.R")
        } else {
        file.remove("statedata.R")
}
```

答案 4 :(得分:0)

Latex宏可以解决此问题。参见this answer to my related question

\newcommand\body{

\section{Analysis}

<<>>= 
x <- 2
@

Some text here

}  % Finishes body

\section*{Executive Summary}

<<>>=
x
@

\body