我想以编程方式将工作目录设置为当前脚本的路径,但首先我需要获取当前脚本的路径。
所以我希望能够做到:
current_path = ...retrieve the path of current script ...
setwd(current_path)
到目前为止,我试过了:
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)
script.name 返回NULL
source("script.R", chdir = TRUE)
返回: 文件错误(文件名,“r”,编码=编码):无法打开 连接另外:警告消息:在文件中(文件名,“r”, encoding = encoding):无法打开文件'/script.R':没有这样的文件或 目录
dirname(parent.frame(2)$ofile)
返回:dirname中的错误(parent.frame(2)$ ofile):预期的字符向量参数 ...因为parent.frame为空
frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
PATH <- dirname(frame_files[[length(frame_files)]])
返回:空,因为frame_files是0
的列表
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))
}
}
返回:path.expand(路径)出错:无效的'path'参数
我也看到here,here,here和here的所有答案。 没有快乐。
使用RStudio 1.1.383
编辑:如果不需要外部库来实现这一点,那就太棒了。
答案 0 :(得分:37)
在RStudio中,您可以使用
获取当前在源窗格中显示的文件的路径rstudioapi::getSourceEditorContext()$path
如果您只想要目录,请使用
dirname(rstudioapi::getSourceEditorContext()$path)
如果您想要source(filename)
运行的文件的名称,那就更难了。您需要在堆栈中的某处查找变量srcfile
。多远取决于你如何写东西,但它大约是后退4步:例如,
fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi
应该在最后两行打印相同的内容。
答案 1 :(得分:9)
TLDR :here包可帮助您从项目的根文件夹构建路径,无论存储R脚本或Rmd文档的文件夹位于何处。
CRAN上仍然可以使用here包。开发版本已移至github.com/r-lib/here。下面引用的网站中提到的要点仍然有效。
你是这样的: 你的脚本中有setwd()吗?请停止这样做。 这使得您的脚本非常脆弱,只需一次就能完成硬连接。只要重命名或移动目录,它就会中断。或者你可能得到一台新电脑?或者也许其他人需要运行您的代码?[...]
经典问题演示:围绕构建路径和/或在具有子目录的项目中设置工作目录的尴尬。特别是如果你使用R Markdown和knitr,它会以很多人的默认行为“工作目录=这个文件所在的目录”来绊倒很多人。 [...]
安装here包:
install.packages("here")
library(here)
here()
here("construct","a","path")
here()
功能的文档:
在程序包加载期间从当前工作目录开始, 这里将向上遍历目录层次结构,直到找到它为止 满足以下至少一个条件的目录:
- 包含匹配[。] Rproj $的文件,其内容与^ Version:in匹配 第一行
- [......其他选项......]
- 包含目录.git
一旦建立,根目录在活动期间不会更改 R会话。 here()然后将参数附加到根目录。
答案 2 :(得分:2)
如果您通过命令行等运行Rscript
Rscript /path/to/script.R
下面的函数会将this_file
分配给/path/to/script
library(tidyverse)
get_this_file <- function(){
commandArgs() %>%
tibble::as.tibble() %>%
tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
dplyr::filter(key == "--file") %>%
dplyr::pull(value)
}
this_file <- get_this_file()
答案 3 :(得分:1)
2019年3月更新
基于Alexis Lucattini和user2554330的答案,使其可以在命令行和RStudio上使用。还解决了“ as_tibble”弃用消息
library(tidyverse)
getCurrentFileLocation <- function()
{
this_file <- commandArgs() %>%
tibble::enframe(name = NULL) %>%
tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
dplyr::filter(key == "--file") %>%
dplyr::pull(value)
if (length(this_file)==0)
{
this_file <- rstudioapi::getSourceEditorContext()$path
}
return(dirname(this_file))
}
答案 4 :(得分:1)
获取当前脚本路径的另一个选项是$fname = preg_replace('/\s+/', '_', $fname);
// output : document_(1).pdf you get this output...
// Or Removing All special characters and spaces from filename
$fname = preg_replace("/[^a-z0-9\_\-\.]/i", '', $fname);
// output : document_1.pdf you get this output...
,您不需要使用RStudio运行脚本。
答案 5 :(得分:1)
我遇到了所有这些麻烦,因为它们依赖于直到设置了工作目录后才使用的库(由于packrat的原因)(这就是为什么我需要获得开始的路径)。
因此,这是一种仅使用基数R的方法(已编辑,除了/路径外还处理Windows \字符)
## Solution for A_Loc1 and B_Loc1
## Convert all date columns to datetime, replace with NaN if error
df['A_Date1'] = pd.to_datetime(df['A_Date1'], errors ="coerce")
df['B_Date1'] = pd.to_datetime(df['B_Date1'], errors ="coerce")
# Add Result column
df.insert(loc=0, column="Result", value=np.nan)
# groupby Cust_ID and Site, then fill A_Date1 forward and back
df['A_Date1'] = df.groupby(['Cust_ID','Site'], sort=False)['A_Date1'].apply(lambda x: x.ffill().bfill())
# Perform comparison
df.loc[(((df["A_Date1"].notna()) & (df["B_Date1"].notna()))
& ((df["A_Date1"]) > (df["B_Date1"]))),
"Result"] = "Fail"
答案 6 :(得分:1)
以下内容可在三种情况下解决该问题:RStudio源代码按钮,RStudio R控制台(如果文件仍在“源”窗格中,则为source(...)
或通过Rscript
的OS控制台:
this_file = gsub("--file=", "", commandArgs()[grepl("--file", commandArgs())])
if (length(this_file) > 0){
wd <- paste(head(strsplit(this_file, '[/|\\]')[[1]], -1), collapse = .Platform$file.sep)
}else{
wd <- dirname(rstudioapi::getSourceEditorContext()$path)
}
print(wd)
答案 7 :(得分:1)
如果您是从Rstudio或使用Rscript命令从命令行运行的Rscript,则以下代码提供了正在运行的Rscript的目录:
if (rstudioapi::isAvailable()) {
if (require('rstudioapi') != TRUE) {
install.packages('rstudioapi')
}else{
library(rstudioapi) # load it
}
wdir <- dirname(getActiveDocumentContext()$path)
}else{
wdir <- getwd()
}
setwd(wdir)
答案 8 :(得分:1)
这是一个自定义函数,用于在R,RStudio或Rscript中获取文件的路径:
stub <- function() {}
thisPath <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
if (length(grep("^-f$", cmdArgs)) > 0) {
# R console option
normalizePath(dirname(cmdArgs[grep("^-f", cmdArgs) + 1]))[1]
} else if (length(grep("^--file=", cmdArgs)) > 0) {
# Rscript/R console option
scriptPath <- normalizePath(dirname(sub("^--file=", "", cmdArgs[grep("^--file=", cmdArgs)])))[1]
} else if (Sys.getenv("RSTUDIO") == "1") {
# RStudio
dirname(rstudioapi::getSourceEditorContext()$path)
} else if (is.null(attr(stub, "srcref")) == FALSE) {
# 'source'd via R console
dirname(normalizePath(attr(attr(stub, "srcref"), "srcfile")$filename))
} else {
stop("Cannot find file path")
}
}
https://gist.github.com/jasonsychau/ff6bc78a33bf3fd1c6bd4fa78bbf42e7
答案 9 :(得分:0)