2011-05-09 98 views
9

我經常遇到需要爲不同變量創建大量類似模型的情況。通常我將它們轉儲到列表中。下面是僞代碼的例子:訪問R中列表中的列表中的同名列表元素

modlist <- lapply(1:10,function(l) { 
    data <- data.frame(Y=rnorm(10),X=rnorm(10)) 
    lm(Y~.,data=data) 
}) 

現在獲得適合的例子很簡單:

lapply(modlist,predict) 

我想有時做的是從列表中提取一個元素。顯而易見的方法是

sapply(modlist,function(l)l$rank) 

這就是我想要的,但我不知道是否有一個較短的方法來獲得相同的結果?

+0

示例代碼返回一個錯誤的一個版本。 – 2011-05-09 11:11:50

+0

@Joris,它是一個虛擬代碼,原則上它不應該工作,因爲'simulate'沒有被定義。但是,大寫的'C'出錯了。感謝您指出。 – mpiktas 2011-05-09 12:34:20

+3

我明白了。但是,人們會假設你的虛擬代碼運行,並且一個最小可重現的例子通常是一個小的努力來解釋一個問題。它避免了我們必須讓自己在尋找答案。 – 2011-05-09 12:37:06

回答

14

我通常使用kohske way,但這裏有另一個竅門:

sapply(modlist, with, rank) 

當你需要更多的元素,例如:

sapply(modlist, with, c(rank, df.residual)) 

我記得我偷了從哈德利(從plyr文檔我認爲)這是比較有用的。

+2

感謝,這當然感覺像@哈代碼,簡單而優雅。 – mpiktas 2011-05-09 12:40:35

+0

@mpiktas''[''''和'with'解決方案之間的主要區別在於缺少元素。 '「[[」'元素丟失時返回'NULL'。 '用'拋出一個錯誤**,除非在全局工作空間中存在一個名稱與搜索元素**相同的對象。所以例如'dah <-1;當modlist沒有任何'dah'元素時,lapply(modlist,with,dah)'返回一個列表。 – Marek 2011-05-10 21:19:40

+0

感謝您的補充評論。在我的情況下,列表中的元素不應該有任何缺失的元素,所以錯誤是值得歡迎的。 – mpiktas 2011-05-11 05:59:04

24

可能這些都有點簡單:

> z <- list(list(a=1, b=2), list(a=3, b=4)) 
> sapply(z, `[[`, "b") 
[1] 2 4 
> sapply(z, get, x="b") 
[1] 2 4 

,你可以這樣定義一個函數:

> `%c%` <- function(x, n)sapply(x, `[[`, n) 
> z %c% "b" 
[1] 2 4 

而且這就像是$擴展:

> `%$%` <- function(x, n) sapply(x, `[[`, as.character(as.list(match.call())$n)) 
> z%$%b 
[1] 2 4 
+1

謝謝,我認爲這應該是可能的。這是一個可惜我不能接受這兩個答案,我選擇@Marek純粹是出於美學原因的答案。我贊成你的。 – mpiktas 2011-05-09 12:39:09

1

隨着哈德利的新lowliner包,您可以提供map()數字索引或元素名稱優雅地從列表中拔出組件。 map()相當於lapply()有一些額外的技巧。

library("lowliner") 

l <- list(
    list(a = 1, b = 2), 
    list(a = 3, b = 4) 
) 

map(l, "b") 
map(l, 2) 

還有,簡化了結果的向量使用foreach包時

map_v(l, "a") 
map_v(l, 1)