Удаление и замена значений NA
Применяйте na.omit(), complete.cases() и стратегии ручной замены.
«Удаление и замена значений NA» — бесплатный урок R Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.
Стратегии обработки NA
Существует три основные стратегии обработки пропущенных значений: удалить их, заменить константой или восстановить с помощью статистической оценки. Выбор подхода зависит от данных и целей анализа.
data_vals <- c(88, NA, 72, NA, 91, 65, NA, 78)
cat('Original data:', data_vals, '
')
cat('NA count:', sum(is.na(data_vals)), '
')
# Strategy 1: remove
cat('After removal:', data_vals[!is.na(data_vals)], '
')
# Strategy 2: replace with 0
replaced <- data_vals; replaced[is.na(replaced)] <- 0
cat('Replaced with 0:', replaced, '
')Удаление NA с помощью x[!is.na(x)]
Самый прямой способ удалить NA из вектора — логическая выборка: x[!is.na(x)]. Она сохраняет только элементы, для которых is.na(x) равно FALSE (то есть присутствующие значения).
response_times <- c(1.2, NA, 0.9, 1.5, NA, 1.1, 0.8, NA, 1.3)
cat('With NAs: ', response_times, '
')
cat('Length:', length(response_times), '
')
clean_times <- response_times[!is.na(response_times)]
cat('Without NAs: ', clean_times, '
')
cat('Length:', length(clean_times), '
')
cat('Mean after removal:', round(mean(clean_times), 3), '
')na.omit() для векторов
na.omit(x) удаляет значения NA из вектора. Это эквивалентно x[!is.na(x)], но дополнительно сохраняет позиции удалённых NA в атрибуте с именем 'na.action'.
scores <- c(88, NA, 72, NA, 91, 65, NA, 78)
clean_scores <- na.omit(scores)
cat('Original:', scores, '
')
cat('Cleaned: ', as.numeric(clean_scores), '
')
# na.omit records which positions were removed
removed_at <- attr(clean_scores, 'na.action')
cat('NAs were at positions:', removed_at, '
')na.omit() для таблиц данных
При применении к таблице данных na.omit(df) удаляет любую строку, содержащую хотя бы одно NA. Это называется построчным удалением — всё наблюдение удаляется целиком.
df <- data.frame(
name = c('Alice', 'Bob', 'Carol', 'Dave', 'Eve'),
age = c(28, NA, 32, 45, 29),
salary = c(55000, 72000, NA, 90000, 61000)
)
cat('Original rows:', nrow(df), '
')
df_clean <- na.omit(df)
cat('After na.omit rows:', nrow(df_clean), '
')
print(df_clean)complete.cases() — полнота по строкам
complete.cases(df) возвращает логический вектор, содержащий TRUE для строк без пропущенных значений. Используйте его, чтобы отфильтровать полные строки или определить неполные строки.
df <- data.frame(
id = 1:5,
x = c(1, NA, 3, 4, NA),
y = c(NA, 2, 3, NA, 5)
)
cc <- complete.cases(df)
cat('Complete cases (T/F):', cc, '
')
cat('Complete rows:
')
print(df[cc, ])
cat('Number complete:', sum(cc), '
')Замена NA константой
Чтобы заменить NA определённым значением, используйте логическое присваивание: x[is.na(x)] <- value. Обычно для количества используют 0, для непрерывных данных — среднее или медиану, а для факторов — метку категории.
# Replace with 0
counts <- c(5, NA, 3, NA, 8, 1, NA, 4)
counts_filled <- counts
counts_filled[is.na(counts_filled)] <- 0
cat('Original:', counts, '
')
cat('Filled: ', counts_filled, '
')
# Replace with mean of present values
mean_val <- mean(counts, na.rm = TRUE)
counts_mean <- counts
counts_mean[is.na(counts_mean)] <- mean_val
cat('Mean-filled:', round(counts_mean, 1), '
')replace() — функциональная замена
replace(x, list, values) возвращает изменённую копию x, в которой элементы на позициях list заменены значениями values. Это функциональный подход к замене, не изменяющий исходный объект.
temps <- c(22.1, NA, 19.8, NA, 25.1)
cat('Original:', temps, '
')
# Replace NAs with the median
median_temp <- median(temps, na.rm = TRUE)
filled_temps <- replace(temps, is.na(temps), median_temp)
cat('Filled: ', filled_temps, '
')
cat('Original unchanged:', temps, '
') # original not modifiedЗаполнение вперёд (Last Observation Carried Forward)
Распространённая стратегия восстановления — заполнение вперёд (LOCF): каждое NA заменяется последним известным значением. Этот подход используют для данных временных рядов, в которых измерение сохраняется до следующего обновления.
# Manual forward-fill
readings <- c(10, NA, NA, 13, NA, 15, NA, NA, 18)
filled <- readings
for (i in seq_along(filled)) {
if (is.na(filled[i]) && i > 1) {
filled[i] <- filled[i - 1]
}
}
cat('Original: ', readings, '
')
cat('Forward-filled:', filled, '
')Замена NA в текстовых векторах
Те же методы работают и для текстовых векторов. В анализе категориальных данных часто заменяют NA в строках меткой вроде 'Unknown' или 'Missing'.
categories <- c('A', NA, 'B', 'A', NA, 'C', NA, 'B')
cat('Original:', categories, '
')
# Replace with 'Unknown'
filled_cat <- replace(categories, is.na(categories), 'Unknown')
cat('Filled: ', filled_cat, '
')
# Count each category
cat('Table:
')
print(table(filled_cat))Стратегия условной замены
Иногда нужно использовать разные значения замены в зависимости от значения другого столбца. Применяйте индексацию с условиями, чтобы выполнять выборочную замену.
# Scores: replace NA with group mean
group <- c('A', 'A', 'B', 'B', 'A', 'B')
scores <- c(85, NA, 72, NA, 90, 78)
mean_a <- mean(scores[group == 'A'], na.rm = TRUE)
mean_b <- mean(scores[group == 'B'], na.rm = TRUE)
imputed <- scores
imputed[is.na(imputed) & group == 'A'] <- mean_a
imputed[is.na(imputed) & group == 'B'] <- mean_b
cat('Original:', scores, '
')
cat('Imputed: ', imputed, '
')Сводка методов удаления NA
Сводка инструментов обработки NA в R:
x[!is.na(x)]— удалить NA из вектораna.omit(x)— удалить NA (также сохранить их позиции)na.omit(df)— удалить неполные строки из таблицы данныхcomplete.cases(df)— логический вектор: TRUE для полных строкx[is.na(x)] <- val— заменить NA на местеreplace(x, is.na(x), val)— функциональная замена (возвращает копию)
v <- c(5, NA, 8, NA, 3, 7)
cat('Remove: ', v[!is.na(v)], '
')
cat('Replace with 0: ', replace(v, is.na(v), 0), '
')
cat('Replace with mean:', replace(v, is.na(v), mean(v, na.rm=TRUE)), '
')Быстрая проверка
Что возвращает na.omit(c(1, NA, 3, NA, 5))?
Итоги: удаление и замена NA
Отличная работа! Основные выводы этого урока:
x[!is.na(x)]иna.omit(x)удаляют NA из вектораna.omit(df)выполняет построчное удаление (удаляет любую строку с NA)complete.cases(df)определяет строки без пропущенных значенийx[is.na(x)] <- valueзаменяет NA на местеreplace(x, is.na(x), value)возвращает изменённую копию, не меняя исходный объект- Выбирайте стратегию с учётом причины появления пропущенных данных и их количества
# Complete workflow: audit, then handle
data_raw <- c(82, NA, 75, NA, 91, 68, NA, 79)
cat('Missing:', sum(is.na(data_raw)), '/', length(data_raw), '
')
# Replace with median (robust to outliers)
imputed <- replace(data_raw, is.na(data_raw), median(data_raw, na.rm=TRUE))
cat('Before imputation mean:', round(mean(data_raw, na.rm=TRUE), 2), '
')
cat('After imputation mean: ', round(mean(imputed), 2), '
')Часто задаваемые вопросы
Урок «Удаление и замена значений NA» бесплатный?
Да — полный текст урока «Удаление и замена значений NA» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.
Чему я научусь в уроке «Удаление и замена значений NA»?
Применяйте na.omit(), complete.cases() и стратегии ручной замены. Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать R Academy?
Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Удаление и замена значений NA»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке R Academy?
Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Понимание NA в R
- Обнаружение и подсчёт пропущенных значений
- Удаление и замена значений NA
- NA в вычислениях и агрегациях