2015-10-07 25 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 

Danh sách của tôi có 13 phần tử, 11 trong số đó là NULL. Tôi muốn loại bỏ chúng, nhưng vẫn giữ nguyên các chỉ số của các phần tử không trống.R: xóa phần tử NULL khỏi danh sách

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

[[2]] 
[1] 456 

này loại bỏ các yếu tố NULL tốt, nhưng tôi không muốn các yếu tố không rỗng được lập chỉ mục, tức là, tôi muốn mylist2 để trông giống như thế này, nơi mà các chỉ số của các mục không rỗng được bảo toàn.

> mylist2 
[[11]] 
[1] 123 

[[13]] 
[1] 456 
+0

Ai đó có thể tìm thấy một cách, nhưng tôi nghĩ rằng bạn đang rơi vào cái bẫy "Tại sao nó in theo cách đó". Các số chỉ mục này không phải là tên của các phần tử danh sách của bạn. Không có tên. Kiểm tra 'tên (danh sách của tôi)'. Vì vậy, họ chỉ là những người trợ giúp cho thấy vị trí trong danh sách các yếu tố. Đó là lý do tại sao bạn gặp khó khăn khi yêu cầu R trả lại vị trí thứ 11 của danh sách chỉ với hai phần tử. Bạn có thể thử đặt tên cho danh sách dưới dạng câu trả lời bên dưới. –

Trả lời

24

Gần nhất bạn sẽ có thể nhận được là đầu tiên đặt tên cho nguyên tố danh sách và sau đó loại bỏ các NULLs.

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

Nếu bạn muốn giữ lại những cái tên bạn có thể làm

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 

Sau đó, bạn có thể truy cập vào các yếu tố như vậy

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

Bạn không thể có được chúng trong gọn gàng [[11]], Tuy nhiên, ký hiệu [[13]] vì các ký hiệu đại diện cho các chỉ số bằng số.

+0

Đây là gần nhất với những gì bạn muốn mà thực sự có thể được thực hiện mặc dù :) –

2

Dưới đây là với ký hiệu chaining thuận tiện

library(magrittr) 

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

'Bộ lọc (Negate (is.null), setNames (L, seq_along (L)))' là khá dễ dàng để đọc. – thelatemail

+0

Ok, đã khắc phục sự cố. Bỏ qua! = '!' – bramtayl

2

Có chức năng tự động xóa tất cả các mục nhập rỗng của danh sách và nếu danh sách được đặt tên, nó sẽ duy trì tên của các mục nhập không rỗng.

Chức năng này được gọi là compact từ gói plyr.

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

plyr::compact(l) 

Nếu bạn muốn duy trì các chỉ số của các mục không null, bạn có thể đặt tên cho danh sách vì nó được thực hiện trong các bài trước và sau đó compact danh sách của bạn:

names(l) <- seq_along(l) 
plyr::compact(l) 
Các vấn đề liên quan