在这里

here包通过使用文件项目的顶级目录轻松构建文件路径,从而实现轻松的文件引用。这与使用setwd(),它很脆弱,取决于您在计算机上订购文件的方式。阅读有关面向项目的工作流的更多信息:

基本功能

为了进行演示,本文使用了一个位于/tmp/RtmpnoXhd8/Rinst301434451937/here/demo项目在我的机器上。这是项目根目录。您的机器上的路径很可能不同,此处的包有助于处理这种情况。

项目结构如下:

#>/tmp/RtmpnoXhd8/Rinst301434451937/此处/演示项目#>⑪——分析#>│∏——报告。房间#>&数据#>│&企鹅.csv#>&演示项目。Rproj项目#>●准备#>⑪——企鹅。R(右)

您可以在上查看项目github并下载副本。

要在RStudio中开始处理此项目,请打开演示项目。Rproj项目文件。这确保了工作目录设置为/tmp/RtmpnoXhd8/Rinst301434451937/here/demo项目,项目根目录。仅打开.房间文件可能不足!

其他开发环境可能对项目有不同的概念。无论是哪种方式,都必须将工作目录设置为项目根目录或该路径的子目录。您可以通过以下方式进行检查:

设置wd(项目路径)
获得()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”

(请参见渐晕(“rmarkdown”)例如,工作目录在启动时设置为子目录。)

声明当前脚本的位置

预期用途是添加对此处::i_am()在脚本的开头或rmarkdown报告的第一块。1这样可以实现以下目的:

的第一个参数此处::i_am()应该是当前文件的路径,相对于项目根。这个企鹅。R(右)脚本使用:

在这里::我(_A)(“准备/企鹅。R”)
#>here()开始于/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project

此处::i_am()显示当前项目的顶级目录。因为项目有一个准备/根目录中包含企鹅。R(右),它被正确推断为项目根。

之后此处::i_am(),插入图书馆(此处)使此处()可用功能:

图书馆(此处)

顶级目录也从此处()功能:

在这里()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”

与工作目录的一个重要区别是,即使工作目录发生更改,这一点也保持稳定:

设置wd(“分析”)
获得()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project/analysis”
在这里()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”
设置wd("..")

(我建议避免更改工作目录。这可能并不总是可行的,尤其是当工作目录被您无法控制的代码更改时。)

使用项目相关路径

您可以构建相对于顶级目录的路径,以便构建文件的完整路径:

在这里(“数据”,“企鹅.csv”)
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project/data/pengines.csv”
阅读器::读取csv(
  在这里(“数据”,“企鹅.csv”),
  列类型(_T)= 列表(默认值=阅读器::冷量(_G)()),
  n最大值= 
)
#>#易趣:3 x 8
#>物种岛bill_length_mm bill_depth_mm fliper_length…body_mass_g性别
#><chr><chr><dbl><dbl><dbl><dbl
#>1 Adelie Torge…39.1 18.7 181 3750男
#>2阿黛丽·托奇…39.5 17.4 186 3800女性…
#>3 Adelie Torge…40.3 18 195 3250 fema…
#>#…还有一个变量:年份<dbl>

无论关联的源文件位于项目中的何处,这都是有效的。使用此处(),路径将始终相对于顶级项目目录。

此处()工作原理与文件.path()fs::path(),可以传递路径组件或整个子路径:

在这里(“data/企鹅.csv”)
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project/data/pengines.csv”

如上所示,此处()返回绝对路径(以开头/,<驱动器号>:\\\). 这样可以安全地将这些路径传递给其他函数,即使工作目录在传递过程中发生了更改。

从1.0.0版开始,绝对路径传递给此处()返回时保持不变。这意味着您可以在中安全地使用绝对路径和项目相关路径此处().

数据路径(_P)<- 在这里(“数据”)
在这里(数据路径)
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project/data”
在这里(数据路径,“企鹅.csv”)
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project/data/pengines.csv”

情况报告

这个博士()函数解释了选择项目根的原因:

dr_此处()
#>here()开始于/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project。
#>-此目录包含一个文件“prepare/pengines.R”
#>-初始工作目录:/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project
#>-当前工作目录:/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project

这个show_reason(显示原因)参数可以设置为错误的要将输出减少为一行:

dr_此处(show_reason(显示原因)= 错误的)
#>here()开始于/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project

如果工作目录错误怎么办?

通过声明活动文件此处::i_am()还可以防止从项目外部的工作目录意外运行脚本。下面的示例调用此处::i_am()从临时目录中,该目录显然不在我们的项目范围内:

用r::带目录(_D)(临时目录(), {
  打印(获得())
在这里::我(_A)(“准备/企鹅。R”)
})
#>[1]“/tmp/RtmpHuFWzz”
#>错误:在工作目录或任何父目录中找不到关联的项目。
#>-项目路径:准备/企鹅。R(右)
#>-当前工作目录:/tmp/RtmpHuFWzz
#>请打开与此文件关联的项目,然后重试。

