如何在 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
请注意,生成 Inf
和 NaN
是因为您发布的数据在 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))
我有以下数据框:
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
请注意,生成 Inf
和 NaN
是因为您发布的数据在 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))