获取当前脚本的路径

Pan*_*al. 25 r rstudio

我想以编程方式将工作目录设置为当前脚本的路径,但首先我需要获取当前脚本的路径.

所以我希望能够做到:

current_path = ...retrieve the path of current script ...
setwd(current_path) 
Run Code Online (Sandbox Code Playgroud)

就像RStudio菜单一样: RStudio设置工作目录

到目前为止我试过:

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)
Run Code Online (Sandbox Code Playgroud)

script.name 返回NULL

source("script.R", chdir = TRUE)
Run Code Online (Sandbox Code Playgroud)

返回:文件中的错误(文件名,"r",编码=编码):无法打开连接另外:警告消息:在文件中(文件名,"r",编码=编码):无法打开文件'/script.R' : 没有相应的文件和目录

dirname(parent.frame(2)$ofile)
Run Code Online (Sandbox Code Playgroud)

返回:dirname中的错误(parent.frame(2)$ ofile):期望的字符向量参数 ...因为parent.frame为null

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

返回:Null,因为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))
    }
}
Run Code Online (Sandbox Code Playgroud)

返回:path.expand(path)中的错误:无效的'path'参数

我也看到了这里,这里,这里这里的所有答案.没有快乐.

与...合作 RStudio 1.1.383

编辑:如果不需要外部库来实现这一点,那就太好了.

use*_*330 48

在RStudio中,您可以使用获取当前在源窗格中显示的文件的路径

rstudioapi::getSourceEditorContext()$path
Run Code Online (Sandbox Code Playgroud)

如果您只想要该目录,请使用

dirname(rstudioapi::getSourceEditorContext()$path)
Run Code Online (Sandbox Code Playgroud)

如果你想要运行的文件的名称source(filename),那就更难了.您需要srcfile在堆栈中的某个位置查找变量.多远取决于你如何写东西,但它大约退回4步:例如,

fi <- tempfile()
writeLines("f()", fi)
f <- function() print(sys.frame(-4)$srcfile)
source(fi)
fi
Run Code Online (Sandbox Code Playgroud)

应该在最后两行打印相同的东西.

  • 这不会像“Rscript test.R”那样在终端中运行 (2认同)

小智 16

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))
}
Run Code Online (Sandbox Code Playgroud)

  • 这实际上有效,并且应该成为所有相关问题中公认的答案。 (2认同)

Pau*_*eux 11

2018年8月更新

TLDR:这里的包可以帮助你从项目的根文件夹构建一个路径,无论文件夹的位置是什么,存储R脚本或Rmd文档.

这里包仍然可在CRAN.开发版本已移至github.com/r-lib/here.以下引用的网站中提到的要点仍然有效.

以前的答案

阅读这个颂歌:

你:你的脚本中有setwd()吗?请停止这样做.这使得您的脚本非常脆弱,只需一次就能完成硬连接.只要重命名或移动目录,它就会中断.或者你可能得到一台新电脑?或者也许其他人需要运行您的代码?

[...]

经典问题演示:围绕构建路径的尴尬和/或在具有子目录的项目中设置工作目录.特别是如果你使用R Markdown和knitr,它会以很多人的默认行为"工作目录=这个文件所在的目录"来绊倒很多人.[...]

安装包:

install.packages("here")
library(here)
here()
here("construct","a","path")
Run Code Online (Sandbox Code Playgroud)

here()功能文档:

在程序包加载期间从当前工作目录开始,此处将向上遍历目录层次结构,直到找到满足以下至少一个条件的目录:

  • 包含匹配[.] Rproj $的文件,其内容与第一行中的^ Version:匹配
  • [......其他选择......]
  • 包含目录.git

一旦建立,根目录在活动R会话期间不会更改.here()然后将参数附加到根目录.

这个的开发版本可以在github上找到.

  • @PaulRougieux 这与加载数据无关。这是关于导入其他 R 文件。例如必须使用source()。与 python import 相比,它非常糟糕,因为您必须使用非常糟糕的技巧来确保正确可靠的导入。当您必须编写可用于生产的代码并因此具有一定程度的控制权时,这一点非常重要。 (3认同)
  • 仅当您在同一项目树中“source”或“Rscript”文件时,这才有效。例如,如果您正在调用位于其他地方的实用程序脚本,则这不起作用。 (2认同)
  • 假设 R 不是为实际可靠的开发而设计的。如果您有多个相互依赖的包,则相对于给定文件路径进行导入会非常困难。您唯一的选择是全局导入根脚本中的所有内容。这对于可靠的开发来说是不可接受的。 (2认同)
  • 这不是 R 包的工作方式,您有一个包名称空间,并且函数在该名称空间内相互调用。 (2认同)

Ale*_*ini 7

如果您通过命令行等运行 Rscript

Rscript /path/to/script.R
Run Code Online (Sandbox Code Playgroud)

下面的函数将分配this_file/path/to/script

library(tidyverse)
get_this_file <- function(){
    commandArgs() %>% 
       tibble::enframe(name=NULL) %>%
       tidyr::separate(col=value, into=c("key", "value"), sep="=", fill='right') %>%
       dplyr::filter(key == "--file") %>%
       dplyr::pull(value)
}
this_file <- get_this_file()
Run Code Online (Sandbox Code Playgroud)


小智 6

获取当前脚本路径的另一个选项是funr::get_script_path(),您不需要使用 RStudio 运行脚本。

  • 假设您有一个位于“/path/to/project/script.R”中的脚本,并且在该脚本中您有一个语句“funr::get_script_path()”,它将返回一个值“/path/to/project” `。注意:它返回当前文件的**完整目录路径**,而不是当前文件的**完整路径**,应该是`/path/to/project/script.R`。不过该功能适用​​于我的情况。 (3认同)

Jas*_*hau 6

这是一个自定义函数,用于在 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")
  }
}
Run Code Online (Sandbox Code Playgroud)

https://gist.github.com/jasonsychau/ff6bc78a33bf3fd1c6bd4fa78bbf42e7