【问题标题】:How to set the current file location as the default working directory in R programming?如何将当前文件位置设置为R编程中的默认工作目录?
【发布时间】:2016-05-06 14:54:14
【问题描述】:

我想将当前文件位置作为工作目录。

使用 Rstudio(有效!):

# Author  : Bhishan Poudel
# Program : writehere.r
# Source  : Rscript writehere.r

# set working directory here
this.dir <- dirname(parent.frame(2)$ofile) # frame(3) also works.
setwd(this.dir)

# Sample data to test this code
mydata <- seq(1:10)
write.csv(mydata,"writehere.dat")
#This works flawlessly in  MacOS 10.9 and Ubuntu 15.1.

从终端使用命令:Rscript writehere.r(不起作用!)

Error in dirname(parent.frame(2)$ofile) : 
  a character vector argument expected
Execution halted


------------------
(program exited with code: 1)

从终端使用命令:Rscript writehere.r(现在可以使用!)

# Author  : Bhishan Poudel
# Program : writehere.r
# Source  : Rscript example.r

# set working directory here
this_dir <- function(directory)
setwd( file.path(getwd(), directory) )

# Sample data to test this code
mydata <- seq(1:10)
write.csv(mydata,"writehere.dat")

在 Rstudio 中使用 ~/.Rprofile 中的函数(有效!):

##############################################
# inside ~/.Rprofile
# set up working directory
setwd_thisdir <- function () {
  this.dir <- dirname(parent.frame(3)$ofile)
  setwd(this.dir)
} 
##############################################

然后,在任何目录中,假设我有一个文件 writehere.r,现在它可以工作了。

# Author  : Bhishan Poudel
# Program : writehere.r
# Compile : Rscript writehere.r

# set working directory here
setwd_thisdir

# Sample data to test this code
mydata <- seq(1:10)
write.csv(mydata,"writehere.dat")

问题: 为什么函数

this.dir <- dirname(parent.frame(2)$ofile) # frame(3) also works.
setwd(this.dir)

不适用于 Rstudio 以外的文本编辑器?

一些有用的链接如下:
R setting working directory to source file location?
R command for setting working directory to source file location
get filename and path of `source`d file
setwd() in the current working dir
Command for "Set working directory to source file location"
SublimeText and R: Setting Current File Directory
@987654327 @
What is a fool-proof way of permanently setting R working directory?
R setting working directory to source file location?
How to get into the directory of a file in R?

【问题讨论】:

  • 什么是class(parent.frame(2)$ofile)
  • @MichaelChirico 我不知道,我听从了链接stackoverflow.com/questions/34843889/…的建议
  • 添加行 print(class(parent.frame(2)$ofile)) 并尝试运行您的函数。l
  • @MichaelChirico 的答案是“NULL”
  • 为了澄清,这里的所有方法只适用于sourced 或传递给RScript 的文件。似乎无法确定当前逐行运行的文件(或该文件的目录)(Ctrl+R)。 R应该怎么知道?在这种情况下,代码逐行传递给解释器——不涉及文件。但是,RStudio 知道哪个文件当前处于活动状态,但恕我直言,目前没有办法利用它。

标签: r setwd


【解决方案1】:

尝试在你的函数中使用parent.frame(3)

setwd_thisdir <- function () {
  this.dir <- dirname(parent.frame(3)$ofile)
  setwd(this.dir)
}

请参阅?parent.framehttp://adv-r.had.co.nz/Environments.html#calling-environments

您还可以查看 source 函数 (?source) 的 chdir 选项。

