将数据框与缺失值对齐

时间:2016-07-07 18:56:35

标签: r regression linear-regression na lm

我使用的数据框有很多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

4 个答案:

答案 0 :(得分:7)

这里实际上有三个解决方案:

  1. 自己填充NA以适应值;
  2. 使用predict()计算拟合值;
  3. 自行删除不完整的案例,并仅将完整案例传递给lm()
  4. 选项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以直接的方式完成“对齐”,但我认为人们很少采用这种方法;
    • 选项2 非常简单,但计算成本更高;
    • 选项3 是我的最爱,因为它让所有事情变得简单。

答案 1 :(得分:2)

我使用简单的for循环。拟合值具有它们所属的原始行的属性(名称)。因此:

for(i in 1:nrow(data)){
  data$fitted.values[i]<-
    fit$fitted.values[paste(i)]
}

&#34;数据&#34;是您的原始数据框架。拟合是模型中的对象(即拟合&lt; -lm(y~x,data = data))

答案 2 :(得分:0)

我的回答是对@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个用于组合。并且做更多事情&#34;更多&#34;方便:男性和女性随机分布在我的data。此外,我将lm()的输入作为输入缺失,因此我fit <- lm(y~x, data = data, na.action = na.exclude)在我的模型对象(fit)中获取了NA。

希望这有助于其他人。

(我发现很难制定我的问题/问题,很高兴我找到了这个帖子!)

答案 3 :(得分:0)

如果您不想更改原始数据。尝试这种方式,这非常简单。

names(fitted.values(model))是可用观测值的数据行名,我们可以使用此功能添加新列:

dat[names(fitted.values(model)), "fitted.values"] <- fitted.values(model)
sum(!is.na(dat[, "fitted.values"]))
# [1] 2745