Search code examples
rpurrr

Using map_dfr() with list of dates


Is there a way to use purrr::map_dfr() to run a function on a list of dates of varying lengths/missingness?

So far, I am able to do this with map, then enframe, then unnest:

library(tidyverse)

date_list <- list(as.Date('2020-01-01'),
     c(as.Date('2021-01-01'), as.Date('2021-06-01')),
     NA_Date_,
     c(as.Date('2022-01-01'), as.Date('2022-08-01')),
     as.Date('2023-01-01')) 

map(date_list, max) |> 
  enframe(value = "latest") |> 
  unnest(cols = "latest") |>
  select(latest)
#> # A tibble: 5 × 1
#>   latest    
#>   <date>    
#> 1 2020-01-01
#> 2 2021-06-01
#> 3 NA        
#> 4 2022-08-01
#> 5 2023-01-01

However, using the more concise map_dfr returns the following error:

map_dfr(date_list, max, .id = "latest")
#> Error in `dplyr::bind_rows()`:
#> ! Argument 1 must be a data frame or a named atomic vector.
#> Backtrace:
#>     ▆
#>  1. └─purrr::map_dfr(date_list, max, .id = "latest")
#>  2.   └─dplyr::bind_rows(res, .id = .id)
#>  3.     └─rlang::abort(glue("Argument {i} must be a data frame or a named atomic vector."))

Created on 2023-04-18 with reprex v2.0.2


Solution

  • Do you want purrr::map_vec()?

    library(purrr)
    
    date_list <- list(
      as.Date('2020-01-01'),
      c(as.Date('2021-01-01'), as.Date('2021-06-01')),
      lubridate::NA_Date_,
      c(as.Date('2022-01-01'), as.Date('2022-08-01')),
      as.Date('2023-01-01')
    ) 
    
    map_vec(date_list, max)
    #> [1] "2020-01-01" "2021-06-01" NA           "2022-08-01" "2023-01-01"
    
    tibble::tibble(latest = map_vec(date_list, max))
    #> # A tibble: 5 × 1
    #>   latest    
    #>   <date>    
    #> 1 2020-01-01
    #> 2 2021-06-01
    #> 3 NA        
    #> 4 2022-08-01
    #> 5 2023-01-01
    

    Created on 2023-04-18 with reprex v2.0.2.9000