2011-11-18 11 views
5

Debo estar haciendo algo mal porque esta función no está terminando.Agregando para crear la matriz de frecuencia tomando mucho tiempo

Estoy tratando de agregar algunos datos por semana. Los datos se dividen en id y weeknumber. Me gustaría que el resultado tuviera los ID como filas, las semanas como columnas y los totales como valores.

Ejemplo de lo que he probado hasta ahora (intentó un montón de otras cosas, incluyendo la adición de una variable ficticia = 1 y luego fun.aggregating = suma sobre eso):

ddply(data, .(id), dcast, id~weeknumber, value_var="id", 
     fun.aggregate=length, fill=0, .parallel=TRUE) 

¿Hay una mejor forma de hacer esto?

de entrada:

id  week 
1  1 
1  2 
1  3 
1  1 
2  3 

Salida:

1 2 3 
1 2 1 1 
2 0 0 1 

Respuesta

10

No es necesario ddply para esto. El dcast de reshape2 es suficiente:

dat <- data.frame(
    id = c(rep(1, 4), 2), 
    week = c(1:3, 1, 3) 
) 

library(reshape2) 
dcast(dat, id~week, fun.aggregate=length) 

    id 1 2 3 
1 1 2 1 1 
2 2 0 0 1 

Editar: Para una solución de base R (que no sea table - tal como fue anunciado por Joshua Uhlrich), trate de xtabs:

xtabs(~id+week, data=dat) 

    week 
id 1 2 3 
    1 2 1 1 
    2 0 0 1 
12

Usted podría solo use el comando table:

table(data$id,data$week) 

    1 2 3 
    1 2 1 1 
    2 0 0 1 
+0

+1 explosiva. Tiene la habilidad de hacer que mis soluciones parezcan totalmente largas, indirectas y peatonales. – Andrie

+2

Si tiene muchos datos y operaciones que no se pueden simplificar tanto, entonces el paquete 'data.table' puede ayudarlo. –

6

El motivo por el que ddply tarda tanto es que la división por grupo no se ejecuta en paralelo (solo los cálculos en las 'divisiones'), por lo tanto con un gran número de grupos será lenta (y .parallel = T) no ayudará .

A data.table enfoque debe ser extremadamente eficiente en tiempo y memoria.

Para la eficiencia data.table lo mejor es trabajar en forma larga hacer la agrupación y formar de nuevo a gran

library(data.table) 
library(reshape2) 
DT <- data.table(data) 

setkeyv(DT, 'id') 

dcast(DT[, .N, by = list(id, week)], id~ week, fill = 0) 
Cuestiones relacionadas