Getting path of an R script

北慕城南 提交于 2019-12-11 12:42:28

问题


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?


回答1:


Use source("yourfile.R", chdir = T)




回答2:


This works for me:

getSrcDirectory(function(x) {x})

This defines an anonymous function (that does nothing) inside the script, and then determines the source directory of that function, which is the directory where the script is.




回答3:


For RStudio only:

setwd(dirname(rstudioapi::getActiveDocumentContext()$path))

This works when Running or Sourceing your file.




回答4:


Exploit the implicit "--file" argument of Rscript

When calling the script using "Rscript" (Rscript doc) the full path of the script is given as a system parameter. The following function exploits this to extract the script directory:

getScriptPath <- function(){
    cmd.args <- commandArgs()
    m <- regexpr("(?<=^--file=).+", cmd.args, perl=TRUE)
    script.dir <- dirname(regmatches(cmd.args, m))
    if(length(script.dir) == 0) stop("can't determine script dir: please call the script with Rscript")
    if(length(script.dir) > 1) stop("can't determine script dir: more than one '--file' argument detected")
    return(script.dir)
}



回答5:


If you wrap your code in a package, you can always query parts of the package directory.
Here is an example from the RGtk2 package:

> system.file("ui", "demo.ui", package="RGtk2")
[1] "C:/opt/R/library/RGtk2/ui/demo.ui"
> 

You can do the same with a directory inst/glade/ in your sources which will become a directory glade/ in the installed package -- and system.file() will compute the path for you when installed, irrespective of the OS.




回答6:


This answer works fine to me:

script.dir <- dirname(sys.frame(1)$ofile)

Note: script must be sourced in order to return correct path

I found it in: https://support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-

But I still don´t understand what is sys.frame(1)$ofile. I didn´t find anything about that in R Documentation. Someone can explain it?




回答7:


#' current script dir
#' @param
#' @return
#' @examples
#' works with source() or in RStudio Run selection
#' @export
z.csd <- function() {
    # http://stackoverflow.com/questions/1815606/rscript-determine-path-of-the-executing-script
    # must work with source()
    if (!is.null(res <- .thisfile_source())) res
    else if (!is.null(res <- .thisfile_rscript())) dirname(res)
    # http://stackoverflow.com/a/35842176/2292993  
    # RStudio only, can work without source()
    else dirname(rstudioapi::getActiveDocumentContext()$path)
}
# Helper functions
.thisfile_source <- function() {
    for (i in -(1:sys.nframe())) {
        if (identical(sys.function(i), base::source))
            return (normalizePath(sys.frame(i)$ofile))
    }

    NULL
}
.thisfile_rscript <- function() {
    cmdArgs <- commandArgs(trailingOnly = FALSE)
    cmdArgsTrailing <- commandArgs(trailingOnly = TRUE)
    cmdArgs <- cmdArgs[seq.int(from=1, length.out=length(cmdArgs) - length(cmdArgsTrailing))]
    res <- gsub("^(?:--file=(.*)|.*)$", "\\1", cmdArgs)

    # If multiple --file arguments are given, R uses the last one
    res <- tail(res[res != ""], 1)
    if (length(res) > 0)
        return (res)

    NULL
}



回答8:


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/




回答9:


How about using system and shell commands? With the windows one, I think when you open the script in RStudio it sets the current shell directory to the directory of the script. You might have to add cd C:\ e.g or whatever drive you want to search (e.g. shell('dir C:\\*file_name /s', intern = TRUE) - \\ to escape escape character). Will only work for uniquely named files unless you further specify subdirectories (for Linux I started searching from /). In any case, if you know how to find something in the shell, this provides a layout to find it within R and return the directory. Should work whether you are sourcing or running the script but I haven't fully explored the potential bugs.

#Get operating system
OS<-Sys.info()
win<-length(grep("Windows",OS))
lin<-length(grep("Linux",OS))

#Find path of data directory
#Linux Bash Commands
if(lin==1){
  file_path<-system("find / -name 'file_name'", intern = TRUE)
  data_directory<-gsub('/file_name',"",file_path)
}
#Windows Command Prompt Commands
if(win==1){
  file_path<-shell('dir file_name /s', intern = TRUE)
  file_path<-file_path[4]
  file_path<-gsub(" Directory of ","",file_path)
  filepath<-gsub("\\\\","/",file_path)
  data_directory<-file_path
}

#Change working directory to location of data and sources  
setwd(data_directory)



回答10:


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
}


来源:https://stackoverflow.com/questions/35112128/how-do-i-get-script-directory-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!