2016-07-27 1 views
0

У меня есть данные о датах посещений и личных идентификаторов:Эффективность при ранжировании дат с использованием data.table в R

n  <- 1e6 
set.seed(42L) 
DT <- data.table(id = sample(1:37000, n, replace=TRUE), 
       date = as.Date("1963-07-13", "%Y-%m-%d") 
       - sample(1:9000, n, replace=TRUE)) 

Я добавляю переменную, которая ранжирует посещения для каждого человека. Посетите # 1, # 2 и т. Д. Если я не могу различать два посещения, они могут быть ранжированы любым (последовательным) способом.

После моего последнего question (по эффективности) Я понял, что должен научиться использовать data.table. Итак, мое текущее решение - с data.table - единственная проблема заключается в том, что для выполнения команды требуется несколько секунд.

> system.time(DT[, visit.n := rank(date, ties.method="first"), by = id] 
+) 
    user system elapsed 
    4.42 0.02 4.44 

Интересно, что я делаю что-то «неправильно» или просто нужно быть терпеливым и двигаться дальше.

+1

Попробуйте 'setkey (DT, дата); system.time (DT [, visit.n: = 1: .N, by = id]) ' –

+2

Предполагая, что вам нравятся ваши смешные даты, как они есть, вы можете просто использовать порядок (дату) в i для сортировки только для этой цели создания нового col. И если вы заботитесь о производительности, вы можете рассмотреть целочисленные форматы хранения для дат, поэтому 'system.time (DT [, date: = as.IDate (date)] [order (date), visit.n: = 1: .N ]) 'Я вижу, что это занимает половину времени установки Мартина. Также обратите внимание, что автор пакета говорит: «В большинстве случаев поэтому больше не нужно устанавливать ключи». http://stackoverflow.com/a/20057411/ – Frank

+1

Интересно. Но ваша строка кода не дает желаемого результата, не так ли? При добавлении 'by = id' (так что результат корректен), производительность снова удваивается ... –

ответ

4

Взятые из моего комментария:

Как @Frank отметил, setkey не является необходимым. Для этого используем order(date). Я также включил его пункт сохранения дат как целых чисел.

system.time({ 
    DT[, date := as.IDate(date)][order(date), visit.n := 1:.N, by=id] 
}) 

    user  system  elapsed 
    0.126  0.005  0.132 
+0

Отличное улучшение! Но я также попробовал «setkey (DT, id)», и это было еще быстрее. – snoram

+0

Правильно, применил ваше замечание. –

+1

Установленный ключ принадлежит времени; 1: .N теперь доступен в функции rowid (id); и setkey редко необходимы (см. комментарий выше). Просто фью. О, я думаю, что rowid все еще только в версии devel. – Frank

Смежные вопросы