2015-10-07 16 views
14
mylist <- list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
    123, NULL, 456) 

> mylist 
[[1]] 
NULL 

[[2]] 
NULL 

[[3]] 
NULL 

[[4]] 
NULL 

[[5]] 
NULL 

[[6]] 
NULL 

[[7]] 
NULL 

[[8]] 
NULL 

[[9]] 
NULL 

[[10]] 
NULL 

[[11]] 
[1] 123 

[[12]] 
NULL 

[[13]] 
[1] 456 

Moja lista zawiera 13 elementów, z których 11 ma wartość NULL. Chciałbym je usunąć, ale zachować indeksy elementów, które są niepuste.R: usuwanie elementów NULL z listy

mylist2 = mylist[-which(sapply(mylist, is.null))] 
> mylist2 
[[1]] 
[1] 123 

[[2]] 
[1] 456 

Usuwa NULL elementy dobrze, ale nie chcę elementy niepuste być przeindeksowane, tj chcę mylist2 aby wyglądać tak, gdzie indeksy niepustych wpisy są zachowane.

> mylist2 
[[11]] 
[1] 123 

[[13]] 
[1] 456 
+0

Ktoś może znaleźć sposób, ale myślę, że wpadasz w pułapkę "Dlaczego to jest drukowanie w ten sposób". Te numery indeksów nie są nazwami elementów listy. Nie ma nazw. Sprawdź 'names (mylist)'. Są po prostu pomocnikami pokazującymi, gdzie na liście znajdują się pierwiastki. Właśnie dlatego masz problem z nakazaniem R, aby zwrócił 11 pozycję listy z tylko dwoma elementami. Możesz spróbować nazwać listę jako odpowiedź poniżej. –

Odpowiedz

24

Najbliżej będziesz w stanie dostać się do pierwszej nazwy elementów listy, a następnie usunąć wartości null.

names(x) <- seq_along(x) 

## Using some higher-order convenience functions 
Filter(Negate(is.null), x) 
# $`11` 
# [1] 123 
# 
# $`13` 
# [1] 456 

# Or, using a slightly more standard R idiom 
x[sapply(x, is.null)] <- NULL 
x 
# $`11` 
# [1] 123 
# 
# $`13` 
# [1] 456 
4

Jeśli chcesz zachować nazwy można zrobić

a <- list(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
      123, NULL, 456) 
non_null_names <- which(!sapply(a, is.null)) 
a <- a[non_null_names] 
names(a) <- non_null_names 
a 

Następnie można uzyskać dostęp do elementów jak tak

a[['11']] 
num <- 11 
a[[as.character(num)]] 
a[[as.character(11)]] 
a$`11` 

Nie można dostać je w schludne [[11]], [[13]] notacja, ponieważ reprezentują one indeksy numeryczne.

+0

To jest najbliższe temu, co chcesz, ale) –

2

Oto ona z notacją wygodne łańcuchowym

library(magrittr) 

mylist %>% 
    setNames(seq_along(.)) %>% 
    Filter(. %>% is.null %>% `!`, .) 
+6

'Filtr (Negate (is.null), setNames (L, seq_along (L)))' jest dość łatwy do odczytania. – thelatemail

+0

Ok, poprawiono problem. Neguj! = '!' – bramtayl

2

Jest to funkcja, która automatycznie usuwa wszystkie wpisy z zerową listą, a jeśli lista jest nazwany, zachowuje nazwy niż null wpisów. Ta funkcja nazywa się compact z pakietu plyr.

l <- list(NULL, NULL, foo, bar) 
names(l) <- c("one", "two", "three", "four") 

plyr::compact(l) 

Jeśli chcesz zachować indeksy niż null wpisów, można wymienić listę jak to się robi w post przed i potem Kondensowanie listę:

names(l) <- seq_along(l) 
plyr::compact(l) 
Powiązane problemy