0Pricing
R Academy · Урок

Удаление и замена значений 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 — локальная установка не требуется.

Все уроки этого курса

  1. Понимание NA в R
  2. Обнаружение и подсчёт пропущенных значений
  3. Удаление и замена значений NA
  4. NA в вычислениях и агрегациях
← Назад к R Academy