开发者

In R, is there a way to know the path to the source file where a given function is defined?

开发者 https://www.devze.com 2023-02-14 23:37 出处:网络
I\'m writing a unit test in R, which needs to read some test data defined in the 开发者_Go百科same directory. But I would also like to be able to run that unit test no matter what the current working

I'm writing a unit test in R, which needs to read some test data defined in the 开发者_Go百科same directory. But I would also like to be able to run that unit test no matter what the current working directory happens to be.

Is there a way to tell R to load a file from here, where here is defined as the directory holding the source file of the function being executed?


Depends on how what you mean with "I'm writing a unit test". If you just source that function from wherever, David is right and I don't even see the need to do that as you know which directory it is.

I would include that function in a package, and then there are mechanisms in R allowing you to make the data available for loading or via lazy-loading. See section 1.1.5 (Data in packages) in the manual Writing R Extensions. This is the R-way of doing it.

Another option Gabor Grothendieck gave in this thread on the R mailing list, is to add following line at the top of a script :

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

This will give the directory of the file when sourced using source(). Gabor calls it a dirty hack, and I agree with him.

On a sidenote, check also following packages for unit testing in R :

  • RUnit
  • svUnit
  • testthat


If the functions aren't in a package, and sourced from files via source() then perhaps source references might provide something to work with. Argument keep.source = TRUE is required, and read the R Journal article by Duncan Murdoch

Here is a quick example:

> setwd("./Downloads/")
> source("../foo.R", keep.source=TRUE) ## if options("keep.source") is FALSE
> bar
function(a, b) {
    a + b
}
> body(bar)
{
    a + b
}
attr(,"srcfile")
../foo.R 
attr(,"wholeSrcref")
bar <- function(a, b) {
    a + b
}

> srcref <- attr(body(bar), "srcref")[[1]]
> attr(srcref, "srcfile")
../foo.R
> ls(attr(srcref, "srcfile"))
[1] "Enc"       "encoding"  "filename"  "timestamp" "wd"       
> attr(srcref, "srcfile")$filename
[1] "../foo.R"
> attr(srcref, "srcfile")$wd
[1] "/home/gavin/Downloads"

Of course this assumes you don't know where the sourced functions come from to be of any use and yet the functions need to be sourced...

If this is in a package, then you can have data in a ./data directory or arbitrary directories in ./inst/. You can use data() toload datasets from the former, and system.file() for any file in a package. See the relevant help pages.


There's no realistic hope of achieving this in full generality. Functions don't need to be loaded from files, they can be created dynamically by code, loaded from workspaces and so on.

0

精彩评论

暂无评论...
验证码 换一张
取 消