如何在 r 中的数据框中的不同行组上训练回归模型

how to train a regression model on different group of rows in a data frame in r

我有以下数据框:

id   total_transfered_amount day
 1       1000                 2
 1       2000                 3
 1       3000                 4
 2       1000                 1
 2       3000                 4
 2       5000                 3
 3       1000                 4
 3       2000                 2
 3       3000                 3
 4       1000                 1
 4       2000                 2
 4       3000                 3

我需要为按 id 分组的每组行训练回归模型 例如:

model_id_1=lm(day~total_transfered_amount)
model_id_2=lm(day~total_transfered_amount)
model_id_n=lm(day~total_transfered_amount)

如何将 lm 应用于一组具有相同 id 的数据,并将其放入模型中?然后再由另一个 id?

为另一组行

我可以使用 apply 家庭吗?如果是怎么办?或者 dplyr 在这种情况下可以帮助我吗?

一种方法是根据 id 和 lapply 回归公式拆分数据框,

list1 <- split(df, df$id)
lapply(list1, function(i)lm(i$day ~ i$total_transfered_amount))

为了效率。并获得系数。和拦截,data.table 选项应该非常有效,

setDT(df)[, .(new = lm(day~total_transfered_amount)[1]), id]
#   id               new
#1:  1       1.000,0.001
#2:  2 1.166667,0.000500
#3:  3      4e+00,-5e-04
#4:  4       0.000,0.001

最直接的方法是使用 nlme 包中的 lmList 函数:

library(nlme)
models_id <- lmList(day ~ total_transfered_amount| id, df)

models_id
Call:
  Model: day ~ total_transfered_amount | id 
   Data: df 

Coefficients:
  (Intercept) total_transfered_amount
1    1.000000                   1e-03
2    1.166667                   5e-04
3    4.000000                  -5e-04
4    0.000000                   1e-03

Degrees of freedom: 12 total; 4 residual
Residual standard error: 1.020621

只是为了添加一个替代方案,我建议沿着这条路走:

library(dplyr)
library(broom)

df %>% group_by(id) %>% do(tidy(lm(day~ total_transfered_amount, data=.)))

在这里,我只是用dplyr的分组动作来运行线性回归id。这为您提供了一个以系数作为输出的数据框。参见:

> df %>% group_by(id) %>% do(tidy(lm(day~ total_transfered_amount, data=.)))
Source: local data frame [8 x 6]
Groups: id [4]

     id                    term  estimate    std.error  statistic   p.value
  (dbl)                   (chr)     (dbl)        (dbl)      (dbl)     (dbl)
1     1             (Intercept)  1.000000 0.0000000000        Inf 0.0000000
2     1 total_transfered_amount  0.001000 0.0000000000        Inf 0.0000000
3     2             (Intercept)  1.166667 1.9720265944  0.5916080 0.6599011
4     2 total_transfered_amount  0.000500 0.0005773503  0.8660254 0.5456289
5     3             (Intercept)  4.000000 1.8708286934  2.1380899 0.2785092
6     3 total_transfered_amount -0.000500 0.0008660254 -0.5773503 0.6666667
7     4             (Intercept)  0.000000 0.0000000000        NaN       NaN
8     4 total_transfered_amount  0.001000 0.0000000000        Inf 0.0000000

请注意,生成 InfNaN 是因为您发布的数据在 id 的因变量和解释变量之间具有完美的 1:1 关系的 1 和 4。有趣的是,与 nlme::lmList 选项相比,您实际上可以在此处看到这一点。您还可以查看 broom::tidy 的选项以添加例如置信区间等

如果你想使用 dplyr,你可以做到

df <- data.frame(id = c(1,1,1,2,2,2,3,3,3,4,4,4), total_transfered_amount = c(1000,2000,3000,1000,3000,5000,1000,2000,3000,1000,2000,3000), day=c(2,3,4,1,4,3,4,2,3,1,2,3))
result <-df %>% group_by(id) %>% do (model = lm(.$day ~.$total_transfered_amount))