我有一个数据框,其中列有一些“我的价值”和39>:
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等微小数据帧上的数百万人做同样的事情。
非常感谢!
答案 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