pmap_变体以列表形式对data.frames进行操作

时间:2019-06-03 15:06:27

标签: r purrr

我有个回忆,purrr::pmap_*可以将data.frame视为列表,但是语法使我难以理解。

想象一下我们想为lmmtcars$vs的每个值装配一个单独的mtcars$am对象

library(tidyverse)
library(broom)

d1 <- mtcars %>% 
  group_by(
    vs, am
  ) %>% 
  nest %>% 
  mutate(
    coef = data %>% 
      map(
        ~lm(mpg ~ wt, data =.) %>% 
          tidy
      )
  )

如果我想将系数估计值提取为未嵌套的data.frame,并附加amvs的值,我可以尝试

d1[, -3] %>% 
  pmap_dfr(
    function(i, j, k)
      k %>% 
      mutate(
        vs = i,
        am = j
      )
  )

但这会导致错误。更明确地将这些变量声明为单独的列表具有预期的效果

list(
  d1$vs,
  d1$am,
  d1$coef
  ) %>% 
  pmap_dfr(
    function(i, j, k)
      k %>% 
      mutate(
        vs = i,
        am = j
      )
  )

pmap_*是否有一种简洁的方法将data.frame视为列表?

2 个答案:

答案 0 :(得分:3)

我们可以使用标准选项来提取组件(..1..2等)

d1[, -3]  %>% 
    pmap_dfr(~ ..3 %>%
                  mutate(vs = ..1, am = ..2))
# A tibble: 8 x 7
#  term        estimate std.error statistic   p.value    vs    am
#  <chr>          <dbl>     <dbl>     <dbl>     <dbl> <dbl> <dbl>
#1 (Intercept)    42.4      3.30      12.8  0.000213      0     1
#2 wt             -7.91     1.14      -6.93 0.00227       0     1
#3 (Intercept)    44.1      6.96       6.34 0.00144       1     1
#4 wt             -7.77     3.36      -2.31 0.0689        1     1
#5 (Intercept)    31.5      8.98       3.51 0.0171        1     0
#6 wt             -3.38     2.80      -1.21 0.281         1     0
#7 (Intercept)    25.1      3.51       7.14 0.0000315     0     0
#8 wt             -2.44     0.842     -2.90 0.0159        0     0

答案 1 :(得分:2)

这是因为第二个列表没有名称属性。如果您unname d1有效。在第二个示例中使用list函数的事实并没有什么不同(除了它删除了名称),因为两个对象都是列表(数据框是列表)。

d1[, -3] %>% 
  unname %>% 
  pmap_dfr(
    function(i, j, k)
      k %>% 
      mutate(
        vs = i,
        am = j
      )
  )


# # A tibble: 8 x 7
#   term        estimate std.error statistic   p.value    vs    am
#   <chr>          <dbl>     <dbl>     <dbl>     <dbl> <dbl> <dbl>
# 1 (Intercept)    42.4      3.30      12.8  0.000213      0     1
# 2 wt             -7.91     1.14      -6.93 0.00227       0     1
# 3 (Intercept)    44.1      6.96       6.34 0.00144       1     1
# 4 wt             -7.77     3.36      -2.31 0.0689        1     1
# 5 (Intercept)    31.5      8.98       3.51 0.0171        1     0
# 6 wt             -3.38     2.80      -1.21 0.281         1     0
# 7 (Intercept)    25.1      3.51       7.14 0.0000315     0     0
# 8 wt             -2.44     0.842     -2.90 0.0159        0     0

您也可以在第一个代码块的函数中命名参数以匹配(或使用..1等)以获得相同的结果

d1[, -3] %>% 
  pmap_dfr(
    function(vs, am, coef)
      coef %>% 
      mutate(
        vs = vs,
        am = am
      )
  )


# # A tibble: 8 x 7
#   term        estimate std.error statistic   p.value    vs    am
#   <chr>          <dbl>     <dbl>     <dbl>     <dbl> <dbl> <dbl>
# 1 (Intercept)    42.4      3.30      12.8  0.000213      0     1
# 2 wt             -7.91     1.14      -6.93 0.00227       0     1
# 3 (Intercept)    44.1      6.96       6.34 0.00144       1     1
# 4 wt             -7.77     3.36      -2.31 0.0689        1     1
# 5 (Intercept)    31.5      8.98       3.51 0.0171        1     0
# 6 wt             -3.38     2.80      -1.21 0.281         1     0
# 7 (Intercept)    25.1      3.51       7.14 0.0000315     0     0
# 8 wt             -2.44     0.842     -2.90 0.0159        0     0

您还可以使用实验性rap package中的wap

library(rap)

d1[, -3] %>% 
  wap( ~ coef %>% 
          mutate(
            vs = vs,
            am = am)) %>% 
  bind_rows
# # A tibble: 8 x 7
#   term        estimate std.error statistic   p.value    vs    am
#   <chr>          <dbl>     <dbl>     <dbl>     <dbl> <dbl> <dbl>
# 1 (Intercept)    42.4      3.30      12.8  0.000213      0     1
# 2 wt             -7.91     1.14      -6.93 0.00227       0     1
# 3 (Intercept)    44.1      6.96       6.34 0.00144       1     1
# 4 wt             -7.77     3.36      -2.31 0.0689        1     1
# 5 (Intercept)    31.5      8.98       3.51 0.0171        1     0
# 6 wt             -3.38     2.80      -1.21 0.281         1     0
# 7 (Intercept)    25.1      3.51       7.14 0.0000315     0     0
# 8 wt             -2.44     0.842     -2.90 0.0159        0     0