8

This is a follow up for clarification of a previous question, How can I ensure a consistent R environment among different users on the same server?

I'd like to enter a "vanilla" R session from within R, e.g. similar to what I would obtain if I launched R using the command R --vanilla. For example, I would like to write a script that is not confounded by a particular user's custom settings.

In particular, I'd like the following

  • doesn't read R history, profile, or environment files
  • doesn't reload data or objects from previous sessions

help("vanilla") does not return anything, and I am not familiar enough with the scope of custom settings to know how to get out of all of them.

Is there a way to enter new, vanilla environment? (?new.env does not seem to help)

Community
  • 1
  • 1
David LeBauer
  • 31,011
  • 31
  • 115
  • 189
  • Can you clarify your intended use case here? I can't tell from your question whether the scripts in question would be run from within an existing R session or directly from the command line. – joran Sep 22 '12 at 02:20
  • [This link](http://stackoverflow.com/a/12323852/967840) might be related – GSee Sep 22 '12 at 02:26
  • @joran I would like for the scripts in question to ensure a standard environment that I can control in the script, independent of if the script is run from the command line or called using `source` in an existing R session; either way I can not ensure that it will be run in a vanilla environment. – David LeBauer Sep 22 '12 at 02:29
  • Note that the [callr package](https://cran.r-project.org/package=callr) will let you start a new R process within your current session. It has a function `r_vanilla()`. – jena May 23 '22 at 12:51

2 Answers2

6

IMHO, reproducible research and interactive sessions don't go well together. You should consider writing executable scripts called from the command line, not from an opened interactive session. At the top of the script, add --vanilla to the shebang:

#!/path/to/Rscript --vanilla

If your script needs to read inputs (arguments or options), you can use ?commandArgs or one of the two packages getopt or optparse for parsing them from the command line.

If the user really needs to do his own work in an interactive session, then he can still do so and call your script via system(): your script will still use its own vanilla session. There's just a little extra work around passing inputs and outputs.

flodel
  • 87,577
  • 21
  • 185
  • 223
  • +1 -- I like that approach much better than what David is trying to do here. – Dirk Eddelbuettel Sep 22 '12 at 13:03
  • I agree the requirement the OP gave in the comments that it shouldn't matter whether the script is run with `Rscript` or via `source` makes things awkward. What if you need to make sure an environment variable was set when R was started. e.g. if you need to make sure `TMPDIR` is set, and you cannot control the `.Renviron` of the user? Can that be done in the shebang, or does it have to be set at command line like `TMPDIR="~/tmp" Rscipt --vanilla` ? – GSee Sep 22 '12 at 13:20
  • Can't speak to Rscript but littler can be told to replicate R's behaviour yet do it in non-interactive mode. – Dirk Eddelbuettel Sep 22 '12 at 13:32
  • 1
    @Gsee, `--vanilla` is an alias for `--no-save --no-restore --no-site-file --no-init-file --no-environ`. You could take `--no-site-file` out as to allow the sourcing of your `Rprofile.site` file at startup. In that file, you can set `TMPDIR` with `Sys.setenv()`. You could also just have the script itself set that variable. – flodel Sep 22 '12 at 13:38
  • @flodel, actually, you cannot change TMPDIR using `Sys.setenv`, it has to be done when starting R as in my comment above. `R --vanilla -q -e 'Sys.setenv(TMPDIR="/home/garrett/tmp"); tempdir()'` gives me "/tmp/RtmpHTXbPp", but `TMPDIR="/home/garrett/tmp" R --vanilla -q -e 'tempdir()'` gives "/home/garrett/tmp/RtmpzgNXPC" – GSee Sep 22 '12 at 13:53
  • @Gsee, thanks, you are right. You could remove `--environ` but it will read both user and site environment files, so probably still dangerous for a multi-user reproducible research. The `?Startup` does mention a `R_HOME/etc/Renviron` that is distinct from the user and site environment files. I tested it and it works, so I guess you could also use that at a site-level. Otherwise, your way, which could also be wrapped in a shell script maybe. – flodel Sep 22 '12 at 14:31
  • Regarding "reproducible research and interactive sessions don't go well together": the goal is to allow each user customize their own analysis, but I generally like your solution, and it could work if all changes were made to a configuration file (e.g. xml) with the variable parameters for each run. – David LeBauer Sep 24 '12 at 13:58
  • +1 for the thought-provoking: "IMHO, reproducible research and interactive sessions don't go well together" – Mark White Mar 29 '18 at 18:04
  • Hard-coding the path to Rscript is a *really bad idea.* – Konrad Rudolph Aug 08 '20 at 09:53
5

You can't just make your current session vanilla, but you can start a fresh vanilla R session from within R like this

> .Last <- function() system("R --vanilla")
> q("no")

I think you'll probably run into a problem using the above as is because after R restarts, the rest of your script will not execute. With the following code, R will run .Last before it quits.  .Last will tell it to restart without reading the site file or environment file, and without printing startup messages. Upon restarting, it will run your code (as well as doing some other cleanup).

wd <- getwd()
setwd(tempdir())
assign(".First", function() {
  #require("yourPackage") 
  file.remove(".RData") # already been loaded
  rm(".Last", pos=.GlobalEnv) #otherwise, won't be able to quit R without it restarting
  setwd(wd)
  ## Add your code here
  message("my code is running.\n")
}, pos=.GlobalEnv)

assign(".Last", function() {
  system("R --no-site-file --no-environ --quiet")
}, pos=.GlobalEnv)
save.image() # so we can load it back when R restarts
q("no") 
GSee
  • 48,880
  • 13
  • 125
  • 145
  • You may need to put your code in a function called `.First` and save `.First` in an `.RData` file in the working directory. Otherwise, it might not run code that comes after the restart. (You'd also need to remove `.Last` inside the `.First` function so that you would be able to quit R later without it restarting.) See [the link](http://stackoverflow.com/a/12323852/967840) I gave in a comment on your Q – GSee Sep 22 '12 at 02:41
  • As I mentioned above, the [callr package](https://cran.r-project.org/package=callr) will let you start a new R process within your current session. It has a function `r_vanilla()`. – jena May 23 '22 at 12:52