获取`source`d文件的文件名和路径

时间:2012-01-12 12:56:13

标签: r sweave

source d或Sweave d文件如何找到自己的路径?

背景:

我使用.R脚本或.Rnw文件工作了很多。 我的项目是在一个目录结构中组织的,但是项目基本目录的路径经常在不同的计算机之间变化(例如,因为我只为其他人做了部分数据分析,他们的目录结构与我的不同:我有项目基目录〜/ Projects / StudentName /或〜/ Projects / Studentname / Projectname和大多数只拥有一个项目的学生通常在〜/ Measurements /或〜/ DataAnalysis /或类似的东西下 - 这对我不起作用)。

所以像

这样的一行
    setwd (my.own.path ()) 

将非常有用,因为它可以确保工作目录是项目的基本路径,而不管项目实际位于何处。用户无需考虑设置工作目录。

让我澄清一下:我寻找一个解决方案,可以按下编辑器的/ IDE的sourceSweave键盘快捷方式。

6 个答案:

答案 0 :(得分:12)

仅供参考,knitr setwd()knit('path/to/input.Rnw')输入文件的目录(当且仅在评估代码块时),即如果您调用path/to/,则工作目录将是暂时切换到knitr:::input_dir()。如果你想知道代码块中的输入目录,目前你可以调用一个未导出的函数{{1}}(我将来可以将它导出)。

答案 1 :(得分:11)

从gsk3的Seb建议开始,这是一个想法:

  • 可以使用用户名(登录名)和IP或计算机名称的组合来选择正确的目录。

这会导致类似:

    setwd (switch (paste (Sys.info () [c ("user", "nodename")], collapse="."), 
           user.laptop  = "~/Messungen",
           user2.server = "~/Projekte/Projekt/",
           ))

所以有一个自动解决方案,

  • 适用于source
  • 适用于Sweave
  • 甚至适用于逐行发送命令的交互式会话

  • usernodename的组合当然需要具体具体

  • 但需要手动编辑路径。

欢迎改进!


更新

Gabor Grothendieck今天就r-help的相关问题回答了以下问题:

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

适用于source


另一个更新:我现在在RStudio中进行大部分数据分析工作。 RStudio的项目基本上解决了这个问题:每次在项目之间切换时,RStudio都会将工作目录更改为项目根目录。

因此,我可以将项目目录放在我想要的目录树中(并且学生也可以将他们的副本放在他们想要的任何地方)并通过版本控制同步数据文件和脚本/ .Rnw(我们使用私人git服务器)。 RStudio项目文件不受版本控制,即.gitignore包含.Rproj.user

显然,项目中,目录结构需要同步。

答案 2 :(得分:4)

您可以使用sys.calls()获取用于获取文件的命令。然后,您需要使用正则表达式来获取路径名,请记住source("something/filename")可以使用绝对路径或相对路径。这是将所有部分组合在一起的第一次尝试:尝试在源文件的顶部插入以下行。

whereFrom=sys.calls()[[1]]
# This should be an expression that looks something like
# source("pathname/myfilename.R")
whereFrom=as.character(whereFrom[2]) # get the pathname/filename
whereFrom=paste(getwd(),whereFrom,sep="/") # prefix it with the current working directory
pathnameIndex=gregexpr(".*/",whereFrom) # we want the string up to the final '/'
pathnameLength=attr(pathnameIndex[[1]],"match.length")
whereFrom=substr(whereFrom,1,pathnameLength-1)
print(whereFrom) # or "setwd(whereFrom)" to set the working directory

它不是很健壮 - 例如,它会在source("pathname\\filename")的窗口上失败,我还没有测试如果你有一个文件来源另一个文件会发生什么 - 但你可能能够构建一个解决方案最重要的。

答案 3 :(得分:3)

我没有直接的解决方案如何获取文件本身的目录,但是如果你有一个有限范围的目录和目录结构,你可以使用

 if(file.exists("c:/somedir")==TRUE){setwd("c:/somedir")}

您可以查看相关目录的模式,然后设置目录。这对你有帮助吗?

答案 4 :(得分:2)

另一个问题是工作目录是一个全局变量,可以由任何脚本更改,因此如果您的脚本调用另一个脚本,则必须重新设置wd。在RStudio中我使用Session - &gt;设置工作目录 - &gt;来源文件位置(我知道,这不是理想的),然后我的脚本

wd = getwd ()
...
source ("mySubDir/myOtherScript.R", chdir=TRUE); setwd (wd)
...
source ("anotherSubDir/anotherScript.R", chdir=TRUE); setwd (wd)

通过这种方式,可以维护一堆工作目录。我很乐意看到这个用语言本身实现。

答案 5 :(得分:0)

此答案适用于source以及nvim-R内部 - 我不知道它是否适用于knitr和类似的事情。任何反馈意见。

如果您有多个脚本source,那么获取正确的脚本非常重要。也就是说,i存在的最大sys.frame(i)$ofile

get.full.path.to.this.sourced.script = function() {    
    for(i in sys.nframe():1) {  # Go through all the call frames,
                                # in *reverse* order.
        x = sys.frame(i)$ofile
        if(!is.null(x))               # if $ofile exists,
            return(normalizePath(x))  #  then return the full absolute path
    }
}