2012-02-14 39 views
3

我有几个R脚本文件,例如f1.Rf2.R,f3.R如何获取R脚本文件名称时调用其中的函数?

我有另一个叫做AddSignal(signal)的函数,它将一个信号向量添加到列表中。 f1.R,f2.R等函数可能会调用此AddSignal()函数。

现在我想要的是,在函数AddSignal()中,除了添加信号部分外,它还会记录哪个函数在哪个R文件中进行调用。例如,我想知道f1.R添加信号sig1中的函数ff1()。

有没有办法做到这一点?其实,使用sys.call(),我可以知道调用了AddSignal()函数(例如ff1())。但我不知道ff1()在哪个R文件中。我可以看到一个很难的方法,就是扫描所有.R文件,然后存储文件名和函数名称的映射。但我想看看是否有更简单的方法。

谢谢。

+0

你是什么意思的函数调用GetFileName?你的意思是你想把你的函数作为参数传递给GetFileName? – Dason 2012-02-14 06:47:15

+1

你可以加入你对此问题的理由吗?这听起来相当奇特你想要的,也许我们可以建议一个替代方案... – 2012-02-14 06:49:02

+0

相关问题:http://stackoverflow.com/questions/9132150/returning-directory-of-containing-file – 2012-02-14 06:50:11

回答

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),] 
+0

感谢您的回答!我的R文件实际上是在一个库中。我想知道图书馆是否有更简单的方法。 – danioyuan 2012-02-15 20:28:37

+0

在库中,所有函数都在/ R子目录中。只需将list.files指向该目录并完成即可。请注意,如果在当前工作目录以外的任何其他目录中使用list.files,请使用full.names = TRUE。 – 2012-02-15 22:00:11

+0

谢谢。唯一的担心是某些文件可能有可运行的代码,而不仅仅是函数。然后,采购他们会做一些事情,或更多的关注,它可能需要未知的时间跑步或给出错误。 – danioyuan 2012-02-15 23:59:13

相关问题