Determine path of the executing script

前端 未结 28 2395
再見小時候
再見小時候 2020-11-22 08:01

I have a script called foo.R that includes another script other.R, which is in the same directory:

#!/usr/bin/env Rscript
message(\         


        
相关标签:
28条回答
  • 2020-11-22 08:36

    I liked steamer25's solution as it seems the most robust for my purposes. However, when debugging in RStudio (in windows), the path would not get set properly. The reason being that if a breakpoint is set in RStudio, sourcing the file uses an alternate "debug source" command which sets the script path a little differently. Here is the final version which I am currently using which accounts for this alternate behavior within RStudio when debugging:

    # @return full path to this script
    get_script_path <- function() {
        cmdArgs = commandArgs(trailingOnly = FALSE)
        needle = "--file="
        match = grep(needle, cmdArgs)
        if (length(match) > 0) {
            # Rscript
            return(normalizePath(sub(needle, "", cmdArgs[match])))
        } else {
            ls_vars = ls(sys.frames()[[1]])
            if ("fileName" %in% ls_vars) {
                # Source'd via RStudio
                return(normalizePath(sys.frames()[[1]]$fileName)) 
            } else {
                # Source'd via R console
                return(normalizePath(sys.frames()[[1]]$ofile))
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:36

    I also had this problem, and none of the above solutions worked for me. Maybe with the source or things like that, but it was not clear enough.

    I found this, for me elegant, solution:

    paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE),"/")
    

    The important thing in that is the fileSnapshot() that gives you a lot of information about a file. It returns a list of 8 elements. When you pick path as the list element, the path is returned with \\ as separator, so the rest of the code is just to change that.

    I hope this helps.

    0 讨论(0)
  • 2020-11-22 08:37

    I tried almost everything from this question, Getting path of an R script, Get the path of current script, Find location of current .R file and R command for setting working directory to source file location in Rstudio, but at the end found myself manually browsing the CRAN table and found

    scriptName library

    which provides current_filename() function, which returns proper full path of the script when sourcing in RStudio and also when invoking via R or RScript executable.

    0 讨论(0)
  • 2020-11-22 08:37

    I work in an HPC cluster environment. I develop my code in a different location from where I do my production runs. During development, I'm usually calling R interactively from the command line (not using RStudio). There is lots of source("foo.R") going on.

    During production runs, I usually write a bash script that tries different parameters and runs each set of parameters in a separate directory. The bash script utilizes the workload manager (i.e. SLURM). In this environment, it is trivial to set an environmental variable. With this in mind, the below solution works best for me.

    other.R

    my_message <- function(){
    return("R is awkward")
    }
    

    foo.R

    srcpath = Sys.getenv("R_SRC")
    # Check if runnning w/o setting R_SRC - presumably done in directory of development, i.e. /path/to/R/code
    if(srcpath == ""){
        srcpath="./"
    }
    source(sprintf("%s/other.R", srcpath))
    string = my_message()
    print(string)
    

    If running this from the R interactive shell and within /path/to/R/code, simply do

    > source("foo.R")
    

    If running not from the interactive shell and not running from /path/to/R/code, set the environmental variable R_SRC first, then call Rscript

    $ export R_SRC=/path/to/R/code/
    $ Rscript /path/to/R/code/foo.R
    
    0 讨论(0)
  • 2020-11-22 08:41

    You can use the commandArgs function to get all the options that were passed by Rscript to the actual R interpreter and search them for --file=. If your script was launched from the path or if it was launched with a full path, the script.name below will start with a '/'. Otherwise, it must be relative to the cwd and you can concat the two paths to get the full path.

    Edit: it sounds like you'd only need the script.name above and to strip off the final component of the path. I've removed the unneeded cwd() sample and cleaned up the main script and posted my other.R. Just save off this script and the other.R script into the same directory, chmod +x them, and run the main script.

    main.R:

    #!/usr/bin/env Rscript
    initial.options <- commandArgs(trailingOnly = FALSE)
    file.arg.name <- "--file="
    script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
    script.basename <- dirname(script.name)
    other.name <- file.path(script.basename, "other.R")
    print(paste("Sourcing",other.name,"from",script.name))
    source(other.name)
    

    other.R:

    print("hello")
    

    output:

    burner@firefighter:~$ main.R
    [1] "Sourcing /home/burner/bin/other.R from /home/burner/bin/main.R"
    [1] "hello"
    burner@firefighter:~$ bin/main.R
    [1] "Sourcing bin/other.R from bin/main.R"
    [1] "hello"
    burner@firefighter:~$ cd bin
    burner@firefighter:~/bin$ main.R
    [1] "Sourcing ./other.R from ./main.R"
    [1] "hello"
    

    This is what I believe dehmann is looking for.

    0 讨论(0)
  • 2020-11-22 08:41

    I have wrapped up and extended the answers to this question into a new function thisfile() in rprojroot. Also works for knitting with knitr.

    0 讨论(0)
提交回复
热议问题