【问题标题】:How to replace NAs with the linear interpolation between known observations? [duplicate]如何用已知观测值之间的线性插值替换 NA? [复制]
【发布时间】:2015-05-20 06:59:21
【问题描述】:

我有以下数据框,

df <- data.frame(id = c("a", "a", "a", "a", "b", "b", "b", "b"),
        time = 1:4, value = c(100, NA, NA, 550, 300, NA, NA, 900))

有人可以建议一种方法来替换 df 中的 NA 值,方法是随时间平均划分 value 列的差异吗?在时间 1,A 为 100,在时间 4 A 为 550。如何将时间 2 和 3 的 NA 更改为 250 和 400?然后在第 2 次和第 3 次为 B 提供 500 和 700?

我可以编写一个复杂的 for 循环来强制它,但是有没有更有效的解决方案?

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用 na.approx 中的 zoo

    library(zoo)
    df$value <- na.approx(df$value)
    df
    #  id time value
    #1  a    1   100
    #2  a    2   250
    #3  a    3   400
    #4  a    4   550
    #5  b    1   300
    #6  b    2   500
    #7  b    3   700
    #8  b    4   900
    

    【讨论】:

      【解决方案2】:

      或者您可以创建自己的na.approx 的矢量化版本,无需任何复杂的循环,无需任何外部包即可解决

      myna.approx <- function(x){
        len <- length(x) 
        cumsum(c(x[1L], rep((x[len] - x[1L])/(len - 1L), len - 1L)))
      }
      
      with(df, ave(value, id, FUN = myna.approx))
      ## [1] 100 250 400 550 300 500 700 900
      

      【讨论】:

      • 我接受了 zoo 解决方案,因为我认为一般人们会寻找预先存在的功能,即使我从您的回答中学到了更多。
      • 没关系,我也会使用na.approx。我只想说明的是,在 R 中,您应该尝试考虑向量化,并且 95% 的日常任务可以在不编写单个循环的情况下解决 - 无论乍一看任务有多难。
      猜你喜欢
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 2020-07-22
      • 2020-07-31
      • 2021-06-04
      • 1970-01-01
      相关资源
      最近更新 更多