我有几个R脚本文件,例如f1.R
,f2.R
,f3.R
。
我有另一个名为AddSignal(signal)的函数,它将一个信号向量添加到列表中。 f1.R,f2.R等中的函数可以调用此AddSignal()函数。
现在我想要的是,在函数AddSignal()中,除了执行add信号部分之外,它还记录了R文件调用哪个函数。例如,我想知道f1.R中的函数ff1()添加了信号sig1。
有办法吗?
实际上,使用sys.call(),我可以知道哪个函数(例如,ff1())称为AddSignal()。但我不知道ff1()所在的哪个R文件。我可以看到一种难以实现的方法,就是扫描所有.R文件,然后存储文件名和函数名的映射。但是我想看看是否有更简单的方法。
感谢。
答案 0 :(得分:6)
我要做的是创建一个查找表,将函数映射到它所在的.R
文件。每次添加,删除或移动函数时都必须重新创建此表,但我认为它每次要查找函数的源文件时,最好重新生成表。所以这是我创建这样一个表:
library(plyr)
functionsFromRfile = function(filename) {
# Get all functions from a source file. Create new enviroment
# source the functions into them and use ls() to extract names.
e = new.env()
source(filename, local = e)
return(ls(envir = e))
}
# This assumes you are in the directory with your R code,
# and that all files need to be included. You can also
# make this list manually ofcourse
Rfiles = list.files(".", pattern = ".R")
# Get a list of functions for each .R file
lutFunc2sourcefile = ldply(Rfiles, function(x) {
return(data.frame(fname = x, func = functionsFromRfile(x)))
})
对于我自己的一个包,这会导致:
> head(lutFunc2sourcefile)
fname func
1 autofitVariogram.r autofitVariogram
2 autoKrige.cv.r autoKrige.cv
3 autoKrige.cv.r checkIfautokrige.cv
4 autoKrige.cv.r compare.cv
5 autoKrige.cv.r cv.compare.bubble
6 autoKrige.cv.r cv.compare.ggplot
您可以使用查找表使用从sys.call
获得的函数名称来执行映射。
编辑:鉴于您对非功能代码的评论,此代码使用parse,它不会评估代码。它搜索解析的输出,并清除函数,不应评估任何代码或返回非函数的代码。我没有详尽地测试它,试一试。
library(plyr)
Rfiles = list.files(".", pattern = "(.R|.r)")
lutFunc2sourcefile = ldply(Rfiles, function(fname) {
f = parse(fname)
functions = sapply(strsplit(as.character(f), "="), function(l) {
if(grepl("^function", sub(' ', '', l[2]))) {
return(l[1])
} else {
return(NA)
}
})
return(data.frame(fname, func = functions))
})
# Remove lines with func = NA
lutFunc2sourcefile = lutFunc2sourcefile[!is.na(lutFunc2sourcefile$func),]
答案 1 :(得分:0)
您可以将AddSignal(signal)
修改为
AddSignal(signal, filename=NULL){
...
...
return(list(signal=signal,filename=filename))}