r用两个先前值的平均值替换每个缺失值

时间:2018-04-09 19:24:49

标签: r missing-data moving-average imputation

我有一个数据框,其中列有一些“我的价值”和

x <- data.frame(mydates = as.Date(c("2018/04/01","2018/04/02","2018/04/03","2018/04/04",
                                                     "2018/04/05","2018/04/06","2018/04/07","2018/04/08",
                                                     "2018/04/09","2018/04/10","2018/04/11")),
                                 myvalues = c(2.3, NA, 2.1, 2.2, NA, 2.4, 2.3, 2.1, NA, NA, 2.6))
x

我想用前两个值的平均值替换每个NA。对于第2行中的NA,它应该等于第1行中的值。 我可以使用&#39; for&#39;循环遍历x $ myvalues中的NA。但是,它非常慢,我正在寻找一个快速的解决方案,因为我必须对x等微小数据帧上的数百万人做同样的事情。

非常感谢!

3 个答案:

答案 0 :(得分:1)

data.table解决方案应该相当快:

library(data.table)

x <-
  data.frame(
    mydates = as.Date(
      c(
        "2018/04/01",
        "2018/04/02",
        "2018/04/03",
        "2018/04/04",
        "2018/04/05",
        "2018/04/06",
        "2018/04/07",
        "2018/04/08",
        "2018/04/09",
        "2018/04/10",
        "2018/04/11"
      )
    ),
    myvalues = c(2.3, NA, NA, 2.2, NA, NA, 2.3, NA, NA, NA, 2.6)
  )

# Carry forward mean of last two non-missing values
setDT(x)

x[, segment := cumsum(!is.na(myvalues))]
x[, last1 := myvalues[1], by = segment]
x[!is.na(myvalues), segment2:=segment]
x[is.na(myvalues), segment2:=segment-1]
x[, last2 := myvalues[1], by = segment2]
x[, repl:=rowMeans(.SD, na.rm=T), .SDcols=c("last1", "last2")]
x[, myvalues2:=myvalues]
x[is.na(myvalues2) & !is.nan(repl), myvalues2:=repl]

x[, list(mydates, myvalues, myvalues2)]
# mydates myvalues myvalues2
# 1: 2018-04-01      2.3      2.30
# 2: 2018-04-02       NA      2.30
# 3: 2018-04-03       NA      2.30
# 4: 2018-04-04      2.2      2.20
# 5: 2018-04-05       NA      2.25
# 6: 2018-04-06       NA      2.25
# 7: 2018-04-07      2.3      2.30
# 8: 2018-04-08       NA      2.25
# 9: 2018-04-09       NA      2.25
# 10: 2018-04-10       NA      2.25
# 11: 2018-04-11      2.6      2.60

答案 1 :(得分:1)

您可以减少Reduce功能。在这种情况下,例如,最后NA将是前两个值的平均值,但它首先填充先前的值,然后使用它来获取当前值

x$myvalues=Reduce(function(x,y)if(is.na(y))c(x,mean(tail(x,2))) else c(x,y),x$myvalues)
> x
      mydates myvalues
1  2018-04-01     2.30
2  2018-04-02     2.30
3  2018-04-03     2.10
4  2018-04-04     2.20
5  2018-04-05     2.15
6  2018-04-06     2.40
7  2018-04-07     2.30
8  2018-04-08     2.10
9  2018-04-09     2.20
10 2018-04-10     2.15
11 2018-04-11     2.60

答案 2 :(得分:0)

矢量化解决方案,如果您需要速度:

lost

以上版本的NA为第二个值,因为在第一个NA之前没有2个值取平均值。如果您希望此NA为其前面唯一值的平均值,那么我们可以改为:

Player