我有一个包含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)
这未能以调整(即预测)的形式向我提供“家属”。
有什么想法吗?
提前致谢
答案 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.karno
和pat.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?