Plot created outside of knit function somehow sneaks into knit_child
I have a problem where knitting a child document according to the recommendation under https://bookdown.org/yihui/rmarkdown-cookbook/child-document.html results in some weird behaviour. A plot which was printed in the global environment is inserted in the output of knitr.
This has happened in a more complex setup where I was rendering Rmarkdown files with Child-Documents. I have tried to create a minimal reproducible example as follows:
I have a main.Rmd with the following syntax:
```{r, results = "asis"}
print("I am main.")
res <- knitr::knit_child("child.Rmd")
cat(res, sep = '\n')
```
and I have a child.Rmd
```{r}
print("I am the child.")
```
I then run
plot(1:10)
knitr::knit("main.Rmd")
I get the following main.md as output:
```r
print("I am main.")
```
[1] "I am main."
```r
res <- knitr::knit_child("child.Rmd")
```
```
##
##
## processing file: test_knitr/child.Rmd
```
|
| | 0%
|
|.......................................................| 100%
label: unnamed-chunk-2
```r
cat(res, sep = '\n')
```

```r
print("I am the child.")
```
```
## [1] "I am the child."
```
The plot which was created outside of the knit-function is now inside the document. I could reproduce this problem for different R versions and different machines.
Thanks!
P.S.: I am happy to supplement additional infos etc. if you need it.
Session info:
R version 4.2.1 (2022-06-23 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19044)
Locale:
LC_COLLATE=German_Germany.utf8
LC_CTYPE=German_Germany.utf8
LC_MONETARY=German_Germany.utf8
LC_NUMERIC=C
LC_TIME=German_Germany.utf8
Package version:
evaluate_0.16 glue_1.6.2 graphics_4.2.1
grDevices_4.2.1 highr_0.9 knitr_1.40.1
magrittr_2.0.3 methods_4.2.1 stats_4.2.1
stringi_1.7.8 stringr_1.4.1 tools_4.2.1
utils_4.2.1 xfun_0.32 yaml_2.3.5
By filing an issue to this repo, I promise that
- [x] I have fully read the issue guide at https://yihui.org/issue/.
- [x] I have provided the necessary information about my issue.
- If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
- If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included
xfun::session_info('knitr'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version:remotes::install_github('yihui/knitr'). - If I have posted the same issue elsewhere, I have also mentioned it in this issue.
- [x] I have learned the Github Markdown syntax, and formatted my issue correctly.
I understand that my issue may be closed if I don't fulfill my promises.
This sounds weird. @cderv Are you able to reproduce the problem?
Hi,
yes I am able to reproduce. See Details below
Details
> plot(1:10)
> knitr::knit("test.Rmd")
processing file: test.Rmd
|............................................................................... | 50%
ordinary text without R code
|..............................................................................................................................................................| 100%
label: unnamed-chunk-1 (with options)
List of 1
$ results: chr "asis"
output file: test.md
[1] "test.md"
> xfun::file_string("test.md")
---
title: "Untitled"
output: html_document
---
```r
print("I am main.")
```
[1] "I am main."
```r
res <- knitr::knit_child("child.Rmd", quiet = TRUE)
cat(res, sep = '\n')
```

```r
print("I am the child.")
```
```
## [1] "I am the child."
```
Closing the graphic device before knitting fix the issue. So doing this fix it:
plot(1:10)
dev.off() # adding this fix the issue - no plot included as image
knitr::knit("test.Rmd")
Details
> plot(1:10)
> dev.off()
null device
1
> knitr::knit("test.Rmd")
processing file: test.Rmd
|............................................................................... | 50%
ordinary text without R code
|..............................................................................................................................................................| 100%
label: unnamed-chunk-1 (with options)
List of 1
$ results: chr "asis"
output file: test.md
[1] "test.md"
> xfun::file_string("test.md")
---
title: "Untitled"
output: html_document
---
```r
print("I am main.")
```
[1] "I am main."
```r
res <- knitr::knit_child("child.Rmd", quiet = TRUE)
cat(res, sep = '\n')
```
```r
print("I am the child.")
```
```
## [1] "I am the child."
```
it seems knitr will indeed use an existing open one right ? https://github.com/yihui/knitr/blob/907184f82489488ab8fd3619aa15b9822bf96067/R/block.R#L201-L208
It could be link to this. It is also happening only when using knit_child() is used, and image is included right before the knit_child content.
---
title: "Untitled"
output: html_document
---
```{r}
print("I am main.")
res <- knitr::knit_child("child.Rmd", quiet = TRUE)
res
```
will show us this in knitr
```r
res <- knitr::knit_child("child.Rmd", quiet = TRUE)
res
```

```
## [1] "\n\n```r\nprint(\"I am the child.\")\n```\n\n```\n## [1] \"I am the child.\"\n```"
```
So it does not seem to be inside res which is knit_child result. We should check what knitting_child can trigger.
Can't you reproduce ? Is this a windows issue ?
@cderv I didn't try to reproduce (just asking you for help instead).
I don't remember why I wanted to avoid opening a new device when an existing device is open (i.e., dev.list() is not NULL). Perhaps I should remove this condition.
@niklaswillrich Would it be much trouble for you to close the device after the plot (i.e., plot() then dev.off())?
If I call dev.off() after plot() the figure is not inserted anymore.
The main.md now looks like this:
```r
print("I am main.")
```
[1] "I am main."
```r
res <- knitr::knit_child("child.Rmd")
```
```
##
##
## processing file: test_knitr/child.Rmd
```
|
| | 0%
|
|.......................................................| 100%
label: unnamed-chunk-2
```r
cat(res, sep = '\n')
```
```r
print("I am the child.")
```
```
## [1] "I am the child."
```
I will force dev.off() before all the rendering of Rmarkdown in my original project as a workaround for now and wait for a possible bug fix.
Still happy to test stuff provide further information.
Thanks for the quick reply and help!
I didn't try to reproduce (just asking you for help instead).
@yihui Ok great no problem. I'll look closer to this - I want to understand. That is an unexpected behavior.
I will force dev.off() before all the rendering of Rmarkdown
@niklaswillrich is this happening with rmarkdown::render too ?
The example shared only used knitr to render the Rmd to md and not rmarkdown completely.
@cderv yes, this is happening with rmarkdown::render too.
If you replace knitr::knit("main.Rmd") with rmarkdown::render("main.Rmd") the plot is still shown inside the output.
Just as a clarification: dev.off() solves the problem for rmarkdown::render too.
I have finally figured out and fixed this weird problem. You can install the development version via
remotes::install_github('yihui/knitr')
Thanks!
This old thread has been automatically locked. If you think you have found something related to this, please open a new issue by following the issue guide (https://yihui.org/issue/), and link to this old issue if necessary.