有没有办法以编程方式在脚本本身内找到R脚本的路径?
我问这个是因为我有几个脚本使用RGtk2
并从.glade文件加载GUI。
在这些脚本中,我不得不在开头添加setwd("path/to/the/script")
指令,否则将找不到.glade文件(位于同一目录中)。
这很好,但如果我将脚本移动到另一个目录或另一台计算机,我必须更改路径。我知道,这不是什么大不了的事,但有一些东西会很好:
setwd(getScriptPath())
那么,是否存在类似的功能?
答案 0 :(得分:36)
这对我有用:
getSrcDirectory(function(x) {x})
这在脚本中定义了一个匿名函数(什么都不做),然后确定该函数的源目录,即脚本所在的目录。
答案 1 :(得分:26)
仅适用于RStudio:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
这适用于运行 ning或源您的文件。
答案 2 :(得分:24)
使用source("yourfile.R", chdir = T)
答案 3 :(得分:6)
利用Rscript
的隐式“--file”参数使用“Rscript”(Rscript doc)调用脚本时,脚本的完整路径将作为系统参数给出。以下函数利用此功能提取脚本目录:
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)
}
答案 4 :(得分:4)
如果将代码包装在包中,则始终可以查询包目录的各个部分 以下是RGtk2包中的一个示例:
> system.file("ui", "demo.ui", package="RGtk2")
[1] "C:/opt/R/library/RGtk2/ui/demo.ui"
>
您可以对源中的目录inst/glade/
执行相同操作,该目录将成为已安装软件包中的目录glade/
- system.file()
将在安装时为您计算路径,与操作系统无关。
答案 5 :(得分:3)
这个答案对我很好:
script.dir <- dirname(sys.frame(1)$ofile)
注意:必须提供脚本才能返回正确的路径
中找到了它但我还是不明白什么是sys.frame(1)$ ofile。我在R文档中没有找到任何相关内容。有人可以解释一下吗?
答案 6 :(得分:1)
#' 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
}
答案 7 :(得分:1)
这些解决方案中有很多已经使用了几年。尽管有些仍然可以使用,但是有充分的理由反对使用它们中的每一个(请参阅下面的链接源)。我有最好的解决方案(也来自源代码):使用here
库。
原始示例代码:
library(ggplot2)
setwd("/Users/jenny/cuddly_broccoli/verbose_funicular/foofy/data")
df <- read.delim("raw_foofy_data.csv")
修改后的代码
library(ggplot2)
library(here)
df <- read.delim(here("data", "raw_foofy_data.csv"))
此解决方案是最动态,最强大的解决方案,因为它不管您是否使用命令行,RStudio,从R脚本进行调用等,都可以使用。它使用起来也非常简单且简洁。
来源:https://www.tidyverse.org/articles/2017/12/workflow-vs-script/
答案 8 :(得分:0)
如何使用system和shell命令?使用windows one,我认为当你在RStudio中打开脚本时,它会将当前的shell目录设置为脚本目录。您可能必须添加cd C:\ eg或您要搜索的任何驱动器(例如shell(&#39; dir C:\\ * file_name / s&#39;,intern = TRUE) - \\以转义转义字符) 。除非您进一步指定子目录(对于我从/开始搜索的Linux),否则仅适用于唯一命名的文件。在任何情况下,如果你知道如何在shell中找到一些东西,这提供了一个布局,可以在R中找到它并返回目录。无论您是采购还是运行脚本,都应该工作,但我还没有充分发现潜在的错误。
#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)
答案 9 :(得分:0)
感谢您使用此功能,尽管我必须对它进行如下调整(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
}
答案 10 :(得分:0)
就我而言,我需要一种复制执行文件的方法来备份原始脚本及其输出。这在研究中相对重要。在命令行上运行脚本时,对我有用的是这里介绍的其他解决方案的组合,如下所示:
library(scriptName)
file_dir <- paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE))
file.copy(from = file.path(file_dir, scriptName::current_filename()) ,
to = file.path(new_dir, scriptName::current_filename()))
或者,可以将日期和日期添加到文件名中,以帮助将文件与源文件区分开来,如下所示:
file.copy(from = file.path(current_dir, current_filename()) ,
to = file.path(new_dir, subDir, paste0(current_filename(),"_", Sys.time(), ".R")))
答案 11 :(得分:0)
我知道这个问题现在已经很老了,但是我想回答,因为我制作了一个软件包来处理这个问题。它称为“ this.path”,可在CRAN上使用,因此可以像使用以下任何其他软件包一样安装: install.packages(“ this.path”)
从RStudio,RGui,命令行//终端(Rscript)运行R以及使用“源”时,它应该检索执行脚本的文件名。