删除NULL元素并从R中的嵌套列表中取消列出本地级别列表

use*_*497 10 r

假设我有一个列表,说它有三个级别:

tmp =list(list(list(c(2,9,10), NULL), c(1,3,4,6)), 7) 
Run Code Online (Sandbox Code Playgroud)

这会输出

[[1]]
[[1]][[1]] 
[[1]][[1]][[1]]
[1]  2  9 10

[[1]][[1]][[2]]
NULL

[[1]][[2]]
[1] 1 3 4 6

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

我想删除NULL元素和列表的本地级别.即,嵌套列表tmp只有2个级别,它就变成了

tmp =list(list(c(2,9,10), c(1,3,4,6)), 7). 
Run Code Online (Sandbox Code Playgroud)

也就是说,所需的输出可能如下:

tmp
[[1]]
[[1]][[1]]
[1]  2  9 10

[[1]][[2]]
[1] 1 3 4 6

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

我试图搜索NULL的索引位置,但没有运气.此外,我不知道如何检测和取消列表列表中包含NULL元素的列表.谢谢!

Bea*_*eld 16

通常,您使用删除NULL平面列表中的元素

ll <- list( 1, 2, NULL, 3 )
ll <- ll[ ! sapply(ll, is.null) ]
Run Code Online (Sandbox Code Playgroud)

如果您事先不知道结构,那么将此解决方案与递归函数相结合是一个明显的例子:

removeNullRec <- function( x ){  
  x <- x[ !sapply( x, is.null ) ]
  if( is.list(x) ){
    x <- lapply( x, removeNullRec)
  }
  return(x)
}

removeNullRec(tmp)

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1]  2  9 10


[[1]][[2]]
[1] 1 3 4 6


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

编辑

尽可能简单地重新解决问题总是好的.我从你的评论中理解的是,NULL你想要替换孩子本身只包含一个孩子的每个元素(独立于元素的出现).还有另一个案例需要考虑:两个兄弟叶子也可以NULL.所以让我们从一个更复杂的例子开始:

在此输入图像描述

tree <- list(
  list(
    list(
      list(
        list( NULL, NULL ),
        list( NULL, NULL )
      ),
      7
    ),
    list(
      list(
        list( c(1,2), NULL ),
        c(3,4)
))))
Run Code Online (Sandbox Code Playgroud)

通过应用递归方法,当然也解决了使树平坦化的这个孤立问题:

flatTreeRec <- function( x ){
  if( is.list(x) ){
    # recursion
    x <- lapply( x, flatTree )
    # remove empty branches
    x <- x[ sapply( x, length ) > 0 ]
    # flat branches with only child
    if( length(x) == 1 ){
      x <- x[[1]]
    }
  }
  return(x)
}

flatTreeRec( removeNullRec(tree) )
Run Code Online (Sandbox Code Playgroud)

当然,您可以直接组合这两个函数,以避免对堆栈施加两次压力:

removeNullAndFlatTreeRec <- function( x ){  
  x <- x[ !sapply( x, is.null ) ]
  if( is.list(x) ){
    x <- lapply( x, removeNullRec)
    x <- x[ sapply( x, length ) > 0 ]
    if( length(x) == 1 ){
      x <- x[[1]]
    }
  }
  return(x)
}

removeNullAndFlatTreeRec( tree )
Run Code Online (Sandbox Code Playgroud)