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

时间:2015-06-30 16:19:08

标签: r lapply

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

for (i in ListOfTraining){


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

}

感谢您的任何建议!

3 个答案:

答案 0 :(得分:3)

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

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,假设它们具有相同的列。然后,使用lmList包中的nlme来拟合模型。

## 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

答案 1 :(得分:2)

如果您愿意,可以使用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

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

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

答案 2 :(得分:1)

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

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

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选项可能更简单一点。)