我有一个包含缺失值的表,我正在尝试编写一个函数,该函数将用基于最接近的两个非零值的计算替换缺失值。
例子:
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
这个功能是否已经存在?如果没有,任何建议将不胜感激。
我有一个包含缺失值的表,我正在尝试编写一个函数,该函数将用基于最接近的两个非零值的计算替换缺失值。
例子:
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
这个功能是否已经存在?如果没有,任何建议将不胜感激。
一种更常用的方法(但不等同于问题)是使用线性插值:
library(zoo)
df <- data.frame(X = 1:5, Tom = c(4.3, 5.1, NA, NA, 7.4))
na.approx(df)
或样条插值:
na.spline(df)
实际上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 包的介绍。
在这种情况下只需使用循环,其他方法要困难得多。
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