查找当前.R文件的位置

问题描述 投票:18回答:4

我已经查看了许多与此相似的问题(见帖子末尾),但我还没有找到任何实际完成我需要的解决方案。我根据项目在Windows或Fedora上编码,我为使用Windows和几个Linux发行版的人编写代码。

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

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

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

这个问题只涉及第2步。只要我能做到这一点,其他所有事情都会顺利进行。有这样的东西会很高兴:

setwd(FindThisScriptsLocation())

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

以下是一些相关问题:

r
4个回答
4
投票

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

Option 1 (programatically)

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

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

Option 2 (interactively)

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

FILE <- file.choose()

THEN:

DIR  <- dirname(FILE)

并且你有你的目录/文件夹,你可以正常执行你的脚本传递DIR作为参数


8
投票

有同样的问题,这就是我想出的。它适用于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)
}

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

1
投票

我认为这是Windows。

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.