Создание кратких сводок в верхней части отчета 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]
```

Ответ 1

Вот еще один подход, который использует 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

Простым решением является просто knit() документ дважды из новой сессии Rgui.

В первый раз встроенный R-код вызывает некоторые жалобы на переменные, которые не могут быть найдены, но куски будут оцениваться, а возвращаемые переменные будут оставлены в глобальной рабочей области. Во второй раз, встроенный R-код найдет эти переменные и заменит их значения без жалобы:

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

## RStudio users will need to explicitly set knit 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, потому что как описано здесь, он по умолчанию запускает knit() в отдельном процессе и среде. Это поведение по умолчанию направлено на то, чтобы не касаться чего-либо в глобальной среде, а это означает, что первый запуск не оставит требуемые переменные, лежащие где угодно, где их может найти второй прогон.

Ответ 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")
```

Ответ 4

Я работаю в knitr, и для меня работает следующая двухпроходная система. У меня есть два (невидимых) фрагмента кода, один сверху и один внизу. Тот, который находится внизу, сохраняет значения любых переменных, которые мне нужно включить в текст, прежде чем они будут фактически вычислены в файле (statedata.R). Верхний фрагмент устанавливает значения переменных в то, что выделяется, если они еще не определены, а затем (если он существует) он захватывает фактические значения из сохраненного файла.

script необходимо вязать дважды, поскольку значения будут доступны только после одного прохода. Обратите внимание, что второй фрагмент стирает сохраненный файл состояния в конце второго прохода, так что последующие изменения в script, которые влияют на сохраненные переменные, должны будут вычисляться заново (чтобы мы не случайно сообщали старые значения от более раннего запуска script).

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