R data.table применяет функцию с вводом нескольких столбцов по всем строкам и получает разумный результат

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

Вот моя ближайшая попытка. Здесь важны, конечно же, правильность, эффективность и простота использования выходной структуры.

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

person interested_in_the_world    schedule 17.02.2015    source источник
comment
Я думаю, вам не нужно get здесь. gg[,test_func(id, event_date), id]   -  person akrun    schedule 17.02.2015
comment
да, хорошая мысль! Но все равно дает неверный результат :|   -  person interested_in_the_world    schedule 17.02.2015
comment
Каков ожидаемый результат в соответствии с вашим примером набора данных?   -  person akrun    schedule 17.02.2015
comment
Не совсем так.. если вы посмотрите на head(att,n=20), вы заметите неправильный шаблон, который последовательно соединяет последние части каждого вектора. Это также проблема, потому что в данных нельзя быть уверенным, будет ли вывод в 1 или 2 строки. Изменить: В ответ на транспонированный комментарий   -  person interested_in_the_world    schedule 17.02.2015


Ответы (1)


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

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
person mnel    schedule 17.02.2015
comment
За 2к вроде нормально работает! Посмотрим, как он масштабируется до 800 тыс. - person interested_in_the_world; 17.02.2015
comment
Это все еще слишком медленно: / ваше решение верно в тестовом примере. Я думаю, я мог бы просто попытаться распараллелить это... - person interested_in_the_world; 17.02.2015
comment
Вау, я почти сдался, но это заняло около минуты плюс-минус. Пока это лучший вариант, с которым мне приходилось работать, так что спасибо!! - person interested_in_the_world; 17.02.2015