在Rstudio中设置工作目录为源文件位置的R命令

182

我正在学习R的一些教程,每个R代码都在特定文件夹中。这里有数据文件和其他文件。 我想打开.r文件并对其进行源引用,以便我不必像下面显示的那样更改Rstudio中的工作目录:

进入图像描述

是否有一种方法可以自动指定我的工作目录在R中?


这可能是一个重复的问题。请参阅 ?setwd?getwd - Brandon Bertelsen
4
获取 R 脚本的路径:可以使用 commandArgs(trailingOnly = TRUE) 函数获取当前 R 脚本的路径,然后用 dirname() 函数提取出该文件所在的目录路径。例如,以下代码将输出当前 R 脚本的路径:r_script_path <- commandArgs(trailingOnly = TRUE)[1] r_script_dir <- dirname(r_script_path) print(r_script_dir) - nico
4
不是重复问题,发帖者想要在同一文件夹中“加载” .rdata 文件,而不是使用工作目录设置为源文件路径的“源”文件。 - Ruben
为什么R让这件事情变得如此困难? - Giacomo
18个回答

136

要获取脚本被引用的位置,可以使用utils::getSrcDirectoryutils::getSrcFilename。这些函数需要一个函数作为输入。创建一个包含以下行的脚本,然后将其引用以查看它们的用法:

print(utils::getSrcDirectory(function(){}))
print(utils::getSrcFilename(function(){}, full.names = TRUE))

可以使用以下代码将当前工作目录更改为当前文件所在的目录:

setwd(getSrcDirectory(function(){})[1])

如果您在RStudio中运行代码而不是使用源代码,则此方法无效。 您需要使用rstudioapi :: getActiveDocumentContext

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

当然,这个第二种解决方案需要您使用RStudio作为您的IDE。


8
请注意,在RStudio控制台中运行getActiveDocumentContext()时,路径报告为''。但是,如果在编辑器部分运行代码行,则会按预期执行。这可能可以解决@Andru的评论。 - Megatron
1
@giac_man,听起来你正在使用一个非常旧的rstudioapi包版本。尝试更新到最新版本。 - Richie Cotton
2
当我对文件进行源代码处理时,setwd(getSrcDirectory()[1]) 对我不起作用。使用 rstudioapi 解决方案可以解决问题。 - filups21
1
@mjs 在控制台的顶部,您应该看到当前工作目录。在其右侧有一个小箭头。单击它以在文件浏览器中显示当前工作目录。 - Richie Cotton
1
@filups21 @SimonChemnitz-Thomsen 注意,您可以使用以下技巧来获取脚本目录:使用utils::getSrcDirectory()。在脚本中要做的第一件事是定义一个虚拟函数,然后使用该函数作为参数调用utils::getSrcDirectory()。例如:dummy = function() {}; scriptdir = utils::getSrcDirectory(dummy); rm(dummy) - mastropi
显示剩余10条评论

68

我知道这个问题已经过时了,但我也在寻找解决方案,而且Google将其排在首位:

this.dir <- dirname(parent.frame(2)$ofile)
setwd(this.dir)

把它放到文件中的某个地方(尽管最好放在开头),这样wd就根据那个文件改变了。

根据评论,这种方法不一定适用于每个平台(似乎Windows可以,Linux/Mac则要看情况)。 请记住,此解决方案是用于'获取'文件,而不一定是用于运行该文件中的代码块。

另请参见获取'source'd文件的文件名和路径


112
我也尝试了,但是没有成功:dirname(parent.frame(2)$ofile) 函数出错: 预期的是一个字符向量参数。Error in dirname(parent.frame(2)$ofile) : a character vector argument expected - tumultous_rooster
4
和 @Matt O'Brien 在 Linux 上遇到了同样的问题。 - patapouf_ai
5
如果有合适的来源,就能够完美运作。 - m-dz
2
在Windows 10上的RStudio v1.0.143中对我有效。如果选择“保存时源代码”,它将正常工作(您可以使用“cat”打印出检测到的目录)。如果选择行然后执行它们,那么结果为空。 - Contango
2
这对我在Mac上使用source文件时有效。然而,正如@Contango在上面指出的那样,当通过突出显示一个块并按Command + Return来交互式地执行代码时,它将无法工作。在这种情况下,由于您没有使用source文件,因此没有源文件可以从中提取工作目录。答案不需要指定特定于平台的注意事项。 - bmosov01
显示剩余4条评论

13

对于RStudio,您可以使用rstudioapi自动将工作目录设置为脚本所在的目录,方法如下:

library(rstudioapi)

