Tengo un marco de datos con 2 millones de filas y 15 columnas. Quiero agrupar por 3 de estas columnas con ddply (los 3 son factores, y hay 780,000 combinaciones únicas de estos factores), y obtener la media ponderada de 3 columnas (con pesos definidos por mi conjunto de datos). El siguiente es razonablemente rápido:¿Cómo acelerar el resumen y ddply?
system.time(a2 <- aggregate(cbind(col1,col2,col3) ~ fac1 + fac2 + fac3, data=aggdf, FUN=mean))
user system elapsed
91.358 4.747 115.727
El problema es que quiero utilizar weighted.mean en lugar de la media para calcular mis columnas agregadas.
Si trato de la siguiente ddply en la misma trama de datos (Nota, yo echo a inmutable), el siguiente no termina después de 20 minutos:
x <- ddply(idata.frame(aggdf),
c("fac1","fac2","fac3"),
summarise,
w=sum(w),
col1=weighted.mean(col1, w),
col2=weighted.mean(col2, w),
col3=weighted.mean(col3, w))
Esta operación parece ser la CPU hambre, pero no muy intensivo en RAM
EDIT: Así que terminé escribiendo esta pequeña función, que "engaña" un poco al aprovechar algunas propiedades de la media ponderada y hace una multiplicación y una división en todo el objeto, en lugar de en las rebanadas.
weighted_mean_cols <- function(df, bycols, aggcols, weightcol) {
df[,aggcols] <- df[,aggcols]*df[,weightcol]
df <- aggregate(df[,c(weightcol, aggcols)], by=as.list(df[,bycols]), sum)
df[,aggcols] <- df[,aggcols]/df[,weightcol]
df
}
Cuando corro como:
a2 <- weighted_mean_cols(aggdf, c("fac1","fac2","fac3"), c("col1","col2","col3"),"w")
puedo obtener un buen rendimiento, y algo reutilizable, código elegante.
Hay montones y montones de consejos de optimización plyr en [esta cuestión] (http://stackoverflow.com/questions/3685492/r-speeding-up-group-by-operations). Además, no olvide que puede ejecutar 'ddply' en paralelo vinculándolo al paquete' foreach'. –
He visto eso - probé los trucos que me gustaron, no los que no. En su lugar, fui con la edición anterior que usa base R, sigue siendo bastante flexible y se ejecuta rápidamente (aún menos de 2 minutos). Todavía me encantaría una explicación de por qué esto es lento en ddply. Me encantan las características de sintaxis y paralelismo. – evanrsparks
'ddply' es muy lento porque funciona con marcos de datos, que lamentablemente son bastante lentos. Los enfoques más rápidos funcionan directamente con los vectores, que son mucho más rápidos – hadley