Заменить NA предыдущими и следующими строками в R

Как я могу быстро заменить NA на среднее значение его предыдущей и следующей строк?

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

такой, что оценка B будет 63.

3 ответов


или вы можете попробовать 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

Предположим, у вас есть данные.кадр 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

альтернативное решение, использующее медиану вместо среднего, представлено . Как описано в документация, он работает с фреймом данных или цифровой матрицы. В частности, для числовых переменных, 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