ddply с фиксированным количеством строк

Я хочу разбить свои данные на «количество строк». То есть я хочу отправить фиксированное количество строк в свою функцию, и когда я добираюсь до конца фрейма данных (последний блок), мне нужно просто отправить блок, имеет ли он фиксированное количество строк или меньше. Что-то вроде этого:

ddply(df, .(8 rows), .fun=somefunction)

Ответы на вопрос(3)

Вы можете определить 8 строк ID в вызовеddply.

Не особенно элегантно, но с использованиемddply (а такжеhead для примера функции)

df <- data.frame(x = rnorm(100), y = rnorm(100))
ddply(df, .(row_id = rep(seq(ceiling(nrow(df) / 8)), each = 8)[1:nrow(df)]),
             head, n = 1)

Если скорость и краткость представляют интерес, то для полноты (и для краткости примера используем размер фрагмента 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

Обратите внимание, что вы можете сделатьon the fly такие скопления; они не должны быть сначала добавлены к данным. Если у вас много различных агрегатов в производственном скрипте или вы просто хотите взаимодействовать с данными из командной строки, то очень небольшие различия в производительности, подобные этой, могут иногда помочь, в зависимости от вашего рабочего процесса.

NB: я выбралsum но это можно заменить наsomefunction(.SD) или (скорее) простоlist(exp1,exp2,...) где каждыйexp любое выражение R, которое видит имена столбцов как имена переменных.

 31 мая 2012 г., 19:13
+1 однажды я тоже приму власть, котораяdata.table... когда-нибудь
Решение Вопроса

Если вы хотите использоватьplyr Вы можете добавить столбец категории:

df <- data.frame(x=rnorm(100), y=rnorm(100))

somefunction <- function(df) {
    data.frame(mean(df$x), mean(df$y))
}

df$category <- rep(letters[1:10], each=10)

ddply(df, .(category), somefunction)

Но семейство apply может быть лучшим вариантом в этом случае:

somefunction <- function(n, x, y) {
    data.frame(mean(x[n:(n+9)]), mean(y[n:n+9]))
}

lapply(seq(1, nrow(df), by=10), somefunction, x=df$x, y=df$y)

Ваш ответ на вопрос