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
  • 869
  • 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

2 Answers2

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
  • 103,096
  • 29
  • 209
  • 259
  • 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
  • 97,541
  • 25
  • 218
  • 286
  • No `print` and `{…}` necessary, making this *slightly* simpler: `(function() getSrcFilename(sys.call(sys.nframe())))()` – Konrad Rudolph May 13 '17 at 15:45
  • 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