У меня есть большой data.table, который выглядит как:Использование adply в data.table
dt<-data.table(start=c("2012-07-13 23:45:00", "2012-07-14 15:30:00",
"2012-07-14 23:57:00"),
end=c("2012-07-14 00:02:00", "2012-07-14 15:35:00",
"2012-07-15 00:05:00"), id=c(1,2,1),cat=c("a","b","a"))
dt
start end id cat
1: 2012-07-13 23:45:00 2012-07-14 00:02:00 1 a
2: 2012-07-14 15:30:00 2012-07-14 15:35:00 2 b
3: 2012-07-14 23:57:00 2012-07-15 00:05:00 1 a
Мне нужно, чтобы получить выходной сигнал, который показывает общее количество минут события на каждый календарный день от ид и категории. Используя приведенный выше пример вывода должен быть:
day id cat V1
1: 13.07.2012 1 a 15
2: 14.07.2012 1 a 5
3: 14.07.2012 2 b 5
4: 15.07.2012 1 a 5
Я использовал adply функции из пакета plyr разделить продолжительность в интервалах по минуту:
fn<-function(x){
s<-seq(from = as.POSIXct(x$start),
to = as.POSIXct(x$end)-1,by = "mins")
# here s is a sequence of all minutes in the given interval
df<-data.table(x$id,x$cat,s)
# return new data.table that contains each calendar minute for each id
# and categoryy of the original data
df
}
# run the function above for each row in the data.table
dd<-adply(dt,1,fn)
# extract the date from calendar minutes
dd[,day:=format(as.POSIXct(s,"%d.%m.%Y %H:%M%:%S"), "%d.%m.%Y")]
#calculate sum of all minutes of event for each day, id and category
dd[,.N,by=c("day","id","cat")][order(day,id,cat)]
Решение выше идеально подходит моим потребностям, за исключением времени, необходимого для расчета. Когда adply запускается с очень большими данными и несколькими категориями, определенными в функции fn, кажется, что процессор работает навсегда.
Я высоко ценю любой намек на то, как использовать чистую функцию data.table в этой проблеме.
Я полностью согласен с этим, но я не мог придумать лучшее решение :( – Asayat
Могу ли я читать это неправильно, но вы просто не нашли разницы двух столбцов даты и времени? – Parfait
Для начала, все ваше prcedure будет работать намного быстрее, если вы будете конвертировать 'start' и' end' в класс 'POSIXct' только один раз, используя' '' dt [, ': =' (start = as.POSIXct (start), end = as.POSIXct (end))] '' 'вместо того, чтобы делать это для каждой строки. Тогда' s' будет просто 's <- seq (start, end, by =" min ")'. Я предполагаю, что это ваша основная бутылка шея –