[r] 실행 스크립트의 경로 결정

같은 디렉토리에있는 foo.R다른 스크립트를 포함 하는 스크립트 가 있습니다 other.R.

#!/usr/bin/env Rscript
message("Hello")
source("other.R")

그러나 현재 작업 디렉토리가 무엇이든 관계없이 R찾고 싶습니다 other.R.

즉, foo.R자체 경로를 알아야합니다. 어떻게해야합니까?



답변

여기 에 문제에 대한 간단한 해결책이 있습니다. 이 명령은

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

현재 스크립트 파일의 경로를 반환합니다. 스크립트가 저장된 후에 작동합니다.


답변

commandArgs함수를 사용하여 Rscript가 전달한 모든 옵션을 실제 R 인터프리터로 가져 와서 검색 할 수 --file=있습니다. 스크립트가 경로에서 시작되었거나 전체 경로로 시작된 경우 script.name아래는로 시작됩니다 '/'. 그렇지 않으면cwd 전체 경로를 얻기 위해 두 경로를 연결할 수 있습니다.

편집 :script.name 위 의 내용 만 필요 하고 경로의 최종 구성 요소를 제거 하는 것처럼 들립니다 . 불필요한 cwd()샘플을 제거하고 기본 스크립트를 정리 하고 내을 게시했습니다 other.R. 이 스크립트와 other.R스크립트를 동일한 디렉토리에 저장 chmod +x하고 기본 스크립트를 실행하십시오.

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")

출력 :

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"

이것이 내가 dehmann이 찾고 있다고 믿는 것입니다.


답변

R 콘솔에서 ‘소스’할 때 Suppressingfire의 솔루션을 작동시킬 수 없었습니다.
Rscript를 사용할 때 hadley의 솔루션을 사용할 수 없었습니다.

두 세계의 최고?

thisFile <- function() {
        cmdArgs <- commandArgs(trailingOnly = FALSE)
        needle <- "--file="
        match <- grep(needle, cmdArgs)
        if (length(match) > 0) {
                # Rscript
                return(normalizePath(sub(needle, "", cmdArgs[match])))
        } else {
                # 'source'd via R console
                return(normalizePath(sys.frames()[[1]]$ofile))
        }
}


답변

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

내가 잊어 버렸기 때문에 어떻게 작동하는지 묻지 마십시오.


답변

이것은 나를 위해 작동

library(rstudioapi)
rstudioapi::getActiveDocumentContext()$path


답변

라켄시 의 답R 스크립트의 경로얻는 부터 가장 정확하고 정말 훌륭한 IMHO입니다. 그러나 여전히 더미 기능을 통합 한 핵입니다. 다른 사람들이 쉽게 찾을 수 있도록 여기에 인용하고 있습니다.

sourceDir <-getSrcDirectory (함수 (더미) {더미})

이것은 명령문이 배치 된 파일의 디렉토리를 제공합니다 (더미 함수가 정의 된 위치). 그런 다음 작업 direcory를 설정하고 상대 경로를 사용하는 데 사용할 수 있습니다.

setwd(sourceDir)
source("other.R")

또는 절대 경로를 만들려면

 source(paste(sourceDir, "/other.R", sep=""))


답변

하나의 모든 것! (-RStudio 콘솔을 처리하도록 2019 년 1 월 1 일 업데이트 됨)

#' current script file (in full path)
#' @description current script file (in full path)
#' @examples
#' works with Rscript, source() or in RStudio Run selection, RStudio Console
#' @export
ez.csf <- function() {
    # http://stackoverflow.com/a/32016824/2292993
    cmdArgs = commandArgs(trailingOnly = FALSE)
    needle = "--file="
    match = grep(needle, cmdArgs)
    if (length(match) > 0) {
        # Rscript via command line
        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 {
            if (!is.null(sys.frames()[[1]]$ofile)) {
            # Source'd via R console
            return(normalizePath(sys.frames()[[1]]$ofile))
            } else {
                # RStudio Run Selection
                # http://stackoverflow.com/a/35842176/2292993
                pth = rstudioapi::getActiveDocumentContext()$path
                if (pth!='') {
                    return(normalizePath(pth))
                } else {
                    # RStudio Console
                    tryCatch({
                            pth = rstudioapi::getSourceEditorContext()$path
                            pth = normalizePath(pth)
                        }, error = function(e) {
                            # normalizePath('') issues warning/error
                            pth = ''
                        }
                    )
                    return(pth)
                }
            }
        }
    }
}