2012-05-31 3 views
1

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

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

ответ

4

Если вы хотите использовать 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) 

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

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) 
2

Если скорость и краткость представляют интерес, то для полноты (и используя размер куска 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, который видит имена столбцов в качестве имен переменных.

+0

+1 Когда-нибудь я тоже обниму власть, которая 'data.table' ... когда-нибудь – Justin

0

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

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

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) 
Смежные вопросы