2012-02-14 71 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

相關問題