У меня есть большая таблица данных , со многими пропущенными значениями, разбросанными по строкам ~ 200 тыс. И 200 столбцам. Я хотел бы как можно более эффективно перекодировать эти значения NA в нули.
Я вижу два варианта:
1: преобразовать в data.frame и использовать что-то вроде этого
2: какая-то классная команда подустановки data.table
Я буду счастлив с довольно эффективным решением типа 1. Преобразование в data.frame и затем обратно в data.table не займет много времени.
data.table
кdata.frame
?data.table
Являетсяdata.frame
. Любая операция data.frame будет просто работать.data.table
, указав номер столбца. такDT[,3]
что третьего столбца не дадут. я думаю, что это делает решение, предлагаемое по ссылке, нежизнеспособным здесь. Я уверен, что есть элегантный подход с использованием некоторыхdata.table
волшебства!DT[, 3, with=FALSE]
возвращает третий столбец.mydf[is.na(mydf) == TRUE]
с работой с фреймами данных, в то время какmydt[is.na(mydt) == TRUE]
дает мне что-то странное, даже если я используюwith=FALSE
Ответы:
Вот решение с использованием data.table «S
:=
оператора, основываясь на Andrie и ответы Ramnath в.Обратите внимание, что f_dowle обновил dt1 по ссылке. Если требуется локальная копия, то
copy
для создания локальной копии всего набора данных необходим явный вызов функции. data.table'ssetkey
,key<-
а:=
не копировать при записи.Далее, давайте посмотрим, где f_dowle проводит свое время.
Там я бы сосредоточился
na.replace
и тамis.na
, где есть несколько векторных копий и векторных сканов. Их можно легко устранить, написав небольшую C-функцию na.replace, которая обновляетсяNA
по ссылке в векторе. Это, по крайней мере, вдвое сократило бы 20 секунд, я думаю. Существует ли такая функция в любом пакете R?Причина
f_andrie
сбоя может быть в том, что он копируетdt1
или создает логическую матрицу размером с целоеdt1
несколько раз. Другие 2 метода работают с одним столбцом за раз (хотя я только кратко рассмотрелNAToUnknown
).РЕДАКТИРОВАТЬ (более элегантное решение в соответствии с просьбой Рамната в комментариях):
Я хотел бы сделать это таким образом, чтобы начать с!
EDIT2 (более 1 года спустя, сейчас)
Есть также
set()
. Это может быть быстрее, если[,:=,]
через цикл проходит много столбцов, поскольку это позволяет избежать (небольших) накладных расходов на вызов в цикле.set
это петли:=
. См?set
.источник
eval(parse)...
материала. в более широком смысле, я думаю, было бы полезно иметь операции, которые работают со всеми элементамиdata.table
.data.table
подходящим способом сделать это. Спасибо!DT
есть столбцы типаlogical
, в отличие отcreate_dt()
примера для этого теста. Измените 4-й аргументset()
вызова (который0
в вашем примере и введите double в R),FALSE
и он должен работать без предупреждения.seq_along(DT)
тоже предпочитаю . Но тогда читатель должен знать, чтоseq_along
будет по столбцам, а не по строкам.seq_len(col(DT))
чуть более явно по этой причине.Вот самый простой, который я мог придумать:
dt[is.na(dt)] <- 0
Это эффективно и не требует написания функций и другого связующего кода.
источник
[.data.table
(dt, is.na (dt)): я недопустимый тип (матрица). Возможно, в будущем матрица из 2 столбцов могла бы вернуть список элементов DT (в духе A [B] в FAQ 2.14). Пожалуйста, сообщите datatable-help, хотите ли вы этого, или добавьте свои комментарии в FR # 657. >set
Выделенные функции (
nafill
иsetnafill
) для этой цели доступны вdata.table
пакете (версия> = 1.12.4):Он обрабатывает столбцы параллельно, так что хорошо справляется с ранее опубликованными контрольными показателями, ниже своего времени по сравнению с самым быстрым до настоящего времени подходом, а также масштабируется, используя 40-ядерный компьютер.
источник
Просто для справки, медленнее по сравнению с gdata или data.matrix, но использует только пакет data.table и может работать с нечисловыми записями.
источник
ifelse
и обновить по ссылке, выполнивDT[, names(DT) := lapply(.SD, function(x) {x[is.na(x)] <- "0" ; x})]
. И я сомневаюсь, что это будет медленнее, чем ответы, которые вы упомянули.Вот решение с использованием
NAToUnknown
вgdata
пакете. Я использовал решение Andrie для создания огромной таблицы данных, а также включил сравнение времени с решением Andrie.источник
user
временем, но очень большой разницей воelapsed
времени.rbenchmark
для сравнения решений с использованием большего количества репликаций, но получил ошибку нехватки памяти, возможно, из-за размера фрейма данных. если вы сможете запуститьbenchmark
оба этих решения с несколькими репликациями, эти результаты будут интересны, поскольку я не совсем уверен, почему я получаю ускорение в 3 разаncol=5
мне кажется (должны занять гораздо больше времени) из-за ошибки вcreate_dt
.Ради полноты, другой способ заменить NA на 0 - это использовать
Чтобы сравнить результаты и время, я включил все упомянутые подходы.
Таким образом, новый подход немного медленнее,
f_dowle3
чем все остальные. Но, честно говоря, это противоречит моей интуиции синтаксиса data.table, и я понятия не имею, почему это работает. Кто-нибудь может просветить меня?источник
Насколько я понимаю, секрет быстрых операций в R заключается в использовании вектора (или массивов, которые являются векторами под капотом).
В этом решении я использую a,
data.matrix
который является,array
но ведет себя немного как adata.frame
. Поскольку это массив, вы можете использовать очень простую векторную замену для заменыNA
s:Маленькая вспомогательная функция для удаления
NA
s. Суть в одной строке кода. Я делаю это только для измерения времени выполнения.Маленькая вспомогательная функция для создания
data.table
заданного размера.Демонстрация на крошечном образце:
источник
remove_na
. Это время 21,57 включает в себяcreate_dt
(в том числеrunif
иsample
) вместе сremove_na
. Есть ли у вас шанс отредактировать, чтобы разделить 2 раза?create_dt
? Кажется, он всегда создает таблицу данных из 5 столбцов, независимо от того, что былоncol
передано.Чтобы обобщить многие столбцы, вы можете использовать этот подход (используя данные предыдущего примера, но добавив столбец):
Хотя не проверял на скорость
источник
источник
Используя
fifelse
функцию из новейшихdata.table
версий 1.12.6, она даже в 10 раз быстрее, чемNAToUnknown
вgdata
пакете:источник
f_dowle3
все еще будет быстрее: stackoverflow.com/a/7249454/345660