У меня есть фрейм данных и некоторые столбцы имеют NA
значения.
Как заменить эти NA
значения нулями?
r
dataframe
na
missing-data
imputation
Ренато Динхани
источник
источник
Ответы:
Смотрите мой комментарий в ответе @ gsk3. Простой пример:
Там нет необходимости применять
apply
. знак равноРЕДАКТИРОВАТЬ
Вы также должны взглянуть на
norm
пакет. Он имеет много приятных возможностей для анализа отсутствующих данных. знак равноисточник
df[19:28][is.na(df[19:28])] <- 0
Гибридизированные опции dplyr теперь примерно на 30% быстрее, чем переназначение подгруппы Base R. На 100-мегапиксельной базе данных точка данных
mutate_all(~replace(., is.na(.), 0))
работает на полсекунды быстрее, чемd[is.na(d)] <- 0
опция base R. То, что человек хочет избежать, в частности, используетifelse()
илиif_else()
. (Полный 600-кратный пробный анализ занял более 4,5 часов, в основном из-за включения этих подходов.) См. Ниже результаты сравнительного анализа для получения полных результатов.Если вы боретесь с массивными фреймами данных,
data.table
это самый быстрый вариант из всех: на 40% быстрее, чем стандартный подход Base R. Он также изменяет данные на месте, эффективно позволяя работать с почти вдвое большим количеством данных одновременно.Кластеризация других полезных подходов замены Tidyverse
Locationally:
mutate_at(c(5:10), ~replace(., is.na(.), 0))
mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))
contains()
, попробуйтеends_with()
,starts_with()
mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
Условно:
(измените только один тип и оставьте другие типы в покое.)
mutate_if(is.integer, ~replace(., is.na(.), 0))
mutate_if(is.numeric, ~replace(., is.na(.), 0))
mutate_if(is.character, ~replace(., is.na(.), 0))
Полный анализ -
Обновлено для dplyr 0.8.0: функции используют символы формата purrr
~
: замена устаревшихfuns()
аргументов.Подходы проверены:
Код для этого анализа:
Сводка результатов
Boxplot of Results
Цветовая диаграмма рассеяния испытаний (с осью Y в логарифмическом масштабе)
Примечание о других высоких исполнителей
Когда наборы данных становятся больше, Tidyr 's
replace_na
исторически вышли впереди. Благодаря текущему набору 100M точек данных, он работает почти так же хорошо, как и Base R For Loop. Мне любопытно посмотреть, что происходит для разных размеров данных.Дополнительные примеры для вариантов
mutate
иsummarize
_at
и_all
можно найти здесь: https://rdrr.io/cran/dplyr/man/summarise_all.html Кроме того, я нашел полезные демонстрации и коллекции примеров здесь: https: //blog.exploratory. -й / dplyr-0-5-это-удивительный-Херес-почему-be095fd4eb8aАтрибуты и благодарности
С особой благодарностью:
local()
, и (с помощью пациента Фрэнка тоже) роль, которую тихое принуждение играет в ускорении многих из этих подходов.coalesce()
функцию и обновить анализ.data.table
функции достаточно хорошо, чтобы, наконец, включить их в состав.is.numeric()
самом деле тестирует.(Конечно, пожалуйста, подойдите и отдайте им голоса, если вы найдете такие подходы полезными.)
Примечание по использованию чисел: если у вас есть чистый набор целочисленных данных, все ваши функции будут работать быстрее. Пожалуйста, смотрите работу alexiz_laz для получения дополнительной информации. IRL, я не могу вспомнить, чтобы встретил набор данных, содержащий более 10-15% целых чисел, поэтому я запускаю эти тесты на полностью числовых фреймах данных.
Используемое оборудование Процессор 3,9 ГГц с 24 ГБ ОЗУ
источник
df1[j][is.na(df1[j])] = 0
это неправильно, должно бытьdf1[[j]][is.na(df1[[j]])] = 0
forLp_Sbst
не похоже, что кто-то должен подумать о том, чтобы приблизиться к немуforLp_smplfSbst
coalesce()
опцию и запускаю все время. Спасибо за толчок для обновления.Для одного вектора:
Для data.frame сделайте функцию из вышеперечисленного, затем переместите
apply
ее в столбцы.Пожалуйста, предоставьте воспроизводимый пример в следующий раз, как подробно здесь:
Как сделать отличный R воспроизводимый пример?
источник
is.na
является универсальной функцией и имеет методы для объектовdata.frame
класса. так что этот тоже будет работать наdata.frame
с!methods(is.na)
в первый раз, я был как вааааааааааа! , Я люблю, когда такие вещи случаются! =)Пример dplyr:
Примечание. Это работает для каждого выбранного столбца. Если нам нужно сделать это для всех столбцов, см. Ответ @reidjax с использованием mutate_each .
источник
Если мы пытаемся заменить
NA
s при экспорте, например, при записи в csv, тогда мы можем использовать:источник
Я знаю, что на этот вопрос уже дан ответ, но для некоторых это может быть полезно:
Определите эту функцию:
Теперь, когда вам нужно преобразовать NA в векторе в ноль, вы можете сделать:
источник
С
dplyr
0.5.0 вы можете использоватьcoalesce
функцию, которая может быть легко интегрирована в%>%
конвейерcoalesce(vec, 0)
. Это заменяет все NA наvec
0:Скажем, у нас есть фрейм данных с
NA
s:источник
Более общий подход использования
replace()
в матрицы или вектора заменитьNA
на0
Например:
Это также альтернатива использованию
ifelse()
вdplyr
источник
levels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
which
здесь не нужно, вы можете использоватьx1 <- replace(x,is.na(x),1)
.NA
на0
всего один конкретном столбце в большом кадре данных и эта функцияreplace()
работала наиболее эффективно , а также наиболее просто.Также возможно использовать
tidyr::replace_na
.источник
Еще один пример использования пакета imputeTS :
источник
Если вы хотите заменить NA в факторных переменных, это может быть полезно:
Он преобразует фактор-вектор в числовой вектор и добавляет еще один искусственный уровень числового фактора, который затем преобразуется обратно в фактор-вектор с одним дополнительным «уровнем NA» по вашему выбору.
источник
Я бы прокомментировал сообщение @ ianmunoz, но мне не хватает репутации. Вы можете комбинировать
dplyr
«Smutate_each
иreplace
чтобы заботиться оNA
для0
замены. Используя фрейм данных из ответа @ aL3xa ...Мы используем стандартную оценку (SE), поэтому нам нужно подчеркнуть "
funs_
." Мы также используемlazyeval
sinterp
/~
и.
ссылки «все, с чем мы работаем», то есть фрейм данных. Теперь есть нули!источник
Ты можешь использовать
replace()
Например:
источник
NA
s в вашем векторе. Это хорошо для небольших векторов, как в вашем примере.x1 <- replace(x,is.na(x),1)
будет работать без явного перечисления значений индекса.Еще одна
dplyr
совместимая с конвейером опция сtidyr
методом,replace_na
который работает для нескольких столбцов:Вы можете легко ограничить, например, числовые столбцы:
источник
Выделенная функция (
nafill
/setnafill
) для этой цели в последнейdata.table
версииисточник
Эта простая функция, извлеченная из Datacamp, может помочь:
затем
источник
Самый простой способ , чтобы написать это с
if_na
изhablar
:который возвращает:
источник
Чтобы заменить все NA в кадре данных, вы можете использовать:
df %>% replace(is.na(.), 0)
источник
если вы хотите назначить новое имя после изменения NA в определенном столбце в этом случае столбец V3, используйте вы можете сделать также, как это
источник