purrr icon indicating copy to clipboard operation
purrr copied to clipboard

FR: Default value for `map_xxx()` when return is of lenght 0

Open DanChaltiel opened this issue 7 months ago • 0 comments

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

DanChaltiel avatar Nov 24 '23 16:11 DanChaltiel