Tengo el siguiente marco de datos
x <- read.table(text = " id1 id2 val1 val2
1 a x 1 9
2 a x 2 4
3 a y 3 5
4 a y 4 9
5 b x 1 7
6 b y 4 4
7 b x 3 9
8 b y 2 8", header = TRUE)
Quiero calcular la media de val1 y val2 agrupados por id1 e id2, y simultáneamente contar el número de filas para cada combinación id1-id2. Puedo realizar cada cálculo por separado:
# calculate mean
aggregate(. ~ id1 + id2, data = x, FUN = mean)
# count rows
aggregate(. ~ id1 + id2, data = x, FUN = length)
Para hacer ambos cálculos en una llamada, intenté
do.call("rbind", aggregate(. ~ id1 + id2, data = x, FUN = function(x) data.frame(m = mean(x), n = length(x))))
Sin embargo, obtengo una salida confusa junto con una advertencia:
# m n
# id1 1 2
# id2 1 1
# 1.5 2
# 2 2
# 3.5 2
# 3 2
# 6.5 2
# 8 2
# 7 2
# 6 2
# Warning message:
# In rbind(id1 = c(1L, 2L, 1L, 2L), id2 = c(1L, 1L, 2L, 2L), val1 = list( :
# number of columns of result is not a multiple of vector length (arg 1)
Podría usar el paquete plyr, pero mi conjunto de datos es bastante grande y plyr es muy lento (casi inutilizable) cuando aumenta el tamaño del conjunto de datos.
¿Cómo puedo usar aggregate
u otras funciones para realizar varios cálculos en una llamada?
aggregate
mencionado en las respuestas, también hayby
ytapply
.Respuestas:
Puede hacerlo todo en un solo paso y obtener el etiquetado adecuado:
Esto crea un marco de datos con dos columnas de identificación y dos columnas de matriz:
Como lo señala @ lord.garbage a continuación, esto se puede convertir en un marco de datos con columnas "simples" usando
do.call(data.frame, ...)
Esta es la sintaxis para múltiples variables en el LHS:
fuente
d$val1[ , ""mn"]
mirar la estructura constr
.agg <- aggregate(cbind(val1, val2) ~ id1 + id2, data = x, FUN = function(x) c(mn = mean(x), n = length(x)))
usandoagg_df <- do.call(data.frame, agg)
. Consulte también aquí .Dado esto en la pregunta:
Luego, en
data.table
(1.9.4+
) podrías intentar:Para comparar tiempos
aggregate
(usado en la pregunta y las otras 3 respuestas) paradata.table
ver este punto de referencia (los casosagg
yagg.x
).fuente
Puede agregar una
count
columna, agregarlasum
y luego reducirla para obtenermean
:Tiene la ventaja de conservar los nombres de sus columnas y crear una sola
count
columna.fuente
Usando el
dplyr
paquete, podría lograr esto usandosummarise_all
. Con esta función de resumen puede aplicar otras funciones (en este casomean
yn()
) a cada una de las columnas que no se agrupan:lo que da:
Si no desea aplicar la (s) función (es) a todas las columnas que no se agrupan, especifique las columnas a las que deben aplicarse o excluyendo las no deseadas con un signo menos usando la
summarise_at()
función:fuente
¿Quizás quieras fusionarte ?
fuente
También puede utilizar
plyr::each()
para introducir varias funciones:fuente
Otra
dplyr
opción esacross
cuál es parte de la versión de desarrollo actual.Resultado
fuente