将一个 dplyr "do" 函数的结果传递给另一个函数

pass result of one dplyr "do" function to another function

我正在尝试 运行 按组回归,然后将回归模型对象传递给另一个函数。

library("lmtest")
library("broom")
library("tidyr")
library("dplyr")
library("purrr")

  fitted_models <-  mtcars %>% 
    group_by(gear) %>% 
    do(fit = lm(mpg ~ ., data = .),
       test = coeftest(fit)) # from lmtest library

我收到错误:

Error in coeftest(fit) : object 'fit' not found

有没有一种方法可以传递变量,这样我就可以 运行 每个 do 文件有 1 个以上的函数,这样我的数据框就可以将 gear、fit 和 test 作为其列?

我们可以使用{}来分隔do中的多个语句,用tidy包裹coeftest输出(来自broom)以提取相关列到 tibble 输出

res <- mtcars %>% 
         group_by(gear) %>% 
         do({fit = lm(mpg ~ ., data = .)
         tidy(coeftest(fit))
         })
res
# A tibble: 24 x 6
# Groups: gear [3]
#    gear term        estimate std.error statistic p.value
#   <dbl> <chr>          <dbl>     <dbl>     <dbl>   <dbl>
# 1  3.00 (Intercept) -11.9      43.4       -0.273  0.794 
# 2  3.00 cyl         - 0.282     2.04      -0.138  0.895 
# 3  3.00 disp        - 0.0186    0.0190    -0.981  0.364 
# 4  3.00 hp            0.142     0.0779     1.83   0.117 
# 5  3.00 drat          0.998     3.87       0.258  0.805 
# 6  3.00 wt            0.684     2.63       0.260  0.804 
# 7  3.00 qsec          1.33      1.63       0.816  0.445 
# 8  3.00 vs          - 2.42      4.58      -0.527  0.617 
# 9  3.00 carb        - 6.66      2.72      -2.45   0.0499
#10  4.00 (Intercept)  26.7     185          0.144  0.899 

如果我们需要将其保留为一列,则用 list

换行
 fitted_models <-  mtcars %>% 
                     group_by(gear) %>% 
                     do({fit = lm(mpg ~ ., data = .)
                     data_frame(test = list(coeftest(fit)), fit = list(fit)) %>%
                     select(fit, test)}
  )

fitted_models
# A tibble: 3 x 3
# Groups: gear [3]
#   gear fit      test          
#  <dbl> <list>   <list>        
#1  3.00 <S3: lm> <S3: coeftest>
#2  4.00 <S3: lm> <S3: coeftest>
#3  5.00 <S3: lm> <S3: coeftest>

我们可以使用 $[[

提取 list
fitted_models$test

或者另一个选项是 map 来自 purrr

mtcars %>% 
   split(.$gear) %>%
   map(~ lm(mpg ~ ., data = .x)  %>%
               coeftest %>% 
               tidy) %>%
   bind_rows(, .id = 'gear')

或者如果我们需要创建一个包含 map

的列
mtcars %>%
     nest(-gear) %>% 
     mutate(test = map(data, ~ lm(mpg ~ ., data = .x) %>% 
                             coeftest %>% 
                             tidy)) %>%
                             as_tibble %>%
     select(-data)
# A tibble: 3 x 2
#    gear test                 
#    <dbl> <list>               
#1  4.00 <data.frame [10 x 5]>
#2  3.00 <data.frame [9 x 5]> 
#3  5.00 <data.frame [5 x 5]> 

如果我们需要 'fit' 和 'test' 作为列

mtcars %>% 
  nest(-gear) %>%
  mutate(fit = map(data, ~ lm(mpg ~ ., data = .x)),
         test = map(fit, ~coeftest(.x))) %>%
  as_tibble
# A tibble: 3 x 4
#      gear  data                   fit      test          
#   <dbl> <list>                 <list>   <list>        
#1  4.00 <data.frame [12 x 10]> <S3: lm> <S3: coeftest>
#2  3.00 <data.frame [15 x 10]> <S3: lm> <S3: coeftest>
#3  5.00 <data.frame [5 x 10]>  <S3: lm> <S3: coeftest>