`purrr::map` 到任何类型

`purrr::map` to any type

有没有办法映射到 purrr::map

的任何类型
library(tidyverse)
library(lubridate)

df <- data_frame(id = c(1, 1, 1, 2, 2, 2), 
                 val = c(1, 2, 3, 1, 2, 3), 
                 date = ymd("2017-01-01") + days(1:6))

df1 <- df %>% nest(-id) %>% 
  mutate(first_val = map_dbl(data, ~ .$val[1]), 
         first_day = map(data, ~ .$date[1]))

我希望 first_day 成为 <date> 类型的列,如 df 中那样。我试过 flatten,但这不起作用,因为它将列强制为数字。

purrr 是类型稳定的,这需要一些时间来适应。

在这种情况下,它 returns 一个您期望 <date>.

的列表

一个简单且 "stable" 的解决方案是将第二个 map 替换为 map_dbl 并将输出返回到 <date> 对象使用lubridateas_date,像这样:

df3 <- df %>% nest(-id) %>% 
   mutate(first_val = map_dbl(data, ~ .$val[1]), 
          first_day = as_date(map_dbl(data, ~ .$date[1])))

你得到:

# A tibble: 2 × 4
  id             data                 first_val  first_day
 <dbl>          <list>                  <dbl>     <date>
 1              <tibble [3 × 2]>         1      2017-01-02
 2              <tibble [3 × 2]>         1      2017-01-05

这是你想要的(对于这个例子)。

EDIT:对于任何其他类型(<date> 除外),您必须找到不同的解决方案,但是,标准类型由专用 map_lglmap_dblmap_chr

map_dbl() %>% as_date() 的替代方法是在感兴趣的输出列上使用 unnest()

library(tidyverse)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date

df <- data_frame(id = c(1, 1, 1, 2, 2, 2), 
                 val = c(1, 2, 3, 1, 2, 3), 
                 date = ymd("2017-01-01") + days(1:6))

df %>% nest(-id) %>% 
  mutate(first_val = map_dbl(data, ~ .$val[1]), 
         first_day = map(data, ~ .$date[1])) %>% 
  unnest(first_day)
#> # A tibble: 2 x 4
#>      id data             first_val first_day 
#>   <dbl> <list>               <dbl> <date>    
#> 1     1 <tibble [3 × 2]>         1 2017-01-02
#> 2     2 <tibble [3 × 2]>         1 2017-01-05

reprex package (v0.2.1)

创建于 2018-11-17

你可以依靠 purrr's reduce()c():

library(tidyverse)
library(lubridate)

df <- tibble(id = c(1, 1, 1, 2, 2, 2), 
             val = c(1, 2, 3, 1, 2, 3), 
             date = ymd("2017-01-01") + days(1:6))

df1 <- df %>% nest(data = -id) %>% 
    mutate(first_val = map_dbl(data, ~ .$val[1]), 
           first_day = reduce(map(data, ~ .$date[1]), c))

结果:

> df1
# A tibble: 2 × 4
     id data             first_val first_day 
  <dbl> <list>               <dbl> <date>    
1     1 <tibble [3 × 2]>         1 2017-01-02
2     2 <tibble [3 × 2]>         1 2017-01-05