我有一个带有一列模型的数据框,我正在尝试添加一列预测值。一个最小的例子是:
exampleTable <- data.frame(x = c(1:5, 1:5),
y = c((1:5) + rnorm(5), 2*(5:1)),
groups = rep(LETTERS[1:2], each = 5))
models <- exampleTable %>% group_by(groups) %>% do(model = lm(y ~ x, data = .))
exampleTable <- left_join(tbl_df(exampleTable), models)
estimates <- exampleTable %>% rowwise() %>% do(Est = predict(.$model, newdata = .["x"]))
如何向exampleTable
添加一列数字预测?我尝试使用mutate
直接将列添加到表中但没有成功。
> exampleTable <- exampleTable %>% rowwise() %>% mutate(data.frame(Pred = predict(.$model, newdata = .["x"])))
Error: no applicable method for 'predict' applied to an object of class "list"
现在我使用bind_cols
将estimates
添加到exampleTable
,但我正在寻找更好的解决方案。
estimates <- exampleTable %>% rowwise() %>% do(data.frame(Pred = predict(.$model, newdata = .["x"])))
exampleTable <- bind_cols(exampleTable, estimates)
如何一步完成?
答案 0 :(得分:7)
使用建模器,可以使用tidyverse解决方案。
输入
library(dplyr)
library(purrr)
library(tidyr)
# generate the inputs like in the question
example_table <- data.frame(x = c(1:5, 1:5),
y = c((1:5) + rnorm(5), 2*(5:1)),
groups = rep(LETTERS[1:2], each = 5))
models <- example_table %>%
group_by(groups) %>%
do(model = lm(y ~ x, data = .)) %>%
ungroup()
example_table <- left_join(tbl_df(example_table ), models, by = "groups")
解决方案
# generate the extra column
example_table %>%
group_by(groups) %>%
do(modelr::add_predictions(., first(.$model)))
说明
add_predictions
使用给定模型将新列添加到数据框。不幸的是,它仅采用一个模型作为参数。认识do
。使用do,我们可以在每个组上单独运行add_prediction
。
.
代表分组的数据帧,.$model
代表模型列,first()
代表每组的第一个模型。
简体
只有一个模型,add_predictions效果很好。
# take one of the models
model <- example_table$model[[6]]
# generate the extra column
example_table %>%
modelr::add_predictions(model)
食谱
如今,tidyverse已从modelr
软件包转移到recipes
,因此一旦该软件包成熟,这可能就是新的选择。
答案 1 :(得分:3)
为了记录,这在data.table
:
library(data.table)
setDT(exampleTable)
# actually, the more typical usage is to set the newdata
# argument here to .SD (especially for multivariate regressions; see:
# https://stackoverflow.com/a/32277135/3576984
exampleTable[ , estimates := predict(lm(y ~ x), data.frame(x)), by = groups]
exampleTable
# x y groups estimates
# 1: 1 0.3123549 A 0.6826629
# 2: 2 2.7636593 A 1.8297796
# 3: 3 1.7771181 A 2.9768963
# 4: 4 5.2031623 A 4.1240130
# 5: 5 4.8281869 A 5.2711297
# 6: 1 10.0000000 B 10.0000000
# 7: 2 8.0000000 B 8.0000000
# 8: 3 6.0000000 B 6.0000000
# 9: 4 4.0000000 B 4.0000000
# 10: 5 2.0000000 B 2.0000000
如果您按照data.table
的清晰度进行销售,请查看intro vignettes!
另外,您并非真的需要按groups
进行分组。只需将其作为虚拟交互。如果我记得,无论如何,这是获得正确标准错误的正确方法:
exampleTable[ , estimates2 := predict(lm(y ~ x * factor(groups)), .SD)]
exampleTable[ , all.equal(estimates, estimates2)]
# [1] TRUE
答案 2 :(得分:3)
使用tidyverse:
library(dplyr)
library(purrr)
library(tidyr)
library(broom)
exampleTable <- data.frame(
x = c(1:5, 1:5),
y = c((1:5) + rnorm(5), 2*(5:1)),
groups = rep(LETTERS[1:2], each = 5)
)
exampleTable %>%
group_by(groups) %>%
nest() %>%
mutate(model = data %>% map(~lm(y ~ x, data = .))) %>%
mutate(Pred = map2(model, data, predict)) %>%
unnest(Pred, data)
# A tibble: 10 × 4
groups Pred x y
<fctr> <dbl> <int> <dbl>
1 A 1.284185 1 0.9305908
2 A 1.909262 2 1.9598293
3 A 2.534339 3 3.2812002
4 A 3.159415 4 2.9283637
5 A 3.784492 5 3.5717085
6 B 10.000000 1 10.0000000
7 B 8.000000 2 8.0000000
8 B 6.000000 3 6.0000000
9 B 4.000000 4 4.0000000
10 B 2.000000 5 2.0000000
答案 3 :(得分:1)
呃,这只是稍好一点:
answer =
exampleTable %>%
group_by(groups) %>%
do(lm( y ~ x , data = .) %>%
predict %>%
data_frame(prediction = .)) %>%
bind_cols(exampleTable)
我希望这会奏效,但它没有。
answer =
exampleTable %>%
group_by(groups) %>%
mutate(prediction =
lm( y ~ x , data = .) %>%
predict)