How to manipulate NULL elements in a nested list?

I'm going to go with "use a version of rapply doesn't doesn't have weird behaviour with NULL". This is the simplest implementation I can think of:

simple_rapply <- function(x, fn)
{
  if(is.list(x))
  {
    lapply(x, simple_rapply, fn)
  } else
  {
    fn(x)
  }
}

(rawr::rapply2, as mentioned in the comments by @rawr is a more sophisticated attempt.)

Now I can do the replacement using

simple_rapply(l, function(x) if(is.null(x)) NA else x)

This is what William Dunlap suggested in 2010 when this question was asked on Rhelp:

replaceInList <- function (x, FUN, ...) 
  {
      if (is.list(x)) {
          for (i in seq_along(x)) {
              x[i] <- list(replaceInList(x[[i]], FUN, ...))
          }
          x
      }
      else FUN(x, ...)
  }
 replaceInList(l, function(x)if(is.null(x))NA else x)

This is a hack, but as far as hacks go, I think I'm somewhat happy with it.

lna <- eval(parse(text = gsub("NULL", "NA", deparse(l))))

str(lna)
#> List of 3
#> $ : logi NA
#> $ : num 1
#> $ :List of 3
#> ..$ : num 2
#> ..$ : logi NA
#> ..$ :List of 2
#> .. ..$ : num 3
#> .. ..$ : logi NA

Update:

If for some reason you needed "NULL" as a character entry in the list (corner case, much?) you can still use the above hack since it replaces the contents of the string, not the quotes, thus it just requires another step

l2 <- list(
  NULL,
  1,
  list(
    2,
    "NULL",
    list(
      3,
      NULL
    )
  )
)

lna2   <- eval(parse(text = gsub("NULL", "NA", deparse(l2))))
lna2_2 <- eval(parse(text = gsub('\\"NA\\"', '\"NULL\"', deparse(lna2))))

str(lna2_2)
#> List of 3
#> $ : logi NA
#> $ : num 1
#> $ :List of 3
#> ..$ : num 2
#> ..$ : chr "NULL"
#> ..$ :List of 2
#> .. ..$ : num 3
#> .. ..$ : logi NA 

I wrapped the replacement inside the sapply, which makes it more readable/understandable to me, albeit less general.

 replace_null <- function(x) {
  lapply(x, function(x) {
    if (is.list(x)){
      replace_null(x)
      } else{
        if(is.null(x)) NA else(x)
      } 
    })
}

replace_null(l)

Tags:

List

R