# Getting the path of your current open file
current_path = rstudioapi::getActiveDocumentContext()$path 
setwd(dirname(current_path ))
print( getwd() )

当你运行或源代码文件时,这将起作用。

你需要首先安装rstudioapi包。 请注意,我打印路径以确保我在正确的位置,但这是可选的。


setwd(dirname(current_path)) 出错:无法更改工作目录。 - tavalendo
@helmo,请检查您的用户是否对目标目录具有写入权限。 - gagarine
1
不幸的是,"rstudioapi::getActiveDocumentContext()$path" 给我返回一个空字符串。 - Giacomo

8
dirname(rstudioapi::getActiveDocumentContext()$path)

对我来说可以工作,但如果你不想使用rstudioapi并且没有在项目中,你可以在路径中使用符号~。符号~指的是默认的RStudio工作目录(至少在Windows上)。

RStudio options

如果你的RStudio工作目录是“D:/Documents”,setwd("~/proyect1")与setwd("D:/Documents/proyect1")相同。
一旦设置完成,您可以导航到子目录:read.csv("DATA/mydata.csv")read.csv("D:/Documents/proyect1/DATA/mydata.csv")相同。
如果要导航到父文件夹,您可以使用"../"。例如:read.csv("../olddata/DATA/mydata.csv")read.csv("D:/Documents/oldata/DATA/mydata.csv")相同。
这是我编写脚本的最佳方式,无论使用哪台计算机。

7

我知道这是一个旧的帖子,但我遇到了类似的问题,需要设置工作目录,但无法找到任何解决方案来解决我的问题。以下是我用到的方法,以防其他人在以后也会遇到同样的问题:

# SET WORKING DIRECTORY TO CURRENT DIRECTORY:
system("pwd=`pwd`; $pwd 2> dummyfile.txt")
dir <- fread("dummyfile.txt")
n<- colnames(dir)[2]
n2 <- substr(n, 1, nchar(n)-1)
setwd(n2)

虽然有点复杂,但基本上它使用系统命令获取工作目录并将其保存到dummyfile.txt中,然后R使用data.table :: fread读取该文件。 其余的只是清理打印到文件中的内容,以便我只剩下目录路径。

我需要在集群上运行R,因此无法知道我最终会在哪个目录中(作业分配一个数字和计算节点)。这对我很有用。


6

6
如果您正在使用Linux,可以尝试以下方法: setwd(system("pwd", intern = T) ) 这对我很有效。

1
这只是提供您的主目录(即您的shell启动位置)。 - Caner
它提供了运行脚本的目录路径。 - Taz
2
pwd代表当前工作目录。这将把目录设置为shell的当前目录。 - PeterVermont
pwd 在 PowerShell 中也可以使用(它目前被认为是 Windows 上的默认 shell),其中它是 Get-Location 的别名。 - BroVic
@PeterVermont 实际上它代表着打印工作目录 - robertspierre

5
解决方案
dirname(parent.frame(2)$ofile)

对我没有用。

我正在使用暴力算法,但是有效:

File <- "filename"
Files <- list.files(path=file.path("~"),recursive=T,include.dirs=T)
Path.file <- names(unlist(sapply(Files,grep,pattern=File))[1])
Dir.wd <- dirname(Path.file)

在搜索目录时更加简便:

Dirname <- "subdir_name"
Dirs <- list.dirs(path=file.path("~"),recursive=T)
dir_wd <- names(unlist(sapply(Dirs,grep,pattern=Dirname))[1])

2
这个解决方案的问题在于它非常慢。搜索所有文件并存储在变量中也会占用大量内存。 - tavalendo

5

here 包提供了 here() 函数,根据一些启发式方法返回您的项目根目录。

虽然它不能完美解决找到脚本位置的问题,但对于某些目的来说足以满足需求。因此我想在这里分享这个包。


2
谢谢你的回答。可以通过在源代码中调用 here::set_here() 来获取当前脚本的位置。 - BroVic
1
在使用RStudio进行项目设置时,here::here()返回的是项目的工作目录,而不是脚本的位置。而this.path::here()则不受项目设置的影响,始终能够正确返回脚本的位置。 - undefined

4
setwd(this.path::here())

适用于引用的脚本和“活动”的脚本。


我收到的错误信息是“在加载命名空间时出错:没有名为'this.path'的包” - 我缺少了什么? - Giacomo
1
在你能够执行 install.packages("this.path") 命令之前,你需要先安装这个软件包。 - giacomo
太好了!谢谢你。 - Giacomo
1
我确认这个方法有效。它是所有答案中最简单的一个。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接