在管道 purrr 匿名函数调用中迭代列出的数据帧

Iterating over listed data frames within a piped purrr anonymous function call

使用 purrr::mapmagrittr 管道,我正在尝试生成一个新列,其值等于现有列的子字符串。

我可以用以下玩具数据集来说明我正在尝试做什么:

library(tidyverse)
library(purrr)

test <- list(tibble(geoid_1970 = c(123, 456), 
                    name_1970 = c("here", "there"), 
                    pop_1970 = c(1, 2)),
             tibble(geoid_1980 = c(234, 567), 
                    name_1980 = c("here", "there"), 
                    pop_1970 = c(3, 4))
)

在每个列出的数据框中,我想要一个等于相关年份的列。没有迭代,我的代码是:

data <- map(test, ~ .x %>% mutate(year = as.integer(str_sub(names(test[[1]][1]), -4))))

当然,这 returns 在两个列出的数据框中都是 1970 年,这是我不想要的。 (我要第一个 1970,第二个 1980。)

此外,它没有通过管道传输,我尝试通过管道传输它会引发错误:

data <- test %>% map(~ .x %>% mutate(year = as.integer(str_sub(names(.x[[1]][1]), -4))))
# > Error: Problem with `mutate()` input `year`.
# > x Input `year` can't be recycled to size 2.
# > ℹ Input `year` is `as.integer(str_sub(names(.x[[1]][1]), -4))`.
# > ℹ Input `year` must be size 2 or 1, not 0.

如何使用管道遍历每个列出的数据框?

尝试:

test %>% map(~.x %>% mutate(year = as.integer(str_sub(names(.x[1]), -4))))

[[1]]
# A tibble: 2 x 4
  geoid_1970 name_1970 pop_1970  year
       <dbl> <chr>        <dbl> <int>
1        123 here             1  1970
2        456 there            2  1970

[[2]]
# A tibble: 2 x 4
  geoid_1980 name_1980 pop_1970  year
       <dbl> <chr>        <dbl> <int>
1        234 here             3  1980
2        567 there            4  1980

我们可以用 parse_number

得到 'year'
library(dplyr)
library(purrr)
map(test, ~ .x %>%
      mutate(year = readr::parse_number(names(.)[1])))

-输出

#[[1]]
# A tibble: 2 x 4
#  geoid_1970 name_1970 pop_1970  year
#       <dbl> <chr>        <dbl> <dbl>
#1        123 here             1  1970
#2        456 there            2  1970

#[[2]]
# A tibble: 2 x 4
#  geoid_1980 name_1980 pop_1970  year
#       <dbl> <chr>        <dbl> <dbl>
#1        234 here             3  1980
#2        567 there            4  1980