1

我有一个包含缺失值的表,我正在尝试编写一个函数,该函数将用基于最接近的两个非零值的计算替换缺失值。

例子:

X  Tom    
1  4.3    
2  5.1    
3  NA    
4  NA    
5  7.4

对于X = 3, Tom = 5.1 + (7.4-5.1)/2.

对于X = 4, Tom = (5.1 + (7.4-5.1)/2) + (7.4-5.1)/2

这个功能是否已经存在?如果没有,任何建议将不胜感激。

4

3 回答 3

1

一种更常用的方法(但不等同于问题)是使用线性插值:

library(zoo)
df <- data.frame(X = 1:5, Tom = c(4.3, 5.1, NA, NA, 7.4))

na.approx(df)

或样条插值:

na.spline(df)
于 2014-03-29T20:56:36.183 回答
1

实际上imputeTS包(我是维护者)为此提供了一个很好的解决方案。

用移动平均线替换

 na_ma(x, k = 2)

x 是您的输入对象 k 是移动平均窗口

k of 1 意味着您只考虑之前和之后的值 k of 2 意味着您考虑之前的 2 个值和之后的 2 个值

该函数可能是最接近所需计算的函数。唯一的区别是 imputeTS 方法不会跳过 NA 值。(根据线程启动器的要求)

但特别是对于长时间的 NA 条纹来说,这是完全合理的。1, 2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 14, 15, 16(在第 3 位取 2 和 14 的平均值并不是一个好主意)

此外,最后一次观察前瞻(如评论中 42 所述)

imputeTS::na_locf(x)

插值(G. Grothendieck 也提到过)

imputeTS::na_interpolation(x)

还缺少一些朝同一方向发展的数据替换选项。如果你有兴趣,这里是R Journal 中对 imputeTS 包的介绍。

于 2017-04-18T23:20:07.393 回答
0

在这种情况下只需使用循环,其他方法要困难得多。

for (i in seq_len(nrow(df)) {
  if (is.na(df[i, 'Tom']))
    df[i, 'Tom'] <- ((tmp <- c(0, df$Tom[!is.na(df$Tom)], 0))[i+1] + tmp[i]) / 2 + tmp[i]
}

例子

df <- data.frame(X = seq_len(100), Tom = ifelse(runif(100, 0, 1) > 0.5, NA, round(runif(100, 0, 10), 1)))
head(df)
# X Tom
# 1 1  NA
# 2 1.4
# 3 3  NA
# 4 4 3.9
# 5 5  NA
for (i in seq_len(nrow(df))) { if (is.na(df[i, 'Tom']))  df[i, 'Tom'] <- ((tmp <- c(0, df$Tom[!is.na(df$Tom)], 0))[i+1] + tmp[i]) / 2 + tmp[i] }
head(df)
#  X  Tom
# 1 1 0.70
# 2 2 1.40
# 3 3 4.05
# 4 4 3.90
# 5 5 9.05
于 2014-03-29T20:43:20.503 回答