我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
当前回答
我的一切都在一个!(—2019年9月1日更新以处理RStudio控制台)
#' 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)
}
}
}
}
}
其他回答
Supressingfire回答的简化版本:
source_local <- function(fname){
argv <- commandArgs(trailingOnly = FALSE)
base_dir <- dirname(substring(argv[grep("--file=", argv)], 8))
source(paste(base_dir, fname, sep="/"))
}
如果而不是脚本,foo。R,知道它的路径位置,如果你可以改变你的代码,总是从一个公共根引用所有的源路径,那么这些可能会有很大的帮助:
https://github.com/r-lib/rprojroot或https://rprojroot.r-lib.org/ https://here.r-lib.org/
鉴于
/ app /深度/嵌套/ foo。R /应用程序/其他。R
这是可行的
#!/usr/bin/env Rscript
library(here)
source(here("other.R"))
参见https://rprojroot.r-lib.org/了解如何定义项目根。
#!/usr/bin/env Rscript
print("Hello")
# sad workaround but works :(
programDir <- dirname(sys.frame(1)$ofile)
source(paste(programDir,"other.R",sep='/'))
source(paste(programDir,"other-than-other.R",sep='/'))
我的一切都在一个!(—2019年9月1日更新以处理RStudio控制台)
#' 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)
}
}
}
}
}
这对我很有用
library(rstudioapi)
rstudioapi::getActiveDocumentContext()$path