Remove the NULL element and list the local level list from the nested list in R

Suppose I have a list, let's say it has three levels:

tmp =list(list(list(c(2,9,10), NULL), c(1,3,4,6)), 7) 

This will lead to the conclusion

 [[1]] [[1]][[1]] [[1]][[1]][[1]] [1] 2 9 10 [[1]][[1]][[2]] NULL [[1]][[2]] [1] 1 3 4 6 [[2]] [1] 7 

I would like to remove the NULL element and the local level of the list. those. the nested tmp list has only 2 levels and becomes

 tmp =list(list(c(2,9,10), c(1,3,4,6)), 7). 

That is, the desired result will be either the following:

 tmp [[1]] [[1]][[1]] [1] 2 9 10 [[1]][[2]] [1] 1 3 4 6 [[2]] [1] 7 

I tried to find the index position NULL, but no luck. Also, I'm not sure how to find and list a list containing a NULL element in a list. Thanks!

+7
r
source share
2 answers

Typically, you remove NULL items in a flat list with

 ll <- list( 1, 2, NULL, 3 ) ll <- ll[ ! sapply(ll, is.null) ] 

If you do not know the structure in advance, this is an obvious case to combine this solution with a recursive function:

 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 

Edit

It is always helpful to rephrase the problem as simple as possible. From your comments, I realized that (regardless of the appearance of NULL elements), you want to replace each element containing only one child with the child itself. There is also another case that should be considered then: two sister sheets may be NULL . So let's start with a slightly more complex example:

enter image description here

 tree <- list( list( list( list( list( NULL, NULL ), list( NULL, NULL ) ), 7 ), list( list( list( c(1,2), NULL ), c(3,4) )))) 

This isolated problem for a flat tree, of course, is also better solved by applying a recursive approach:

 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) ) 

And, of course, you can directly combine these two functions to avoid the stress of your stack twice:

 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 ) 
+13
source share

I am using this function:

 removeNULL <- function(x){ x <- Filter(Negate(is.null), x) if( is.list(x) ){ x <- lapply( x, function(y) Filter(length, removeNULL(y))) } return(x) } 

Not only does it delete NULL elements, but it also removes elements that are a list containing only NULL elements, such as A2$A2$format$font in the example below:

 > A2 $A2 $A2$value [1] 9.9 $A2$format $A2$format$numberFormat [1] "2Decimal" $A2$format$font $A2$format$font$name NULL $A2$format$font$bold NULL $A2$format$font$color NULL $A2$comment NULL > removeNULL(A2) $A2 $A2$value [1] 9.9 $A2$format $A2$format$numberFormat [1] "2Decimal" 
0
source share

All Articles