如何从R中的列表列表中删除null元素,如下所示:
lll <- list(list(NULL),list(1),list("a"))
Run Code Online (Sandbox Code Playgroud)
我想要的对象看起来像:
lll <- list(list(1),list("a"))
Run Code Online (Sandbox Code Playgroud)
我在这里看到了类似的答案:如何从列表中删除元素?但无法将其从简单列表扩展到列表列表.
编辑
我上面的错误例子.这两个答案都适用于更简单的案例(上图).如果列表如下:
lll <- list(list(NULL),list(1,2,3),list("a","b","c"))
Run Code Online (Sandbox Code Playgroud)
如何获得:
lll <- list(list(1,2,3),list("a","b","c"))
Run Code Online (Sandbox Code Playgroud)
Jos*_*ien 26
这种递归解决方案具有处理更深层嵌套列表的优点.
它与Gabor Grothendieck对这个非常相似的问题的答案密切相关.如果函数还要删除您想要的对象list(NULL)(不相同NULL),则需要修改该代码.
## A helper function that tests whether an object is either NULL _or_
## a list of NULLs
is.NullOb <- function(x) is.null(x) | all(sapply(x, is.null))
## Recursively step down into list, removing all such objects
rmNullObs <- function(x) {
x <- Filter(Negate(is.NullOb), x)
lapply(x, function(x) if (is.list(x)) rmNullObs(x) else x)
}
rmNullObs(lll)
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
Run Code Online (Sandbox Code Playgroud)
以下是其应用于更深层嵌套列表的示例,其他当前提出的解决方案在其中各种失败.
LLLL <- list(lll)
rmNullObs(LLLL)
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [[1]][[1]][[1]][[1]]
# [1] 1
#
#
# [[1]][[1]][[2]]
# [[1]][[1]][[2]][[1]]
# [1] "a"
Run Code Online (Sandbox Code Playgroud)
Dav*_*urg 21
这是一个使用Filter和Negate组合的选项
Filter(Negate(function(x) is.null(unlist(x))), lll)
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
Run Code Online (Sandbox Code Playgroud)
对于此特定示例,您还可以使用unlist其recursive参数.
lll[!sapply(unlist(lll, recursive=FALSE), is.null)]
# [[1]]
# [[1]][[1]]
# [1] 1
#
#
# [[2]]
# [[2]][[1]]
# [1] "a"
Run Code Online (Sandbox Code Playgroud)
运用 purrr
purrr::map(lll, ~ purrr::compact(.)) %>% purrr::keep(~length(.) != 0)
[[1]]
[[1]][[1]]
[1] 1
[[1]][[2]]
[1] 2
[[1]][[3]]
[1] 3
[[2]]
[[2]][[1]]
[1] "a"
[[2]][[2]]
[1] "b"
[[2]][[3]]
[1] "c"
Run Code Online (Sandbox Code Playgroud)
由于列表中有列表,因此您可能需要运行l/sapply两次,例如:
lll[!sapply(lll,sapply,is.null)]
#[[1]]
#[[1]][[1]]
#[1] 1
#
#
#[[2]]
#[[2]][[1]]
#[1] "a"
Run Code Online (Sandbox Code Playgroud)
小智 5
感谢Kun Ren使我们的生活更轻松,CRAN上有一个新的软件包列表。
list.clean(.data, fun = is.null, recursive = FALSE)
Run Code Online (Sandbox Code Playgroud)
或递归删除NULL:
list.clean(.data, fun = is.null, recursive = TRUE)
Run Code Online (Sandbox Code Playgroud)