purrr
purrr copied to clipboard
FR: Default value for `map_xxx()` when return is of lenght 0
Hi,
When you use map_xxx()
, for instance map_chr()
, the function .f
should return a value of length exactly 1.
While I agree that a value of length >1 is obviously the sign of an error, I think a value of length 0 is probably more the sign of a missing value.
Therefore, maybe we could have a .default
argument, giving the value that should be returned if .f
returns a value of length 0.
I am guessing the default should be .default="error"
for backward compatibility, although I don't think anyone is relying on such an error to build their workflow, so .default=NA
should do also.
I couldn't find a more thoughtful example than the following, but please trust me that this happens rather frequently in my experience, for instance when dealing with lookups. Here is a reprex:
library(tidyverse)
x = tibble(
df=c("iris", "mtcars"),
data=list(iris, mtcars),
nm=map(data, names)
)
x %>% mutate(id=map(nm, ~.x[nchar(.x)==7]))
#> # A tibble: 2 x 4
#> df data nm id
#> <chr> <list> <list> <list>
#> 1 iris <df [150 x 5]> <chr [5]> <chr [1]>
#> 2 mtcars <df [32 x 11]> <chr [11]> <chr [0]>
x %>% mutate(id=map_chr(nm, ~.x[nchar(.x)==7]))
#> Error in `mutate()`:
#> i In argument: `id = map_chr(nm, ~.x[nchar(.x) == 7])`.
#> Caused by error in `map_chr()`:
#> i In index: 2.
#> Caused by error:
#> ! Result must be length 1, not 0.
map_chr2 = function(.x, .f, .default=NA_character_, ...){
rtn = map(.x, .f, ...)
rtn[lengths(rtn)==0] = .default
list_c(rtn)
}
x %>% mutate(id=map_chr2(nm, ~.x[nchar(.x)==7], .default=NA))
#> # A tibble: 2 x 4
#> df data nm id
#> <chr> <list> <list> <chr>
#> 1 iris <df [150 x 5]> <chr [5]> Species
#> 2 mtcars <df [32 x 11]> <chr [11]> <NA>
Created on 2023-11-24 with reprex v2.0.2