【问题标题】:Filling NA using linear regression in R在 R 中使用线性回归填充 NA
【发布时间】:2018-04-03 16:04:14
【问题描述】:

我有一个包含一个时间列和 2 个变量的数据。(示例如下)

df <- structure(list(time = c(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 
                              25, 26), var1 = c(20.4, 31.5, NA, 53.7, 64.8, NA, NA, NA, NA, 
                              120.3, NA, 142.5), var2 = c(30.6, 47.25, 63.9, 80.55, 97.2, 113.85, 
                              130.5, 147.15, 163.8, 180.45, 197.1, 213.75)), .Names = c("time", 
                              "var1", "var2"), row.names = c(NA, -12L), class = c("tbl_df", 
                              "tbl", "data.frame"))

var1 的 NA 很少,我想用 var1 和 var2 中剩余值之间的线性回归填充 NA。

请帮忙!! 如果您需要更多信息,请告诉我

【问题讨论】:

  • 你尝试了什么?运行线性模型(您的 NA 将自动省略),然后在带有 NA 的行上运行predict。用预测值填写原始数据。你被困在哪里了?你熟悉lm()吗?
  • 不,我不熟悉 lm()。我在stackoverflow中找不到关于这个的帮助。可以给我看看吗?

标签: r linear-regression na


【解决方案1】:

这是一个使用lm 预测 R 中值的示例。

library(dplyr)

# Construct linear model based on non-NA pairs
df2 <- df %>% filter(!is.na(var1))

fit <- lm(var1 ~ var2, data = df2)

# See the result
summary(fit)

# Call:
#   lm(formula = var1 ~ var2, data = df2)
# 
# Residuals:
#   1          2          3          4          5          6 
# 8.627e-15 -2.388e-15  1.546e-16 -9.658e-15 -2.322e-15  5.587e-15 
# 
# Coefficients:
#   Estimate Std. Error   t value Pr(>|t|)    
# (Intercept) 2.321e-14  5.619e-15 4.130e+00   0.0145 *  
#   var2        6.667e-01  4.411e-17 1.511e+16   <2e-16 ***
#   ---
#   Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# 
# Residual standard error: 7.246e-15 on 4 degrees of freedom
# Multiple R-squared:      1,   Adjusted R-squared:      1 
# F-statistic: 2.284e+32 on 1 and 4 DF,  p-value: < 2.2e-16
# 
# Warning message:
#   In summary.lm(fit) : essentially perfect fit: summary may be unreliable

# Use fit to predict the value
df3 <- df %>% 
  mutate(pred = predict(fit, .)) %>%
  # Replace NA with pred in var1
  mutate(var1 = ifelse(is.na(var1), pred, var1))

# See the result
df3 %>% as.data.frame()

#    time  var1   var2  pred
# 1    15  20.4  30.60  20.4
# 2    16  31.5  47.25  31.5
# 3    17  42.6  63.90  42.6
# 4    18  53.7  80.55  53.7
# 5    19  64.8  97.20  64.8
# 6    20  75.9 113.85  75.9
# 7    21  87.0 130.50  87.0
# 8    22  98.1 147.15  98.1
# 9    23 109.2 163.80 109.2
# 10   24 120.3 180.45 120.3
# 11   25 131.4 197.10 131.4
# 12   26 142.5 213.75 142.5

【讨论】:

    【解决方案2】:

    这是一个使用基础 R 中的 approx 函数的单行:

    newvar1<-approx(df$time, df$var1, xout=df$time)
    

    此函数将在相邻点之间应用线性近似值,这与“www”答案相反,后者在所有点上应用线性近似值。有了这些数据,两种解决方案都提供了相同的结果,因为 time 和 var1 具有完美的线性关系,但可能并非总是如此。
    xout 选项指定估计新值的位置,在这种情况下,我传递的是原始时间向量。

    相关:请参阅spline 函数以获取三次近似值。

    【讨论】:

    • 很高兴学习approx函数。所以我给了你一个赞成票。但是,如果我正确理解了这个问题,OP 会询问 var1var2 之间的线性回归,而您的解决方案仅在 var1 中是线性插值。我说的对吗?
    • 这是线性插值,用于填充 var1 的 NA 值,假设 time 是独立值。这个问题是不现实的,因为timevar1var2 都是 100% 线性相关的。
    • @Dave2e 感谢您的解决方案。感谢介绍近似函数。我将在需要使用时间填充变量的情况下使用它。再次感谢
    【解决方案3】:

    我意识到这是一个老问题,但这可能是一种有用的蛮力技术

    生成你的线性模型

    fit <- lm(var1 ~ var2, data = df)
    

    使用 coef() 将系数保存到对象中

    fit.c <- coef(fit)
    fit.c
    

    使用这些系数生成预测值作为新变量。括号内的数字表示系数在向量 fit.c 中的位置。 fit.c[1] 是截距。

    df$pred <- fit.c[1] + fit.c[2]*df$var2
    

    此时您可以替换原始变量中的 NA 值

    df$var1[is.na(df$var1)] <- df$pred 
    

    但是我的直觉告诉我不要覆盖原始变量中的值,而是将 pred 用于您为 var1 计划的任何目的。

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 2020-08-28
      • 2019-03-10
      • 2019-11-02
      • 2019-03-11
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多