2011-08-04 6 views
22

Jak mogę podzielić listę na podstawie warunku (TRUE, FALSE) na innej liście? Proszę zobaczyć moje przykład poniżej:Podzbiór elementów na liście na podstawie warunku logicznego.

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] 

błąd wl [dyr]: nieprawidłowy typ indeks 'list'

Odpowiedz

11

[ spodziewa się wektor, więc używaj unlist na cond:

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

Innym sposobem jest użycie sapply zamiast z lapply.

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

Spowoduje to utworzenie tylko obiektu cond, wyniku podzbioru. – jrara

+0

Aby wyjaśnić, l [cond] teraz produkuje podzbiór, ponieważ sapply zwraca wektor. Edytowane w celu dodania tego. – PatrickR

17

To właśnie funkcja Filter powstał dla:

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

$c 
[1] 3 4 5 6 
+0

Proste. Base R. Podoba Ci się! – CephBirk

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

Niedawno dowiedziałem lengths(), pobierającą długość każdego elementu listy. To pozwala nam uniknąć tworzenia kolejnej listy zawierającej wartości logiczne, jak próbował OP.

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

Używanie tego w stanie logicznej, możemy podzbioru elementów listy w l.

l[lengths(l) > 3] 

$b 
[1] 4 5 6 5 

$c 
[1] 3 4 5 6