2011-08-04 80 views
22

如何根據另一個列表中的條件(TRUE,FALSE)對列表進行子集劃分?請參閱我下面的例子:基於邏輯條件的列表中的子集元素

l <- list(a=c(1,2,3), b=c(4,5,6,5), c=c(3,4,5,6)) 
l 
$a 
[1] 1 2 3 

$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6 

cond <- lapply(l, function(x) length(x) > 3) 
cond 
$a 
[1] FALSE 

$b 
[1] TRUE 

$c 
[1] TRUE 

> l[cond] 

錯誤L [COND]:無效標類型 '列表'

回答

11

[期待一個矢量,所以使用unlistcond

l[unlist(cond)] 
$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6 
3
> l[as.logical(cond)] 
$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6 
20

另一種方法是用sapply代替lapply

cond <- sapply(l, function(x) length(x) > 3) 
l[cond] 
+0

這隻產生對象cond,子集的結果。 – jrara

+0

爲了澄清,現在l [cond]產生子集作爲sapply返回一個向量。編輯添加此。 – PatrickR

17

這就是Filter功能是爲製作:

Filter(function(x) length(x) > 3, l) 
$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6 
+0

簡單。 Base R.喜歡它! – CephBirk

0
cond <- lapply(l, length) > 3 
l[cond] 
0

筆者近日瞭解到lengths(),其中獲得一個列表中的每個元素的長度。這使我們可以避免在OP嘗試時製作另一個包含邏輯值的列表。

lengths(l) 
#a b c 
#3 4 4 

在邏輯條件利用這一點,我們就可以在l子集列表中的元素。

l[lengths(l) > 3] 

$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6