4

In many (interpreted) programming languages, a variable is set when sourcing a file so that some code can determine the filename from where it is loaded. E.g. in ruby, the variable __FILE__ is set when loading a file.

Is there such a feature in R? Is there a way for R code to determine from where it is loaded?

Example:

main.R:

source("foo.R")

/home/bar/foo.R:

print(FULL_FILENAME)

What do I have to replace FULL_FILENAME with to make it print:

[1] "/home/bar/foo.R"

without hardcoding any filenames in the source?

lith
  • 929
  • 8
  • 23
  • In addition to the answer below, I found the following alternative approach: http://r.789695.n4.nabble.com/FILE-for-R-td919451.html – lith Dec 02 '12 at 13:05

3 Answers3

1

You can use a hack provided by Gabor a while back by putting this on top of your file :

this.file <- parent.frame(2)$ofile

If you want to extract the name of the directory, you can do :

this.dir <- dirname(this.file)

From my understanding of things, sourcing a file creates two parent environments. The outer one (two steps up) contains the information about the file from where the code is sourced.

Joris Meys
  • 106,551
  • 31
  • 221
  • 263
  • Thanks. I added normalizePath() to it to get the full filename. – lith Nov 30 '12 at 12:39
  • @lith normally that shouldn't be necessary, unless you want to use "/" on Windows. – Joris Meys Nov 30 '12 at 12:50
  • This will work when the script is run with `source`, but not when executed using `RScript`. See my answer here for the general solution: http://stackoverflow.com/questions/13477852/how-can-a-script-find-itself-in-r-running-from-the-command-line/13480153#13480153 – Matthew Plourde Nov 30 '12 at 14:28
1

Here's a more reliable way to do this that doesn't depend on the implementation of source:

(function() {
    print(getSrcFilename(sys.call(sys.nframe())))
})()
Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • No `print` and `{…}` necessary, making this *slightly* simpler: `(function() getSrcFilename(sys.call(sys.nframe())))()` – Konrad Rudolph May 13 '17 at 15:45
  • 1
    This does not work for me, I get: `> sys.nframe()` returns `0`, `> sys.call(sys.nframe())` returns `NULL` and `> getSrcFilename(sys.call(sys.nframe()))` returns `character(0)`. – understorey Jun 01 '22 at 08:18
0

The simplest solution that I've found uses rstudioapi::getSourceEditorContext() and sub()

  • Work for both .Rmd and .R file when working interactively.
  • Works when sourcing .R script files
  • Works when knitting .Rmd files
    current_file <-
      rstudioapi::getSourceEditorContext()$path %>% 
      sub(".*/", "", .)

The rstudioapi::getSourceEditorContext()$path returns the full path of the current file, while the sub(".*/", "", .) extracts everything after the last / from the full fle path, leaving only the name of the file.

Lewkrr
  • 414
  • 4
  • 13