Если скорость и краткость представляют интерес, то для полноты (и используя размер куска 4, а не 8, чтобы сохранить пример коротким):
require(data.table)
set.seed(0)
DT = data.table(a=rnorm(10))
DT
a
[1,] 1.262954285
[2,] -0.326233361
[3,] 1.329799263
[4,] 1.272429321
[5,] 0.414641434
[6,] -1.539950042
[7,] -0.928567035
[8,] -0.294720447
[9,] -0.005767173
[10,] 2.404653389
DT[,list(sum=sum(a),groupsize=.N),by=list(chunk=(0:(nrow(DT)-1))%/%4)]
chunk sum groupsize
[1,] 0 3.538950 4
[2,] 1 -2.348596 4
[3,] 2 2.398886 2
Уместно, это довольно длинное заявление. Он называет столбцы и возвращает размер группы, чтобы показать вам, что последний кусок действительно содержит только 2 строки по мере необходимости.
После удобно это делать правильно, он может быть сокращен до этого:
DT[,sum(a),by=list(chunk=(0:(nrow(DT)-1))%/%4)]
chunk V1
[1,] 0 3.538950
[2,] 1 -2.348596
[3,] 2 2.398886
Обратите внимание, что вы можете сделать на лету скопления, как это; их сначала не нужно добавлять к данным. Если у вас много разных агрегатов в производственном скрипте или просто хотите взаимодействовать с данными из командной строки, то иногда небольшие изменения производительности могут помочь в зависимости от вашего рабочего процесса.
NB: Я выбрал sum
, но которые могут быть заменены somefunction(.SD)
или (более вероятно) просто list(exp1,exp2,...)
где каждый exp
это любое выражение R, который видит имена столбцов в качестве имен переменных.
+1 Когда-нибудь я тоже обниму власть, которая 'data.table' ... когда-нибудь – Justin