dplyr,do(),提取模型参数而不失去分组变量

7

从R help文档中稍作修改的一个实例:

by_cyl <- group_by(mtcars, cyl)
models <- by_cyl %>% do(mod = lm(mpg ~ disp, data = .))
coefficients<-models %>% do(data.frame(coef = coef(.$mod)[[1]]))

在数据框架 coefficients 中,每个 cyl 组的线性模型的第一个系数。我的问题是如何生成一个数据框架,该数据框架不仅包含一个系数列,还包含一个分组变量列。
===== 编辑:我扩展了示例,试图更清楚地说明我的问题
假设我想提取模型的系数和一些预测。我可以这样做:
by_cyl <- group_by(mtcars, cyl)
getpars <- function(df){
  fit <- lm(mpg ~ disp, data = df)
  data.frame(intercept=coef(fit)[1],slope=coef(fit)[2])
}
getprediction <- function(df){
  fit <- lm(mpg ~ disp, data = df)
  x <- df$disp
  y <- predict(fit, data.frame(disp= x), type = "response")
  data.frame(x,y)
}
pars <- by_cyl %>% do(getpars(.))
prediction <- by_cyl %>% do(getprediction(.))

问题在于代码重复,因为我拟合了两次模型。我的想法是构建一个函数,返回包含所有信息的列表:
getAll <- function(df){
  results<-list()
  fit <- lm(mpg ~ disp, data = df)
  x <- df$disp
  y <- predict(fit, data.frame(disp= x), type = "response")

  results$pars <- data.frame(intercept=coef(fit)[1],slope=coef(fit)[2])
  results$prediction <- data.frame(x,y)

  results
 }

问题在于我不知道如何使用do()函数与getAll()函数一起使用,以获取仅包含参数的数据框(例如像数据框pars一样)。

1
不确定这是否有帮助。您可以使用summarise代替第二个do。summarise(models, coef = coef(summary(mod))[[1]],group=cyl) - akrun
3
这是一个错误,我会尽快修复它,等我找到方法后。 - hadley
1
@hadley 这个问题已经修复了吗?你能否指出对应的 GitHub 上的 issue? - Rosen Matev
@RosenMatev 你有关于这个问题找到任何信息吗? - danilinares
根据Hadley的说法,这个问题可能在dplyr 0.4中得以解决。 - danilinares
据我所知,akrun的解决方案存在的问题是它只返回数值。我的数据集中需要报告分组变量,但它将因子水平转换为数字。我更喜欢Robert Krzyanowski的解决方案。 - spindoctor
2个回答

7
像这样吗?
coefficients <-models %>% do(data.frame(coef = coef(.$mod)[[1]], group = .[[1]]))

yielding

        coef group
  1 40.87196     4
  2 19.08199     6
  3 22.03280     8

1
谢谢,类似这样的东西。我想知道是否可能自动使用group_by中的分组。因此,如果例如,group_by更改为group_by(mtcar,cyl,am),则在do()内部不需要使用group = .[[1]]和group2 = .[[2]]。 - danilinares
1
我认为这更简单;尝试 coefficients <- models %>% do(data.frame(coef=coef(.$mod), group = .[[1]], var = names(coef(.$mod)))) - gregmacfarlane
1
我知道这已经有点老了,但这确实帮助了我。do(data.frame(group = .[[1]], a=coef(.$mod)[1], b=coef(.$mod)[2], r2 = summary(.$mod)$r.squared)) 这可以获取整个方程以便使用 group_by 变量进行绘图。 - bhive01

4

使用 Hadley Wickham 在 这个视频 中介绍的方法:

library(dplyr)
library(purrr)
library(broom)

fitmodel <- function(d) lm(mpg ~ disp, data = d)
by_cyl <- mtcars %>% 
  group_by(cyl) %>% 
  nest() %>%
  mutate(mod = map(data, fitmodel), 
         pars = map(mod, tidy), 
         pred = map(mod, augment))

pars <- by_cyl %>% unnest(pars)
prediction <- by_cyl %>% unnest(pred)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接