将数据框与缺失值对齐
Aligning Data frame with missing values
我正在使用具有许多 NA
值的数据框。虽然我能够创建线性模型,但由于缺少值和指示列,我随后无法将模型的拟合值与原始数据对齐。
这是一个可重现的例子:
library(MASS)
dat <- Aids2
# Add NA's
dat[floor(runif(100, min = 1, max = nrow(dat))),3] <- NA
# Create a model
model <- lm(death ~ diag + age, data = dat)
# Different Values
length(fitted.values(model))
# 2745
nrow(dat)
# 2843
这里其实有3种解法:
- 填充
NA
到我们自己的拟合值;
- 使用
predict()
计算拟合值;
- 我们自己删除不完整的案例,只将完整的案例传递给
lm()
。
选项 1
## row indicator with `NA`
id <- attr(na.omit(dat), "na.action")
fitted <- rep(NA, nrow(dat))
fitted[-id] <- model$fitted
nrow(dat)
# 2843
length(fitted)
# 2843
sum(!is.na(fitted))
# 2745
选项 2
## the default NA action for "predict.lm" is "na.pass"
pred <- predict(model, newdata = dat) ## has to use "newdata = dat" here!
nrow(dat)
# 2843
length(pred)
# 2843
sum(!is.na(pred))
# 2745
选项 3
或者,您可以简单地将没有任何 NA
的数据帧传递给 lm()
:
complete.dat <- na.omit(dat)
fit <- lm(death ~ diag + age, data = complete.dat)
nrow(complete.dat)
# 2745
length(fit$fitted)
# 2745
sum(!is.na(fit$fitted))
# 2745
综上所述,
- 选项 1 通过填充
NA
以直接的方式完成 "alignment",但我认为人们很少采用这种方法;
- 选项2很简单,但是计算量更大;
- 选项 3 是我的最爱,因为它使所有事情变得简单。
我使用了一个简单的 for 循环。拟合值具有它们所属的原始行的属性(名称)。因此:
for(i in 1:nrow(data)){
data$fitted.values[i]<-
fit$fitted.values[paste(i)]
}
"data" 是您的原始数据框。 Fit 是模型中的对象(即 fit <- lm(y~x, data = data))
我的回答是对@ithomps 解决方案的扩展:
for(i in 1:nrow(data)){
data$fitted.values.men[i]<- ifelse(data$sex == 1,
fit.males$fitted.values[paste(i)], "NA")
data$fitted.values.women[i]<- ifelse(data$sex == 0,
fit.females$fitted.values[paste(i)], "NA")
data$fitted.values.combined[i]<- fit.combo$fitted.values[paste(i)]
}
因为在我的案例中,我 运行 三个模型:1 个男性模型,1 个女性模型,1 个混合模型。为了让事情 "more" 方便:男性和女性 运行 分布在我的 data
中。此外,我将丢失数据作为 lm()
的输入,因此我 fit <- lm(y~x, data = data, na.action = na.exclude)
以在我的模型对象 (fit
) 中获取 NA。
希望这对其他人有帮助。
(我发现很难制定我的 issue/question,很高兴我找到了这个 post!)
如果您不想更改原始数据。试试这个方法,真的很简单
names(fitted.values(model))
是可用观察数据的行名,我们可以使用此功能添加新列:
dat[names(fitted.values(model)), "fitted.values"] <- fitted.values(model)
sum(!is.na(dat[, "fitted.values"]))
# [1] 2745
我正在使用具有许多 NA
值的数据框。虽然我能够创建线性模型,但由于缺少值和指示列,我随后无法将模型的拟合值与原始数据对齐。
这是一个可重现的例子:
library(MASS)
dat <- Aids2
# Add NA's
dat[floor(runif(100, min = 1, max = nrow(dat))),3] <- NA
# Create a model
model <- lm(death ~ diag + age, data = dat)
# Different Values
length(fitted.values(model))
# 2745
nrow(dat)
# 2843
这里其实有3种解法:
- 填充
NA
到我们自己的拟合值; - 使用
predict()
计算拟合值; - 我们自己删除不完整的案例,只将完整的案例传递给
lm()
。
选项 1
## row indicator with `NA`
id <- attr(na.omit(dat), "na.action")
fitted <- rep(NA, nrow(dat))
fitted[-id] <- model$fitted
nrow(dat)
# 2843
length(fitted)
# 2843
sum(!is.na(fitted))
# 2745
选项 2
## the default NA action for "predict.lm" is "na.pass"
pred <- predict(model, newdata = dat) ## has to use "newdata = dat" here!
nrow(dat)
# 2843
length(pred)
# 2843
sum(!is.na(pred))
# 2745
选项 3
或者,您可以简单地将没有任何 NA
的数据帧传递给 lm()
:
complete.dat <- na.omit(dat)
fit <- lm(death ~ diag + age, data = complete.dat)
nrow(complete.dat)
# 2745
length(fit$fitted)
# 2745
sum(!is.na(fit$fitted))
# 2745
综上所述,
- 选项 1 通过填充
NA
以直接的方式完成 "alignment",但我认为人们很少采用这种方法; - 选项2很简单,但是计算量更大;
- 选项 3 是我的最爱,因为它使所有事情变得简单。
我使用了一个简单的 for 循环。拟合值具有它们所属的原始行的属性(名称)。因此:
for(i in 1:nrow(data)){
data$fitted.values[i]<-
fit$fitted.values[paste(i)]
}
"data" 是您的原始数据框。 Fit 是模型中的对象(即 fit <- lm(y~x, data = data))
我的回答是对@ithomps 解决方案的扩展:
for(i in 1:nrow(data)){
data$fitted.values.men[i]<- ifelse(data$sex == 1,
fit.males$fitted.values[paste(i)], "NA")
data$fitted.values.women[i]<- ifelse(data$sex == 0,
fit.females$fitted.values[paste(i)], "NA")
data$fitted.values.combined[i]<- fit.combo$fitted.values[paste(i)]
}
因为在我的案例中,我 运行 三个模型:1 个男性模型,1 个女性模型,1 个混合模型。为了让事情 "more" 方便:男性和女性 运行 分布在我的 data
中。此外,我将丢失数据作为 lm()
的输入,因此我 fit <- lm(y~x, data = data, na.action = na.exclude)
以在我的模型对象 (fit
) 中获取 NA。
希望这对其他人有帮助。
(我发现很难制定我的 issue/question,很高兴我找到了这个 post!)
如果您不想更改原始数据。试试这个方法,真的很简单
names(fitted.values(model))
是可用观察数据的行名,我们可以使用此功能添加新列:
dat[names(fitted.values(model)), "fitted.values"] <- fitted.values(model)
sum(!is.na(dat[, "fitted.values"]))
# [1] 2745