【问题标题】:Find location of current .R file查找当前 .R 文件的位置
【发布时间】:2013-08-02 18:26:59
【问题描述】:

我已经查看了许多与此类似的问题(请参阅帖子末尾),但我还没有找到任何真正满足我需要的解决方案。我根据项目在 Windows 或 Fedora 上编写代码,并且我为使用 Windows 和多个 Linux 发行版的人编写代码。

我的部分工作是为自动分析数据和创建图表的人们编写 R 脚本。最常见的是,我只是将脚本发送给他们,它会生成图表。这样,如果数据发生变化或扩展,我不需要为它们重新运行脚本(而且,它们可以根据需要进行更改)。

问题是我不知道如何获得一个 R 脚本来找出它自己的位置。能够创建如下工作的代码会非常方便:

  1. 用户将脚本保存到包含数据的文件夹中,然后运行脚本。
    • 我通常只是将脚本通过电子邮件发送给与我一起工作的人。
    • 他们将脚本保存到包含他们想要分析/绘制的数据的文件夹中。
    • 理想情况下,他们只需启动 R,加载脚本,然后运行脚本。
  2. 脚本确定自己的位置,然后将其设置为工作目录。
  3. 脚本分析自己目录中的数据。
  4. 脚本生成图表并将其保存到自己的目录中。

这个问题只涉及第 2 步。只要我能完成,其他一切都会顺利进行。有这样的东西会很好:

setwd(FindThisScriptsLocation())

这一行:source(..., chdir = T) 已被建议 here,但它不能用于脚本引用自身,除非它知道自己的路径。

以下是一些相关问题:

【问题讨论】:

  • 请提供类似问题的链接,并告诉我们在这种情况下哪些问题不起作用。
  • 在第 1 步中,用户如何运行脚本?这就是信息可以传递给函数的地方。
  • @HongOoi 与我共事的人表示他们特别希望我这样做。目前,工作目录每次易手或位置时,我们都必须手动设置它。
  • 这似乎过于复杂。为什么不直接向他们发送一个包含他们可以调用的函数的工作区文件(通过save.image 创建)?只要.RData文件与R关联,就可以在任意目录下双击文件,然后调用函数。

标签: r


【解决方案1】:

遇到了同样的问题,这就是我想出的。 它适用于 windows 和 linux 上的 source() 和 rmarkdwon::render()。

更新:函数 get_scriptpath() 现在可以作为我在 CRAN 上的 envDocument 包的一部分使用。见https://cran.r-project.org/package=envDocument

#' Get the path of the calling script
#' 
#' \code{get_scriptpath} returns the full path of the script that called this function (if any)
#' or NULL if path is not available
#' 
#' @examples 
#' mypath <- get_scriptpath()
#' @export
#' 
get_scriptpath <- function() {
  # location of script can depend on how it was invoked:
  # source() and knit() put it in sys.calls()
  path <- NULL

  if(!is.null(sys.calls())) {
    # get name of script - hope this is consisitent!
    path <- as.character(sys.call(1))[2] 
    # make sure we got a file that ends in .R, .Rmd or .Rnw
    if (grepl("..+\\.[R|Rmd|Rnw]", path, perl=TRUE, ignore.case = TRUE) )  {
      return(path)
    } else { 
      message("Obtained value for path does not end with .R, .Rmd or .Rnw: ", path)
    }
  } else{
    # Rscript and R -f put it in commandArgs
    args <- commandArgs(trailingOnly = FALSE)
  }
  return(path)
}

【讨论】:

  • 这是唯一对我有用的建议答案。运行 Lubuntu 16.04。
  • 我对如何使用这个函数感到困惑..我传递给它的参数是什么?不带参数调用 get_scriptpath() 时出现错误:Error in get_scriptpath() : No path information available
  • 这个函数没有参数。它仅在从正在运行的脚本调用时才起作用(例如,如果您使用 Rscript、source、rmarkdown::render 运行脚本或 RMD 文件)。如果您从 R 控制台调用它,它将无法工作,因为控制台不是脚本。 cran.r-project.org/package=envDocument 的 envDocument 包提供了此函数的一个版本,改进了文档和错误处理。
  • 为什么要过滤文件扩展名?在哪些情况下,您遇到了没有预期扩展名之一的调用文件?
  • 偏执狂——如果出于某种原因运行脚本/报告的系统调用不是我所期望的,那么我想提醒一下;我相信它在 sys.call 返回值中始终处于相同的位置。回想起来,我什至可能会将其升级为警告或错误。而且我不想想象是否由于某种原因存在具有预期扩展名的不正确值...
