Getting path of an R script

Viewed 57092

Is there a way to programmatically find the path of an R script inside the script itself?

I am asking this because I have several scripts that use RGtk2 and load a GUI from a .glade file.

In these scripts I am obliged to put a setwd("path/to/the/script") instruction at the beginning, otherwise the .glade file (which is in the same directory) will not be found.

This is fine, but if I move the script in a different directory or to another computer I have to change the path. I know, it's not a big deal, but it would be nice to have something like:

setwd(getScriptPath())

So, does a similar function exist?

14 Answers

A lot of these solutions are several years old. While some may still work, there are good reasons against utilizing each of them (see linked source below). I have the best solution (also from source): use the here library.

Original example code:

library(ggplot2)
setwd("/Users/jenny/cuddly_broccoli/verbose_funicular/foofy/data")
df <- read.delim("raw_foofy_data.csv")

Revised code

library(ggplot2)
library(here)

df <- read.delim(here("data", "raw_foofy_data.csv"))

This solution is the most dynamic and robust because it works regardless of whether you are using the command line, RStudio, calling from an R script, etc. It is also extremely simple to use and is succinct.

Source: https://www.tidyverse.org/articles/2017/12/workflow-vs-script/

I have found something that works for me. setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

None of the solutions given so far work in all circumstances. Worse, many solutions use setwd, and thus break code that expects the working directory to be, well, the working directory — i.e. the code that the user of the code chose (I realise that the question asks about setwd() but this doesn’t change the fact that this is generally a bad idea).

R simply has no built-in way to determine the path of the currently running piece of code.

A clean solution requires a systematic way of managing non-package code. That’s what ‘box’ does. With ‘box’, the directory relative to the currently executing code can be found trivially:

box::file()

However, that isn’t the purpose of ‘box’; it’s just a side-effect of what it actually does: it implements a proper, modern module system for R. This includes organising code in (nested) modules, and hence the ability to load code from modules relative to the currently running code.

To load code with ‘box’ you wouldn’t use e.g. source(file.path(box::file(), 'foo.r')). Instead, you’d use

box::use(./foo)

However, box::file() is still useful for locating data (i.e. OP’s use-case). So, for instance, to locate a file mygui.glade from the current module’s path, you would write.

glade_path = box::file('mygui.glade')

And (as long as you’re using ‘box’ modules) this always works, doesn’t require any hacks, and doesn’t use setwd.

Thank you for the function, though I had to adjust it a Little as following for me (W10):

#Windows Command Prompt Commands
if(win==1){
  file_path<-shell('dir file_name', intern = TRUE)
  file_path<-file_path[4]
  file_path<-gsub(" Verzeichnis von ","",file_path)
  file_path<-chartr("\\","/",file_path)
  data_directory<-file_path
}

In my case, I needed a way to copy the executing file to back up the original script together with its outputs. This is relatively important in research. What worked for me while running my script on the command line, was a mixure of other solutions presented here, that looks like this:

library(scriptName)
file_dir <- gsub("\\", "/", fileSnapshot()$path, fixed=TRUE)
file.copy(from = file.path(file_dir, scriptName::current_filename()) ,
          to = file.path(new_dir, scriptName::current_filename()))

Alternatively, one can add to the file name the date and our to help in distinguishing that file from the source like this:

file.copy(from = file.path(current_dir, current_filename()) ,
          to = file.path(new_dir, subDir, paste0(current_filename(),"_", Sys.time(), ".R")))

I know this question is old at this point, but I'd like to answer because I made a package to handle this problem. It's called "this.path" and it's available on CRAN so it can be installed like any other package using: install.packages("this.path")

It should retrieve the executing script's filename when running R from RStudio, RGui, the command-line / / terminal (Rscript), and when using 'source'.

Related