R:从列表中删除NULL元素

Adr*_*ian 44 r

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
Run Code Online (Sandbox Code Playgroud)

我的列表有13个元素,其中11个是NULL.我想删除它们,但保留非空元素的索引.

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

[[2]]
[1] 456
Run Code Online (Sandbox Code Playgroud)

这很好地删除了NULL元素,但是我不希望非空元素被重新索引,即,我想mylist2看起来像这样,其中非空条目的索引被保留.

> mylist2
[[11]]
[1] 123

[[13]]
[1] 456
Run Code Online (Sandbox Code Playgroud)

Jos*_*ien 69

您能够获得的最接近的是首先命名列表元素,然后删除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
Run Code Online (Sandbox Code Playgroud)

  • 或 `x &lt;- x[!sapply(x,is.null)]` (13认同)
  • @xm1 的答案更好,因为右侧表达式返回不带 NULL 的列表,因此可以写入像这样的便利函数:remove_null_lst &lt;- function(x) x[!sapply(x, is.null)] ` (2认同)

小智 26

Tidyverse 中purrr包含的包具有用于处理列表的优雅且快速的功能:

require(tidyverse)

# this works
compact(mylist)

# or this
mylist %>% discard(is.null)

# or this
# pipe "my_list" data object into function "keep()", make lambda function inside "keep()" to return TRUE FALSE.
mylist %>% keep( ~ !is.null(.) )

Run Code Online (Sandbox Code Playgroud)

以上所有选项均来自 Purrr。输出是:

[[1]] 
[1] 123

[[2]] 
[1] 456
Run Code Online (Sandbox Code Playgroud)

注意:compact() 在 plyr 中,但 dplyr 取代了 plyr,并且 compact() 留在了,但移到了 purrr。无论如何,所有功能都在父包 tidyverse 中。



这是 Purrr 备忘单下载的链接:

https://rstudio.com/resources/cheatsheets/

或者直接在浏览器中查看 Purrr 备忘单:

https://evoldyn.gitlab.io/evomics-2018/ref-sheets/R_purrr.pdf


Dav*_*res 22

有一个函数可以自动删除列表的所有空条目,如果列表已命名,则它会维护非空条目的名称.

compact从包中调用此函数plyr.

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

plyr::compact(l)
Run Code Online (Sandbox Code Playgroud)

如果要保留非空条目的索引,可以在列表中对列表进行命名,然后压缩列表:

names(l) <- seq_along(l)
plyr::compact(l)
Run Code Online (Sandbox Code Playgroud)

  • 为了完整性:purrr :: compact()似乎做同样的工作. (7认同)

F. *_*ivé 12

简单地做mylist[lengths(mylist) != 0].


Ada*_*man 6

此解决方案也适用于嵌套列表

rlist::list.clean(myNestedlist ,recursive = T)
Run Code Online (Sandbox Code Playgroud)


Fel*_*ard 5

如果你想保留你可以做的名字

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
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问这样的元素

a[['11']]
num <- 11
a[[as.character(num)]]
a[[as.character(11)]]
a$`11`
Run Code Online (Sandbox Code Playgroud)

你不能让他们在整齐[[11]],[[13]]符号,但是,因为这些代表数值指标.


bra*_*ayl 5

这是方便的链接符号

library(magrittr)

mylist %>%
  setNames(seq_along(.)) %>%
  Filter(. %>% is.null %>% `!`, .)
Run Code Online (Sandbox Code Playgroud)

  • `Filter(Negate(is.null), setNames(L,seq_along(L)))` 非常容易阅读。 (7认同)