【解决方案2】:

“加载脚本” 过程中的某处,您正在传递 R 脚本的名称和路径。 我建议捕获该信息,然后使用包装脚本来执行您的主脚本。

选项 1(以编程方式)

将要执行的脚本的路径和文件名作为参数的包装函数

FILE <- "~/Desktop/myFolder/InHere/myScript.R"

选项 2(交互式)

在包装函数的开头,让用户点击文件:

FILE <- file.choose()

那么:

DIR  <- dirname(FILE)

你有你的目录/文件夹,你可以像往常一样执行你的脚本,传递DIR作为参数

【讨论】:

    【解决方案3】:

    嘿,我有一个可能的解决方案,它需要一些额外的初始工作,但应该能够满足您的需求。

    首先让您的 R 脚本接受一个参数,该参数将是脚本的位置。 接下来你只需要创建一个 Bash/Batch(windows 和 unix 各一个)

    1) 获取自己的目录

    2) 在目录中搜索 R 脚本(简单 *.R 搜索)

    3) 从步骤 1 开始,使用自己的目录调用 R 脚本。

    然后,您只需将 Bash 和 Batch 脚本与您提供给客户的文件夹一起打包,并要求他们为他们的环境运行相关脚本。

    理论上,您应该只需要创建一次 Bash/Batch 脚本。

    编辑:我创建了一个简单的 bash 脚本来解决这个问题,见下文

    #!/bin/bash
    
    #Modify the search string to narrow the search
    SEARCH_STRING="*.R"
    
    #Get the current directory
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    echo ${DIR}
    
    #Get the name of the R script
    R_SCRIPT=`find $DIR -name ${SEARCH_STRING} -type f -exec basename {} \;`
    echo ${R_SCRIPT}
    
    Rscript ${R_SCRIPT} ${DIR}
    

    我对 Windows Shell 不太熟悉,所以你必须自己做那个:P

    您可以使用此 R 脚本对其进行测试;

    options(echo = FALSE) #So we don't get the script echo'd
    
    arguments <- commandArgs(trailingOnly = TRUE) #getting the arguments
    
    working_directory <- arguments[1]
    
    setwd(working_directory)
    
    getwd() #print out to test
    

    【讨论】:

      【解决方案4】:

      我假设这是 Windows。

      遵循 Ricardo 的建议:让客户端的系统设置为,如果双击脚本,则在脚本目录中启动 R 解释器。您还可以为此行为分配一个特殊的扩展名(例如,.Rwd 用于“R 脚本设置工作目录”)。然后,您不需要在脚本中setwd()

      对于初学者,以下命令行脚本可能会做(未经测试):

      pushd %~d1%~p1
      R --vanilla < "%1"
      

      .Rwd 文件与此脚本相关联。

      如果您需要source() 其他脚本,请考虑使用chdir=T 参数。

      【讨论】:

      • 我主要使用 Windows,但我也使用 Fedora,具体取决于项目。我为运行 Windows 和一些 Linux 发行版的人编写代码。你的答案肯定会奏效(我会学习如何做你所说的,听起来很有用),但并不完全理想。
      • 您可以将%~d1%~p1缩写为%~dp1
      【解决方案5】:

      如果您使用的是 RStudio,只需将光标悬停在脚本上,路径就会出现

      【讨论】:

      • @stevec- 与批处理执行相关的问题,不使用 Rstudio GUI
      • @DonJ 这可能是真的,但我来到这里是为了寻找如何在 RStudio 中查看 R 文件的位置,所以我猜其他人会从同一个谷歌搜索中结束。因此,在此处包含此信息是无害的
      猜你喜欢
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      相关资源
      最近更新 更多