2015-02-17 5 views
1

Я пытаюсь применить функцию ко всем строкам таблицы данных при использовании нескольких столбцов в качестве входов с выходом, который может быть одним или две строки файла data.frame/matrix/what-have-you для каждой строки. Моя таблица данных имеет 800 000 строк.R data.table применяет функцию с несколькими входами столбца по всем строкам и получает разумный вывод

вот моя самая близкая попытка. То, что здесь играет, - это, конечно, правильность, эффективность и простота использования с выходной структурой.

library(data.table) 
d0 = as.Date("2014/01/01") 
sdays = seq(d0,d0+99,by=1) 
gg=data.table(id=1:100,event_date = sdays) 
setkey(gg, id) 

test_func = function(id,day){ 
    delta = day - d0 
    if(delta == 0){ 
    rcomb = c(id, 0, 100, 1,0) 
    } else if(delta != 100){ 
    r1 = c(id, 0, delta, 0, 0) 
    r2 = c(id, delta, 100, 1, 0) 
    rcomb = rbind(r1,r2) 
    } 
    rcomb 
} 

att = gg[, test_func(get("id"), get("event_date")), by=id] 
att 

Любые идеи о том, как использовать быстрые data.table трюки здесь? Я занимался этим часами и не стал намного ближе:/Что касается вывода, я бы предпочел, чтобы это был список с одной записью на исходную строку, поэтому я мог просто позвонить do.call и rbind. Благодаря!

Итак, позвольте мне привести пример желаемых результатов, но ужасно неэффективно:

some_list = vector("list", 100) 
for(i in 1:100) { 
    some_list[[i]] <- test_func(gg$id[i], gg$event_date[i]) 
} 
happy=do.call(rbind,some_list) 
head(happy) 
    [,1] [,2] [,3] [,4] [,5] 
     1 0 100 1 0 
r1 2 0 1 0 0 
r2 2 1 100 1 0 
r1 3 0 2 0 0 
r2 3 2 100 1 0 
r1 4 0 3 0 0 
+0

Думаю, вам не нужно 'get' здесь. 'gg [, test_func (id, event_date), id]' – akrun

+0

да, хорошая точка! Но он по-прежнему дает неправильный результат: | –

+0

Каков ожидаемый результат в соответствии с вашим примером набора данных? – akrun

ответ

1

Если вы хотите создать 4 колонки для data.table, что-то вроде следующего будет работать

test_func = function(day){ 
    delta = day - d0 
    if(delta == 0){ 
     rcomb = list(0, 100, 1,0) 
    } else if(delta != 100){ 
    rcomb <- list(c(0,delta), c(100,delta), c(0,1), c(0,0)) 

    } 
    rcomb 
} 

att = gg[, test_func(event_date), by=id] 
att 
+0

Кажется, неплохо работает 2k! Давайте посмотрим, как он масштабируется до 800k –

+0

. Это все еще слишком медленно:/ваше решение верно в тестовом примере. Думаю, я мог бы просто попытаться распараллелить это ... –

+0

Woah, я почти сдался, но это заняло что-то вроде минуты, плюс или минус. Пока это лучший вариант, с которым я смог работать, так что спасибо! –