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

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

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

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


person sia    schedule 07.04.2014    source источник
comment
Что делать, если соседнее значение тоже отсутствует? Может быть, попробуйте этот подход?   -  person Robert Krzyzanowski    schedule 07.04.2014


Ответы (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
person Henrik    schedule 07.04.2014

Предположим, у вас есть 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
person Jilber Urbina    schedule 07.04.2014
comment
использовал это для следующих действий: Если x = условие, замените x и следующие 2 значения на x-1 и x + 3. который изменяет код на: ind <- which(df$grade<(-100)) и df$grade[ind:ind+2] <- sapply(ind, function(i) with(df, mean(c(grade[i-1], grade[i+3])))) Для x ‹-100 - person Anne; 06.11.2015
comment
В качестве альтернативы вызову sapply вы также можете использовать: df$grade[ind] <- with(df, ((grade[ind-1] + grade[ind+1])/2)) - person Jaap; 31.03.2017

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