2012-11-28 29 views
3

或者把它放得更一般:我怎樣才能給列表元素添加多個屬性?如何使用attr < - 與lapply?

我被困在試圖設置一個屬性列表中的元素,所有這些都是data.frames。最後,我想添加names(myList)作爲不同的屬性,每個data.frame裏面。但我甚至無法獲得所有列表元素的靜態屬性。

lapply(myList,attr,which="myname") <- "myStaticName" 

這不起作用,因爲lapplylapply<-工作。如果我至少有一個想法如何做到這一點,也許我可以弄清楚如何使用不同的屬性,如列表的名稱。

回答

4

我不推薦它,但你可以這樣做:lapply(myList, 'attr<-', which='myname', value='myStaticName')。一個老式的for循環可能是執行這個任務的最明確的方式 - 或者在創建對象時向上遊執行此任務。

for (i in seq_along(myList)) attr(myList[[i]], 'myname') <- 'myStaticName' 

編輯:

如@mnel評價指出,setattrdata.table包也一個有效的選項,因爲它分配由參考。

編輯:@mnel - 不要與lapply一起使用setattr。這是for循環快得多的一種情況。

library(microbenchmark) 
library(data.table) 
myList <- as.list(1:10000) 

`lapply.attr<-` <- 
    function() 
    lapply(myList, 'attr<-', which='myname', value='myStaticName') 

`for.attr<-` <- 
    function() 
    for (i in seq_along(myList)) 
     attr(myList[[i]], 'myname') <- 'myStaticName' 

lapply.setattr <- 
    function() 
    lapply(myList, setattr, name='myname', value='myStaticName') 

for.setattr <- function() 
    for (i in seq_along(myList)) 
    setattr(myList[[i]], name = 'myname', value = 'myStaticName') 

result <- microbenchmark(`lapply.attr<-`(), `for.attr<-`(), lapply.setattr(), for.setattr()) 
plot(result) 

enter image description here

+0

+1,喜歡你的編輯,謝謝。比我的快。你爲什麼不推薦它?僅僅因爲它沒有性能問題,而且更透明? –

+0

@ hans0l0是的,我不認爲第一眼看起來這個叫'lapply'的結果是顯而易見的。我想這取決於誰在維護你的代碼。在R中編寫混淆代碼非常容易。我認爲額外的輸入有時候值得清晰。 –

+1

您也可以使用'data.table'或'bit'包中的'setattr',它將通過引用來設置屬性,因此基本上是瞬時的。 – mnel

0

在此基礎上answer by Thierry我發現我自己的解決方案。其實我已經接近幾次嘗試,但沒有返回關鍵的全部列表。

myList <- lapply(names(myList),function(X){ 
attr(myList[[X]],"myname") <- X 
myList[[X]] 
}) 

我的錯誤不是要返回整個列表,而只是返回函數的第二行,即屬性。因此我無法取代最初的名單。奇怪:你的基準測試在我的機器上看起來有些不同:RStudio,OS X,2.5 Ghz Intel Core i7,16GB RAM。 enter image description here