Пропущенные значения NA
Разбираемся с пропусками данных — значением NA — и учимся корректно считать статистики при их наличии.
NA (Not Available) — специальное значение, означающее «данные отсутствуют».
Реальные данные почти всегда неполные: кто-то не указал возраст, датчик сломался, ячейка пустая. R помечает такие дыры значением NA. Игнорировать их нельзя — иначе вычисления дадут неверный или «пустой» результат. Пропуски — одна из самых частых причин загадочных багов в анализе: код вроде бы правильный, а среднее внезапно равно NA. R здесь ведёт себя честно и осторожно: он не выдумывает значения за вас, а явно сигнализирует, что результат под вопросом. Научиться замечать и грамотно обрабатывать NA — обязательный навык любого, кто работает с настоящими данными.
NA заразен
Любая арифметика с NA даёт NA — ведь неизвестно, что прибавлять. Это видно при попытке посчитать среднее:
ages <- c(25, NA, 30, 41)
mean(ages)Вывод:
[1] NA
Один пропуск «отравил» весь результат. R не угадывает за вас — он честно сообщает, что точное среднее посчитать нельзя.
Аргумент na.rm
Чтобы посчитать статистику по имеющимся данным, многим функциям передают na.rm = TRUE — «удали NA перед расчётом»:
ages <- c(25, NA, 30, 41)
mean(ages, na.rm = TRUE)
sum(ages, na.rm = TRUE)Вывод:
[1] 32 [1] 96
Теперь R посчитал среднее по трём известным значениям: (25 + 30 + 41) / 3 = 32.
Поиск пропусков
Найти, где именно дыры, помогает is.na — она возвращает логический вектор:
ages <- c(25, NA, 30, NA)
is.na(ages)
sum(is.na(ages))Вывод:
[1] FALSE TRUE FALSE TRUE [1] 2
Приём sum(is.na(x)) — стандартный способ сосчитать количество пропусков: логические TRUE превращаются в 1.
Как работает под капотом
Нельзя сравнивать с NA обычным ==: выражение x == NA вернёт не TRUE, а снова NA — ведь неизвестное не равно и не не равно ничему. Именно поэтому существует отдельная функция is.na. Это частая ловушка: новички пишут x[x == NA] и получают пустоту вместо пропусков; правильно — x[is.na(x)].
Частые ошибки
- Забыть
na.rm = TRUE. Тогдаmean,sum,sdвернут NA при наличии хоть одного пропуска. - Сравнивать с NA через
==. Используйте толькоis.na(). - Путать NA и NULL. NA — «нет значения в ячейке», NULL — «нет самого объекта». Это разные вещи.
Итог
NA— отсутствующее значение, оно «заражает» вычисления.na.rm = TRUEзаставляет функцию игнорировать пропуски.is.na(x)находит пропуски,sum(is.na(x))их считает.- Сравнивать с NA через
==нельзя — только черезis.na.