11

When I use knitr to build an HTML document out of the following code:

Chunk Output
========================================================

Outside a chunk.

```{r chunk1, results='asis'}

cat('Inside a chunk\n\n')

for (i in 1:3) {
    cat('* Inside loop #', i, '\n')
}

cat('Outside a loop, but still inside the first chunk')
```

Between chunks.

```{r chunk2, results='asis'}

cat('Inside second chunk')

```

I get output where the code in chunk1 is interleaved with the output of the cat statements. Interestingly, the output within the for loop is output as a single block.

I would prefer to have all of the code from chunk1 to appear first, followed by all of the output from chunk1. Is there a way to ask Rmarkdown/knitr to avoid the more granular interweaving that it's currently doing?

Harlan
  • 18,883
  • 8
  • 47
  • 56
  • Not quite getting what you want but you could make 2 code chunks that are identical, one where you `eval = FALSE` and the second where you `echo = FALSE`. – Tyler Rinker Aug 29 '13 at 18:17
  • I could do that. Or I can wrap the contents of the chunks in `for (x in 1)`, which keeps Rmarkdown from interleaving the output (at the cost of superfluous code in my doc). But I'd prefer to have an option to do this the right way. Anyone know if it's possible? – Harlan Aug 29 '13 at 18:22
  • 1
    @Harlan I don't think this is easy because of the way knitr processes these blocks. A minimal hack would be to put the block inside `{}` – hadley Aug 29 '13 at 18:48
  • @Hadley, that works, although it's obviously not ideal. If you write that as an answer, I'll call it the solution. :) – Harlan Aug 29 '13 at 19:33
  • 2
    Here is [another solution](https://gist.github.com/ramnathv/58233ee63a581847411c), where you use `results = 'hide'` to suppress output and add a dependent chunk with `echo = F, results = "asis"`. You might submit a feature request for an option called `results = "hold"` just like `fig.show = "hold"` which would do this automatically for results, since there seem to be some use cases for this. – Ramnath Aug 29 '13 at 20:35
  • @Ramnath, yes, that works! And doesn't require the extra characters in the code block. I'll submit a feature request to knitr... Thanks! (And please copy this to an answer to collect your reputation points! :) ) – Harlan Aug 29 '13 at 20:52
  • 4
    Feature request heard, and code done. – Yihui Xie Aug 29 '13 at 21:31
  • 1
    This is customer service at its very best @Yihui! – Ramnath Aug 29 '13 at 22:36

1 Answers1

14

Here is the solution I proposed

Chunk Output
========================================================

Outside a chunk.

```{r chunk1, results='hide'}

cat('Inside a chunk\n\n')

for (i in 1:3) {
    cat('* Inside loop #', i, '\n')
}

cat('Outside a loop, but still inside the first chunk')
```

```{r ref.label = 'chunk1', results = 'asis', echo = F}

```

In the latest version of knitr, @yihui has added a new chunk option results = "hold", which automatically holds printing of all output to the end. Accordingly, we can just write

Chunk Output
========================================================

Outside a chunk.

```{r chunk1, results='hold'}

cat('Inside a chunk\n\n')

for (i in 1:3) {
    cat('* Inside loop #', i, '\n')
}

cat('Outside a loop, but still inside the first chunk')
```
Ramnath
  • 54,439
  • 16
  • 125
  • 152