JorisChau/rrapply

Function skips NULLs with no option to include

Closed this issue · 2 comments

rrapply skips over lists with NULLs with no opportunity to replace the contents. Imagine I had a list with NULLs and I wanted to replace them with a single NA.

rrapply(list(NULL), \(){1}, how = "replace")
[[1]]
NULL

Consider rapply2 from rawr which allows NULLs to be skipped or not.

In fact rrapply() does not skip NULL's by default. In the given example, \(){1} has no arguments. Instead try:

library(rrapply)

rrapply(list(NULL), f = \(x) NA)
#> [[1]]
#> [1] NA

There are different ways to include/exclude NULLs when walking through a nested list. Below are several examples:

## dummy list
mylist <- list(a = 1, b = 2, c = NULL)

## apply f to all elements
rrapply(
  mylist, 
  f = \(x) if(is.null(x)) NA else x
)
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2
#> 
#> $c
#> [1] NA

## apply f to NULLs only using condition
rrapply(
  mylist, 
  condition = is.null,
  f = \(x) NA
)
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2
#> 
#> $c
#> [1] NA

## apply f skipping NULLs using condition
rrapply(
  mylist, 
  condition = Negate(is.null),
  f = \(x) x + 1
)
#> $a
#> [1] 2
#> 
#> $b
#> [1] 3
#> 
#> $c
#> NULL

## apply f to NULL using classes
rrapply(
  mylist, 
  classes = "NULL",
  f = \(x) NA
)
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2
#> 
#> $c
#> [1] NA

## apply f skipping NULLs using classes
rrapply(
  mylist, 
  classes = "numeric",
  f = \(x) x + 1
)
#> $a
#> [1] 2
#> 
#> $b
#> [1] 3
#> 
#> $c
#> NULL

## apply f using default for NULLs
rrapply(
  mylist,
  condition = Negate(is.null),
  f = \(x) x + 1,
  deflt = NA,
  how = "list"
)
#> $a
#> [1] 2
#> 
#> $b
#> [1] 3
#> 
#> $c
#> [1] NA

## apply f using default for NULLs (2)
rrapply(
  mylist,
  classes = "numeric",
  f = \(x) x + 1,
  deflt = NA,
  how = "list"
)
#> $a
#> [1] 2
#> 
#> $b
#> [1] 3
#> 
#> $c
#> [1] NA

Ah, yep - turns out that I didn't read the docs right and I was putting the function in the condition section.