6

I have a script (call it Main.R) that has the following code to find itself when I run it:

frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files) 
main.dir <- dirname(dirname(frame_files[[length(frame_files)]]))

This is used to get the directory above its own directory, main.dir, which is used to call other scripts relative to this path.

I'm interested in running this script from a command line, for example

R CMD BATCH Main.R

or

Rscript Main.R

Unfortunately, the commands above do not work when I call the script from the command line.

Is there any code I could put in Main.R or a call option to R or Rscript that I can use instead?

More specifically, the solution would need to work in Windows.

J4y
  • 639
  • 6
  • 21
  • Does this help? http://stackoverflow.com/questions/750786/whats-the-best-way-to-use-r-scripts-on-the-command-line – Lee Nov 20 '12 at 16:58
  • To be fair, I'm not sure, but it doesn't look like it. I have to say, I'm not great at using the command line. I've edited my post to add that I'm using Windows, I don't know if it makes a difference in the answer. Reading some other posts, I get the impression #! doesn't work in Windows. – J4y Nov 20 '12 at 18:15

2 Answers2

8

Below is a solution that will give you the correct file directory path when the script is run either with source or with Rscript.

# this is wrapped in a tryCatch. The first expression works when source executes, the
# second expression works when R CMD does it.
full.fpath <- tryCatch(normalizePath(parent.frame(2)$ofile),  # works when using source
               error=function(e) # works when using R CMD
                     normalizePath(unlist(strsplit(commandArgs()[grep('^--file=', commandArgs())], '='))[2]))
dirname(full.fpath)

The key to this is the function normalizePath. Given a relative or abbreviated path name, normalizePath will return a valid path or raise an error. When running the script from Rscript, if you give normalizePath the base filename of the current script, it'll return the fullpath, regardless of what your current directory is. It even gets the path right when you supply a relative path to R CMD and there's a script with the same name in the current directory!

In the code above, I extract the filename from one of the strings returned by commandArgs. If you take a look at the output of commandArgs, you'll see that the filename is the 4th argument. The argument is recorded as '--file=yourscript.R', so in the final line above, I split the string on '=' and pull out the file name.

Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113
  • 1
    +1 - but run `Rscript` with extra options, like `--vanilla` and `--file=[...]` could end up anywhere. It would be wiser to use a `grep` like function to find it rather than use a hardcoded position like `4`. – flodel Nov 20 '12 at 23:52
  • Thanks for drawing attention to this. Left it out for the sake of brevity. – Matthew Plourde Nov 21 '12 at 04:39
  • @mplourde Thanks! I was not aware of `normalizePath`. I like that you got it all in there with `tryCatch`. – J4y Nov 21 '12 at 11:40
1

On idea is to give the path as an argument to your Main.R

I Suppose You call it with RScript.

Rscript Main.R 'path' 

in your Main.R you add the code to read the argument

args <- commandArgs(trailingOnly = TRUE)
mainpath <- as.character(args[1])  
agstudy
  • 119,832
  • 17
  • 199
  • 261