【讨论】:

    【解决方案2】:

    更新:我意识到这个答案根本没有帮助,我将发布另一个可以解决问题的答案。

    只要您要运行的代码不需要任何额外的参数,使用eval(expr, envir) 的解决方案如下图所示。

    考虑以下使用print(environment()) 的示例,在命令行上使用时应返回environment: R_GlobalEnv。函数test_1 将打印有关调用该函数时创建的内部环境的信息,而函数test_2 将返回所需的结果。

    test_1 <- function(){
         print(environment())
    }
    
    test_2 <- function(){
        .expr <- quote({
            print(environment())
            })
        .envir <- sys.frame(which = -1)
        eval(expr = .expr,
             envir = .envir)
    }
    

    sys.frame(which = -1) 确保在调用函数的环境中计算表达式。如果你确定你总是想使用全局环境,那么最好使用.GlobalEnv。引用您要使用的表达式也很重要,否则它可能无法按预期工作。

    此解决方案的一个不错的特点是您无需调整要放入​​函数的代码,只需引用它即可。

    最后:可以扩展这种方法,以便您的函数可以接受参数,然后将这些参数提供给您要在另一个环境中评估的代码。但是,这将需要对您要评估的表达式进行一些重要的调整;您可能需要使用 bquote + .() 构造 - 您可能还需要使用 calldo.call

    【讨论】:

      【解决方案3】:

      我给出的第一个答案完全没有抓住重点,因为我没有 仔细研究你想要达到的目标。解决方案 然而,这里介绍的应该可以解决问题。

      首先注意source 有一个参数chdir,在帮助文件中描述为:logical;如果TRUEfile是路径名,则将R工作目录临时更改为包含file的目录进行评估。

      每次要获取文件时手动指定该参数 会很痛苦,所以让我们在 .Rprofile 中添加一些东西来改变 chdir 的默认值从 FALSETRUE

      formals-函数可用于修改默认值 值,但是当用于属于其他某个函数的函数时 环境,结果将是创建函数的本地副本。这还不够好。

      可能有几种方法可以解决这个问题,但以下 当我将 source 插入到 .Rprofile 中时,source 的小技巧对我起到了作用。

      .temporary_copy_source <- base::source
      formals(.temporary_copy_source)$chdir <- TRUE
      utils::assignInNamespace(
          x = "source",
          value = .temporary_copy_source,
          ns = environment(source))
      rm(.temporary_copy_source)
      

      警告:这里介绍的方法原则上可以 允许用户修改任何参数的默认值 功能,但这将是一个非常糟糕的主意。保持 请记住,您的脚本稍后可能会与某人共享 与您拥有的 .Rprofile 不同。 永远不要写 需要对命名空间进行此类修改的代码!

      【讨论】:

        【解决方案4】:

        我写了另一个答案,因为你改变了你的问题。有两个有用的事实:

        1. ofilesource函数环境中的一个变量,所以只有在运行一些带有source函数的脚本时才能使用它。
        2. 当您从终端运行脚本时,工作目录将设置为终端中的当前目录。

        所以,评论你的观察:

        1. 使用 Rstudio(有效!)。如果您按 Source(使用 source 函数),则可以,但如果您按 Run(仅在 R 控制台中运行命令),则不会。
        2. Rscript writehere.r(不起作用!)。那是因为您正在寻找 ofile 而没有致电 source
        3. Rscript writehere.r(现在可以使用!)。是的,但它只适用于事实 2:代码 this_dir &lt;- function(directory) setwd( file.path(getwd(), directory) ) 是不必要的,因为它只是一个名为 this_dir 的函数的定义。
        4. Rstudio(工作!)。第一部分:好的。第二部分。它只适用于事实 2。特别是setwd_thisdir 是不必要的,因为它只是将setwd_thisdir 的正文打印到控制台。

        总而言之,setwd(dirname(parent.frame(2)$ofile)) 是一个有用的技巧,当您使用 source 函数获取脚本但无权访问 source 函数选项时:例如当您在 R-Studio 中按 Source 时。如果可能,请使用 source 函数和 chdir=TRUE。如果您从终端运行脚本,只需将终端设置为脚本文件夹即可。

        【讨论】:

          【解决方案5】:

          很简单,使用rstudio API,解压其目录,设置为工作目录,如下图:

          setwd(dirname(rstudioapi::getSourceEditorContext()$path))
          

          通过以下命令验证你是否正确设置了目录:

          getwd()
          

          【讨论】:

            猜你喜欢
            • 2017-11-16
            • 1970-01-01
            • 1970-01-01
            • 2020-02-17
            • 2011-05-28
            • 2022-06-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多