将NA替换为R中的上一行和下一行

时间:2014-04-07 15:18:05

标签: r replace na

如何以快速方式将NA替换为其上一行和下一行的平均值?

  name grade
1    A    56
2    B    NA
3    C    70
4    D    96

这样B的等级将是63。

3 个答案:

答案 0 :(得分:10)

或者您可以尝试na.approx包中的zoo:“缺失值(NAs)将替换为线性插值”

library(zoo)
x <- c(56, NA, 70, 96)
na.approx(x)
# [1] 56 63 70 96

如果您有多个连续的NA

,这也有效
vals <- c(1, NA, NA, 7, NA, 10)
na.approx(vals) 
# [1]  1.0  3.0  5.0  7.0  8.5 10.0

na.approx基于base函数approx,可以代之以使用:

vals <- c(1, NA, NA, 7, NA, 10)
xout <- seq_along(vals)
x <- xout[!is.na(vals)]
y <- vals[!is.na(vals)]

approx(x = x, y = y, xout = xout)$y
# [1]  1.0  3.0  5.0  7.0  8.5 10.0

答案 1 :(得分:8)

假设您有这样的data.frame df

> df
  name grade
1    A    56
2    B    NA
3    C    70
4    D    96
5    E    NA
6    F    95

然后您可以使用以下内容:

> ind <- which(is.na(df$grade))
> df$grade[ind] <- sapply(ind, function(i) with(df, mean(c(grade[i-1], grade[i+1]))))
> df
  name grade
1    A    56
2    B    63
3    C    70
4    D    96
5    E  95.5
6    F    95

答案 2 :(得分:0)

使用中位数而不是均值的替代解决方案由na.roughfix包的randomForest函数表示。 如documentation中所述,它适用于数据框或数字矩阵。 具体来说,对于数字变量,NAs将替换为列中位数。对于因子变量,NAs被替换为最频繁的级别(随机断开关系)。如果对象不包含NAs,则会不加改变地返回。

使用与@Henrik相同的例子,

library(randomForest)
x <- c(56, NA, 70, 96) 
na.roughfix(x)

#[1] 56 70 70 96

或使用更大的矩阵:

y <- matrix(1:50, nrow = 10)
y[sample(1:length(y), 4, replace = FALSE)] <- NA
y
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1   11   21   31   41
# [2,]    2   12   22   32   42
# [3,]    3   NA   23   33   NA
# [4,]    4   14   24   34   44
# [5,]    5   15   25   35   45
# [6,]    6   16   NA   36   46
# [7,]    7   17   27   37   47
# [8,]    8   18   28   38   48
# [9,]    9   19   29   39   49
# [10,]   10  20   NA   40   50

na.roughfix(y)
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1   11 21.0   31   41
# [2,]    2   12 22.0   32   42
# [3,]    3   16 23.0   33   46
# [4,]    4   14 24.0   34   44
# [5,]    5   15 25.0   35   45
# [6,]    6   16 24.5   36   46
# [7,]    7   17 27.0   37   47
# [8,]    8   18 28.0   38   48
# [9,]    9   19 29.0   39   49
#[10,]   10   20 24.5   40   50