Как я могу быстро заменить NA на среднее значение из предыдущих и следующих строк?
name grade
1 A 56
2 B NA
3 C 70
4 D 96
так что оценка B будет 63.
Как я могу быстро заменить NA на среднее значение из предыдущих и следующих строк?
name grade
1 A 56
2 B NA
3 C 70
4 D 96
так что оценка B будет 63.
Или вы можете попробовать 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
Предположим, у вас есть 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
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
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