68

I've seen similar questions on Stack Overflow but virtually no conclusive answers, and certainly no answer that worked for me.

What is the easiest way to access and use objects (regression fits, data frames, other objects) that are located in the global R environment in the Markdown (Rstudio) script.

I find it surprising that there is no easy solution to this, given the tendency of the RStudio team to make things comfortable and effective.

Thanks in advance.

Adam Robinsson
  • 1,651
  • 3
  • 17
  • 29

8 Answers8

78

For better or worse, this omission is intentional. Relying on objects created outside the document makes your document less reproducible--that is, if your document needs data in the global environment, you can't just give someone (or yourself in two years) the document and data files and let them recreate it themselves.

For this reason, and in order to perform the render in the background, RStudio actually creates a separate R session to render the document. That background R session cannot see any of the environments in the interactive R session you see in RStudio.

The best way around this problem is to take the code you used to create the contents of your global environment and move it inside your document (you can use echo = FALSE if you don't want it to show up in the document). This makes your document self-contained and reproducible.

If you can't do that, there are a few approaches you can take to use the data in the global environment directly:

  1. Instead of using the Knit HTML button, type rmarkdown::render("your_doc.Rmd") at the R console. This will knit in the current session instead of a background session. Alternatively:

  2. Save your global environment to an .Rdata file prior to rendering (use R's save function), and load it in your document.

Jonathan
  • 8,497
  • 41
  • 35
  • 6
    One can also use `knitr::knit("your_doc.Rmd")`. The R Studio "Knit HTML" button might be using either the rmarkdown or the knitr engine, depending on one's preference settings, and they can behave slightly differently in some cases – arvi1000 Dec 01 '15 at 23:08
  • 6
    but what if I don't want to rerun all the code everytime I"knit"? Because my datasets are large (several million rows, >200 variables) so rerunning the code will be really time consuming. Can markdown skip re-reunning some of the chunks? I haven't found such an argument, namely. – Adam Robinsson Dec 03 '15 at 21:38
  • 2
    thanks Adam. I have the some issues but find two methods will help. 1.add knitr::opts_chunk$set(cache =TRUE), to your rmarkdown file and run it. 2. run in r console cammand rmarkdown::render("your_file.Rmd"). – Loro Tashi Dec 14 '18 at 03:09
  • Use the option eval=FALSE within the chunk. You will have to save whatever will be needed when knitting, and load it to the R session running the rendering. – VictorZurkowski Feb 22 '21 at 20:25
  • @VictorZurkowski I'm in the same situation as Adam Robinsson. I have large data sets that are slow to re-create. They are also large in file size. So exporting several of these to disk JUST so I can avoid this problem is also prohibitive. I will try the cache =TRUE option. – Earlien May 26 '21 at 06:37
7

Well, in my case i found the following solution:

(1) Save your Global Environmental in a .Rdata file inside the same folder where you have your .Rmd file. (You just need click at disquet picture that is on "Global Environmental" panel)

(2) Write the following code in your script of Rmarkdown:

load(file = "filename.RData") #  it load the file that you saved before

and stop suffering.

Robin
  • 71
  • 1
  • 1
6

Going to RStudio´s 'Tools' and 'Global options' and visiting the 'R Markdown' tab, you can make a selection in 'Evaluate chunks in directory', there select the option 'Documents' and the R Markdown knitting engine will be accessing the global environment as plain R code does. Hope this helps those who search this info!

Patrik_P
  • 3,066
  • 3
  • 22
  • 39
2

You can load the script in the desired environment as follows:

```{r, include=FALSE}
source("your-script.R", local = knitr::knit_global())
# or sys.source("your-script.R", envir = knitr::knit_global())
```

Next in the R Markdown document, you can use objects created in these scripts (e.g., data objects or functions).

https://bookdown.org/yihui/rmarkdown-cookbook/source-script.html

BorisV
  • 71
  • 3
2

The thread is old but in case anyone's still looking for a solution (as I was):

You can pass an envir parameter to the render() (or knit() function) so that it can access objects from the environment it was called from.

rmarkdown::render(
      input = input_rmd,
      output_file = output_file,
      envir = parent.frame()
    )
divbyzero
  • 31
  • 4
  • That save my life! I feel every time I upgrade one package, I trigger an ISII (an _infinite sequence of incompatibility issues_)... – Denis Cousineau Dec 19 '22 at 22:59
1

I have the same problem myself. Some stuff is pretty time consuming to reproduce every time.

I think there could be another answer. What if you save your environment with the save.image() function to a different file than the standard .Rdata one. Then, bring it back with load().

To be sure you are using the same data, use the md5sum() from tools.

Cheers, Cord

Unheilig
  • 16,196
  • 193
  • 68
  • 98
Cordura21
  • 11
  • 1
1

I think I solved this problem by referring to the package explicitly in the code that is being knitted. Using the yarrr package, for example, I loaded the dataframe "pirates" using data(pirates). This worked fine at the console and within an Rstudio code chunk, but with knitr it failed following the pattern in the question above. If, however, I loaded the data into memory by creating an object using pirates <- yarrr::pirates, the document then knitted cleanly to HTML.

invertdna
  • 171
  • 6
0

One option that I have not yet seen is the use of parameters.

This chapter goes through a simple example of how to do this.

Adam Elder
  • 21
  • 4