使用循环,执行回归,为每个人预测新值

时间:2015-09-02 19:01:52

标签: r

我有一个包含20个变量的数据集。其中10个是非常感兴趣的变量,但这些变量需要针对年龄和性别方面的群体差异进行调整。我这样做是通过使用回归来预测取决于年龄和性别的值。

有许多变量和很多人,所以我想要一个循环或类似的东西。

这是我正在尝试的一个例子

# Load example data
library(survival)
library(dplyr)
data(lung) # example data

# I want to obtain adjusted values for the following two variables, called "dependents"
dependents <- names(select(lung, 7:8))

new_data <- lung # copies data set
for (i in seq_along(dependents)) {
     eq <- paste(dependents[i],"~ age + sex")
     fit <- lm(as.formula(eq), data= new_data)
     new_data$predicted_value <- predict(fit, newdata=new_data, type='response')
     new_data <- rename(new_data, paste(dependents[i], "_predicted", sep="") = predicted_value)
}
View(new_data)

这未能以调整(即预测)的形式向我提供“家属”。

有什么想法吗?

提前致谢

3 个答案:

答案 0 :(得分:3)

这是另一种方法,使用tidyr包和扫帚包中的augment功能:

library(tidyr)
library(broom)

new_data <- lung %>%
  gather(dependent, value, ph.karno:pat.karno) %>%
  group_by(dependent) %>%
  do(augment(lm(value ~ age + sex, data = .)))

这会重新组织数据,以便每个从属(ph.karnopat.karno)堆叠在一起,并以dependent列进行区分。 augment函数将每个模型转换为一个数据框,其中包含拟合值,残差和您关注的其他值的列(有关详细信息,请参阅?lm_tidiers)。然后,.fitted列会给出拟合值:

new_data
#> Source: local data frame [452 x 12]
#> Groups: dependent
#> 
#>    dependent .rownames value age sex  .fitted  .se.fit     .resid
#> 1   ph.karno         1    90  74   1 78.86709 1.406553  11.132915
#> 2   ph.karno         2    90  68   1 80.53347 1.115994   9.466530
#> 3   ph.karno         3    90  56   1 83.86624 1.226463   6.133759
#> 4   ph.karno         4    90  57   1 83.58851 1.181024   6.411490
#> 5   ph.karno         5   100  60   1 82.75532 1.078170  17.244683
#> 6   ph.karno         6    50  74   1 78.86709 1.406553 -28.867085
#> 7   ph.karno         7    70  68   2 80.18860 1.419744 -10.188596
#> 8   ph.karno         8    60  71   2 79.35540 1.555365 -19.355404
#> 9   ph.karno         9    70  53   1 84.69943 1.388600 -14.699433
#> 10  ph.karno        10    70  61   1 82.47759 1.056850 -12.477586
#> ..       ...       ...   ... ... ...      ...      ...        ...
#> Variables not shown: .hat (dbl), .sigma (dbl), .cooksd (dbl), .std.resid
#>   (dbl)

作为一种可以使用此数据的方法,您可以绘制因变量预测的不同之处:

ggplot(new_data, aes(age, .fitted, color = dependent, lty = factor(sex))) +
     geom_line()

但是,如果您希望控制年龄和性别,您可能希望使用.resid列。

答案 1 :(得分:3)

你不能这样做吗?

dependents <- names(lung)[7:8]
fit <- lm(as.formula(sprintf("cbind(%s) ~ age + sex", 
                      paste(dependents, collapse = ", "))), 
          data = lung)
predict(fit)

也许我误会了。你的问题不是很清楚。

答案 2 :(得分:2)

第三种方法。

new_data <- na.omit(lung[,c("sex","age",dependents)])
result <- lapply(new_data[,dependents],
                 function(y)predict(lm(y~age+sex,data.frame(y=y,new_data[,c("age","sex")]))))
names(result) <- paste(names(result),"predicted",sep="_")
result <- cbind(new_data,as.data.frame(result))
head(result)
#   sex age ph.karno pat.karno ph.karno_predicted pat.karno_predicted
# 1   1  74       90       100           78.83030            77.34670
# 2   1  68       90        90           80.59974            78.53841
# 3   1  56       90        90           84.13862            80.92183
# 4   1  57       90        60           83.84371            80.72321
# 5   1  60      100        90           82.95899            80.12736
# 6   1  74       50        80           78.83030            77.34670

您的原始代码有一些微妙的问题(除了它没有运行的事实)。响应变量有一些NA s,由lm(...)自动删除,因此预测的原始数据集的行数较少,并且当您尝试添加新列时,例如

 new_data$predicted_value <- predict(fit, newdata=new_data, type='response') 
你得到一个错误。您必须先从new_data中删除NA,如上面的代码所示。

我也想知道,因为你的数据似乎是一些东西,如果你应该使用poisson glm而不是lm?