【问题标题】:Replace NA with previous and next rows mean in R将 NA 替换为 R 中的上一行和下一行均值
【发布时间】:2014-05-19 22:31:25
【问题描述】:

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

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

这样 B 的成绩是 63。

【问题讨论】:

  • 如果相邻的值也丢失了怎么办?也许试试this approach

标签: r replace na


【解决方案1】:

使用中位数而不是均值的替代解决方案由randomForest 包的na.roughfix 函数表示。 如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

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

      【解决方案3】:

      假设你有一个这样的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
      

      【讨论】:

      • 使用它来执行以下操作:如果 x=condition,则将 x 和下 2 个值替换为 x-1 和 x+3。将代码更改为:ind &lt;- which(df$grade&lt;(-100))df$grade[ind:ind+2] &lt;- sapply(ind, function(i) with(df, mean(c(grade[i-1], grade[i+3])))) For x
      • 作为sapply 调用的替代方法,您还可以使用:df$grade[ind] &lt;- with(df, ((grade[ind-1] + grade[ind+1])/2))
      猜你喜欢
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多