在重命名或移动文件而不更新此处::i_am()呼叫。将来,助手功能将帮助安装和更新适当格式的此处::i_am()调用脚本和报告。

额外的安全

与其他程序包冲突

其他程序包也导出此处()功能。在这里装货后再装货会掩盖我们的此处()功能:

图书馆(每年)
#>
#>附加包装:“plyr”
#>以下对象已从“package:here”中屏蔽:
#>
#>这里
在这里()
#>here()中出错:缺少参数“f”,没有默认值

解决此问题的一种方法是使用这里::这里():

在这里::在这里()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”

冲突包提供了另一种选择:它检测到此处()是从多个包导出的,在指定首选项之前,您既不能使用,也不能使用。

图书馆(矛盾)
在这里()
#>错误:在2个包中找到[冲突]`此处`。
#>用`::选择您想要的`
#>*plyr::此处
#>*此处::此处
#>或使用`conflict_prefer()声明首选项`
#>*conflict_prefer(“此处”,“plyr”)
#>*conflict_prefer(“此处”、“此处”)

冲突的::冲突_参考(“在这里”,“在这里”)
#>[矛盾的]比起其他套餐,更喜欢这里::这里
在这里()
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”

指定唯一标识符

为了消除潜在的混淆,此处::i_am()接受乌伊德参数。其思想是每个脚本和报告调用此处::i_am()很早(前100行)就有了一个通用的唯一标识符。即使文件位置跨项目重用(例如,两个项目包含一个“prepare/data.R”文件),如果乌伊德中的参数此处::i_am()呼叫不同。

如果乌伊德参数传递给此处::i_am():

使用uuid::UUIDgenerate()要创建通用唯一标识符:

乌伊德::UUID生成()
#>[1]“36f421ac-2d53-46d4-bfad-a0ac96491443”

确保乌伊德参数在文件中实际上是唯一的!将来,助手功能将帮助安装和更新适当格式的此处::i_am()调用脚本和报告。

在这里以外

更改项目根目录

建议开始新的R会话尽可能经常,尤其是在专注于另一个项目之前。当需要重置项目根时,仍然可能存在合法的情况。

首先,让我们创建一个临时项目进行演示:

临时项目路径<- 临时文件()
目录.创建(临时项目路径)
脚本_路径<- 文件路径(临时项目路径,“脚本”)
目录.创建(脚本路径)
脚本路径(_P)<- 文件路径(scripts_path,“脚本.R”)
写入行(
  c(
    '此处::i_am(“scripts/script.R”)',
    '打印(“你好,世界!”)'
),
脚本路径(_P)
)
英尺::目录树(_T)(临时项目路径)
#>/tmp/RtmpHuFWzz/file30547d5e00ca
#>&脚本
#>⑪——脚本。R(右)
写入行(读行(脚本路径)
#>此处::i_am(“scripts/script.R”)
#>打印(“你好,世界!”)

这个脚本。R(右)文件包含对的调用此处::i_am()声明其位置。从当前工作目录运行它将失败:

来源(脚本路径,回声= 真的)
#>
#>>此处::i_am(“scripts/script.R”)
#>错误:在工作目录或任何父目录中找不到关联的项目。
#>-项目中的路径:脚本/脚本。R(右)
#>-当前工作目录:/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project
#>请打开与此文件关联的项目,然后重试。

要重置项目根中期会话,请使用更改工作目录setwd()现在,接下来调用此处::i_am()从内部脚本。R(右)作品:

设置wd(临时项目路径)
来源(脚本路径,回声= 真的)
#>
#>>此处::i_am(“scripts/script.R”)
#>此处()开始于/tmp/RtmpHuFWzz/file30547d5e00ca
#>
#>>打印(“你好,世界!”)
#>[1]“你好,世界!”

重申一下:新的会议几乎总是更好、更干净、更安全和更健壮的解决方案。只能将此方法用作最后手段。

引擎盖下:rprojroot

根据设计,here包具有非常简单且受限的界面。底层逻辑由功能更强大的rprojroot包提供。如果由于某种原因,此处的默认行为不适合您的工作流,那么rprojroot包可能是更好的选择。还建议从其他包中导入rprojroot,而不是在此处导入。

以下示例显示如何从目录开始查找RStudio项目:

图书馆(rprojroot)
查找根(是学习项目,文件路径(项目路径,“分析”))
#>[1]“/tmp/RtmpnoXhd8/Rinst301434451937/here/demo-project”

可以定义任意标准。请参见vignette(“rprojroot”,package=“rproyroot”)作为介绍。


  1. 在1.0.0版之前,建议通过附加here包图书馆(此处)。这仍然有效,但不再是推荐的方法。↩︎

  2. 图书馆(此处)如果此处::i_am()以前被调用过。↩︎

  3. 图书馆(此处)发出一条消息,如果后面跟来自此处::i_am().↩︎