R将回归系数添加到数据框

R adding regression coeffcients to data frame

我有一个数据框列表,其中包含许多数据子集 (470ish)。我正在尝试 运行 对它们中的每一个进行回归,并将回归系数添加到数据框中。数据框将包含每个子组上所有因变量的系数。我尝试使用 for 循环进行迭代,但显然这不是正确的方法。我认为解决方案与lapply有关?

for (i in ListOfTraining){


    lm(JOB_VOLUME ~  FEB+MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC        data=ListOfTraining[[i]])

}

感谢任何建议!

如果愿意,您可以使用 for 循环解决此问题。您的问题是随着循环的进行,结果没有保存到对象中。您可以在下面查看使用内置 mtcars 数据框的示例。

(第一个示例是根据 OP 对如何提取 R 平方值的示例的请求进行修改的。)

ListOfTraining <- list(mtcars, mtcars)
results <- list()

for (i in seq_along(ListOfTraining)) {
  lm_obj <- lm(disp ~ qsec, data = ListOfTraining[[i]])
  tmp <- c(lm_obj$coefficients, summary(lm_obj)$r.squared)
  names(tmp)[length(tmp)] <- "r.squared"
  results[[i]] <- tmp
}

results <- do.call(rbind, results)
results

您还可以使用 lapply 重写 for 循环,如下所示。

ListOfTraining <- list(mtcars, mtcars)
results <- list()

results <- lapply(ListOfTraining, function(x) {
  lm(disp ~ qsec, data = x)$coefficients
})

results <- do.call(rbind, results)
results

最后,您可以使用 plyr 包的 ldply 函数,它会自动将列表应用输出转换为数据帧(如果可能)。

ListOfTraining <- list(mtcars, mtcars)
results <- plyr::ldply(ListOfTraining, function(x) {
  lm(disp ~ qsec, data = x)$coefficients
})
results

您当前的代码 运行 是回归,但不对结果做任何事情(在循环内它们甚至不会自动打印),因此它们只是被丢弃。你需要有一些结构来保存结果。

下面的代码将创建一个系数矩阵(假设所有回归运行没有错误并且最终系数的数量相同):

my.coef <- sapply( ListOfTraining, function(dat) { 
    coef(lm( JOB_VOLUME ~ FEB+MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC,
             data=dat) )
})

然后可以将矩阵转换为数据框(您也可以使用 lapply 并转换为数据框,但我认为 sapply 选项可能更简单一些)。

broom 中的函数 tidy 可以很好地处理这个问题。

library(dplyr)          # bind_rows is more efficient than do.call(rbind, ...)
library(broom)          # put statistics into data.frame
bind_rows(lapply(ListOfTraining, function(dat)
    tidy(lm(JOB_VOLUME ~ FEB+MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC, data=dat))))

例子

dataList <- split(mtcars, mtcars$cyl)  # list of data.frames by number of cylinders
lapply(dataList, function(dat) tidy(lm(mpg ~ disp + hp, data=dat))) %>%  # fit models
  bind_rows() %>%                                                        # combine into one data.frame
  mutate(model=rep(1:length(dataList), each=3))                          # add a model ID column
#          term     estimate   std.error   statistic      p.value model
# 1 (Intercept) 43.040057552 4.235724713 10.16120274 7.531962e-06     1
# 2        disp -0.119536016 0.036945788 -3.23544366 1.195900e-02     1
# 3          hp -0.046091563 0.047423668 -0.97191054 3.595602e-01     1
# 4 (Intercept) 20.151209478 6.938235241  2.90437104 4.392508e-02     2
# 5        disp  0.001796527 0.020195109  0.08895852 9.333909e-01     2
# 6          hp -0.006032441 0.034597750 -0.17435935 8.700522e-01     2
# 7 (Intercept) 24.044775630 4.045729006  5.94324919 9.686231e-05     3
# 8        disp -0.018627566 0.009456903 -1.96973225 7.456584e-02     3
# 9          hp -0.011315585 0.012572498 -0.90002676 3.873854e-01     3

或者,您可以预先绑定 data.frames,假设它们具有相同的列。然后,使用 nlme 包中的 lmList 拟合模型。

## Combine list of data.frames into one data.frame with a factor variable
lengths <- sapply(dataList, nrow)  # in case data.frames have different num. rows
dat <- dataList %>% bind_rows() %>% 
  mutate(group=rep(1:length(dataList), times=lengths))  # group id column

library(nlme)  # lmList()
models <- lmList(mpg ~ disp + hp | group, data=dat)  # make models, grouped by group
models$coefficients
#   (Intercept)         disp           hp
# 1    43.04006 -0.119536016 -0.046091563
# 2    20.15121  0.001796527 -0.006032441
# 3    24.04478 -0.018627566 -0.011315585