[英]R: removing NULL elements from a list
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
My list has 13 elements, 11 of which are NULL.我的列表有 13 个元素,其中 11 个为 NULL。 I would like to remove them, but preserve the indices of the elements that are nonempty.我想删除它们,但保留非空元素的索引。
mylist2 = mylist[-which(sapply(mylist, is.null))]
> mylist2
[[1]]
[1] 123
[[2]]
[1] 456
This removes the NULL elements just fine, but I don't want the nonempty elements to be reindexed, ie, I want mylist2
to look something like this, where the indices of the nonempty entries are preserved.这很好地删除了 NULL 元素,但我不希望重新索引非空元素,即,我希望mylist2
看起来像这样,其中保留了非空条目的索引。
> mylist2
[[11]]
[1] 123
[[13]]
[1] 456
The closest you'll be able to get is to first name the list elements and then remove the NULLs.最接近的是首先命名列表元素,然后删除 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
Simply use mylist[lengths(mylist) != 0]
.只需使用mylist[lengths(mylist) != 0]
。
Function lengths()
was introduced in R 3.2.0 (April 2015).函数lengths()
是在 R 3.2.0(2015 年 4 月)中引入的。
There's a function that automatically removes all the null entries of a list, and if the list is named, it maintains the names of the non-null entries.有一个函数可以自动删除列表的所有空条目,如果列表被命名,它会维护非空条目的名称。
This function is called compact
from the package plyr
.这个函数被称为compact
包plyr
。
l <- list( NULL, NULL, foo, bar)
names(l) <- c( "one", "two", "three", "four" )
plyr::compact(l)
If you want to preserve the indexes of the non-null entries, you can name the list as it is done in the post before and then compact your list:如果您想保留非空条目的索引,您可以像之前在帖子中所做的那样命名列表,然后压缩您的列表:
names(l) <- seq_along(l)
plyr::compact(l)
The purrr
package, included in Tidyverse , has elegant and fast functions for working with lists:该purrr
包,包含在Tidyverse,对处理列表优雅和快速的功能:
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(.) )
All above options are from Purrr.以上所有选项均来自 Purrr。 Output is:输出是:
[[1]]
[1] 123
[[2]]
[1] 456
Note: compact() was in plyr, but dplyr superseded plyr, and compact() stayed around but moved to purrr.注意:compact() 在 plyr 中,但 dplyr 取代了 plyr,并且 compact() 留在了,但移到了 purrr。 Anyway, all the functions are within the parent package tidyverse.无论如何,所有功能都在父包 tidyverse 中。
Here's a link to the Purrr cheat sheet download:这是 Purrr 备忘单下载的链接:
https://rstudio.com/resources/cheatsheets/ https://rstudio.com/resources/cheatsheets/
Or to view the Purrr cheatsheet directly in a browser:或者直接在浏览器中查看 Purrr 备忘单:
https://evoldyn.gitlab.io/evomics-2018/ref-sheets/R_purrr.pdf https://evoldyn.gitlab.io/evomics-2018/ref-sheets/R_purrr.pdf
此解决方案也适用于嵌套列表
rlist::list.clean(myNestedlist ,recursive = T)
If you want to keep the names you can do如果你想保留你可以做的名字
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
You can then access the elements like so然后您可以像这样访问元素
a[['11']]
num <- 11
a[[as.character(num)]]
a[[as.character(11)]]
a$`11`
You can't get them in the neat [[11]]
, [[13]]
notation, though, because those represent numerical indices.但是,您无法以简洁的[[11]]
、 [[13]]
符号表示它们,因为它们代表数字索引。
Here it is with convenient chaining notation这是使用方便的链接符号
library(magrittr)
mylist %>%
setNames(seq_along(.)) %>%
Filter(. %>% is.null %>% `!`, .)
here's a very simple way to do it using only base R functions:这是仅使用基本 R 函数的一种非常简单的方法:
names(mylist) <- 1:length(mylist)
mylist2 <- mylist[which(!sapply(mylist, is.null))]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.