映射 returns 列表而不是日期

Map returns lists instead of dates

我有一个包含日期的 tibble 列,我想将它们与日期列表中最近的较高日期相匹配。因此我写了一个函数 matchDate,我想用 map:

调用它
library(tidyverse)

d1 = as.Date("2022-01-01")
d2 = as.Date("2022-12-31")

matchDate = function(date,matchDates,...){
  matchDates[matchDates >= date] %>% min %>% return
}

df = tibble(date = seq.Date(from=d1,to=d2,by='months'))
dates = seq.Date(from=d2,to=d1,by='-3 months')
df$match = map(df$date,~matchDate(.x,matchDates=dates))

typeof(matchDate(d1,dates))
#> [1] "double"

df
#> # A tibble: 12 x 2
#>    date       match     
#>    <date>     <list>    
#>  1 2022-01-01 <date [1]>
#>  2 2022-02-01 <date [1]>
#>  3 2022-03-01 <date [1]>
#>  4 2022-04-01 <date [1]>
#>  5 2022-05-01 <date [1]>
#>  6 2022-06-01 <date [1]>
#>  ...

reprex package (v2.0.1)

于 2022-05-30 创建

不确定为什么 typeof returns double 在这里,但函数工作正常并且 map 也 returns 正确的日期。唯一的事情是,它将它们包装成一个列表(长度为一)。我尝试在我的代码中的不同位置添加 unlist,但它没有改变任何东西。有人可以解释发生了什么,或者如何正确取消列出吗?非常感谢!

如果我们不指定列类型的后缀,默认情况下 map return 是 list,即 _int_dbl _chr 等到 return 一个 vector。使用 Date class 它有点复杂,因为存储模式是 integer/double 并且这可能会强制转换为它的整数存储值

library(purrr)
library(dplyr)
df$match <- map(df$date,~matchDate(.x,matchDates=dates)) %>% 
     invoke(c,.)

-输出

> df
# A tibble: 12 × 2
   date       match     
   <date>     <date>    
 1 2022-01-01 2022-03-31
 2 2022-02-01 2022-03-31
 3 2022-03-01 2022-03-31
 4 2022-04-01 2022-07-01
 5 2022-05-01 2022-07-01
 6 2022-06-01 2022-07-01
 7 2022-07-01 2022-07-01
 8 2022-08-01 2022-10-01
 9 2022-09-01 2022-10-01
10 2022-10-01 2022-10-01
11 2022-11-01 2022-12-31
12 2022-12-01 2022-12-31

有了base R,我们可以用do.callc

do.call("c", map(df$date,~matchDate(.x,matchDates=dates)))
 [1] "2022-03-31" "2022-03-31" "2022-03-31" "2022-07-01" "2022-07-01" "2022-07-01" "2022-07-01" "2022-10-01" "2022-10-01" "2022-10-01"
[11] "2022-12-31" "2022-12-31"