是否可以通过编程方式在脚本本身内部找到R脚本的路径?
我之所以这样问是因为我有几个使用RGtk2
和加载.glade文件中的GUI的脚本。
在这些脚本中,我必须setwd("path/to/the/script")
在开头添加一条指令,否则将找不到.glade文件(位于同一目录中)。
很好,但是如果我将脚本移动到其他目录或另一台计算机,则必须更改路径。我知道,这没什么大不了的,但是拥有这样的东西会很好:
setwd(getScriptPath())
那么,是否存在类似的功能?
是否可以通过编程方式在脚本本身内部找到R脚本的路径?
我之所以这样问是因为我有几个使用RGtk2
和加载.glade文件中的GUI的脚本。
在这些脚本中,我必须setwd("path/to/the/script")
在开头添加一条指令,否则将找不到.glade文件(位于同一目录中)。
很好,但是如果我将脚本移动到其他目录或另一台计算机,则必须更改路径。我知道,这没什么大不了的,但是拥有这样的东西会很好:
setwd(getScriptPath())
那么,是否存在类似的功能?
here
软件包)提供的解决方案对我来说非常有效。
Answers:
采用 source("yourfile.R", chdir = T)
Error: '...' used in an incorrect context
,请您说明可能是什么问题?
这对我有用:
getSrcDirectory(function(x) {x})
这将在脚本中定义一个匿名函数(不执行任何操作),然后确定该函数的源目录,即脚本所在的目录。
仅适用于RStudio:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
这在运行文件或为文件提供源时起作用。
install.packages("rstudioapi")
呢?
利用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)
}
--file
不包含完整路径,因此返回的脚本目录为空:```daniel @ computer:〜/ data $ Rscript Script.R / usr / lib / R / bin / exec / R --slave --no-restore --file = Script.R```–
如果将代码包装在包中,则始终可以查询包目录的一部分。
这是RGtk2包中的示例:
> system.file("ui", "demo.ui", package="RGtk2")
[1] "C:/opt/R/library/RGtk2/ui/demo.ui"
>
您可以对inst/glade/
源代码中的目录执行相同操作,该目录将成为glade/
已安装软件包中的目录-并system.file()
在安装时为您计算路径,而与操作系统无关。
这个答案对我来说很好:
script.dir <- dirname(sys.frame(1)$ofile)
注意:必须提供脚本才能返回正确的路径
我在以下位置找到了它:https : //support.rstudio.com/hc/communities/public/questions/200895567-can-user-obtain-the-path-of-current-Project-s-directory-
但是我仍然不明白什么是sys.frame(1)$ ofile。我没有在R Documentation中找到任何有关此的信息。有人可以解释吗?
#' 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
}
这些解决方案中有很多已经使用了几年。尽管有些仍然可以使用,但是有充分的理由反对使用它们中的每一个(请参阅下面的链接源)。我有最好的解决方案(也来自源代码):使用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/
如何使用系统和外壳命令?对于Windows,我想当您在RStudio中打开脚本时,会将当前的shell目录设置为脚本的目录。您可能需要添加cd C:\或任何要搜索的驱动器(例如shell('dir C:\\ * file_name / s',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)
谢谢您的功能,尽管我必须对它进行如下调整(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
}
就我而言,我需要一种复制执行文件的方法来备份原始脚本及其输出。这在研究中相对重要。在命令行上运行脚本时,对我有用的是这里介绍的其他解决方案的混合,如下所示:
library(scriptName)
file_dir <- 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")))
scriptName::current_filename()
是唯一可以在没有Rstudio且没有提供要复制文件的Linux服务器上检索文件名的功能,因为此处的大多数解决方案都sys.frame(1)$ofile
需要您执行此操作。获得所需的文件名后,您只需找到当前的脚本目录,并通过fileSnapshot()$path
进行一些其他调整即可解决该问题gsub
。希望对您有所帮助。