2010-07-27 19 views
6

que tienen un hoja.de.datos que tiene este aspectoR: Agregado de las columnas de un hoja.de.datos

> head(df) 
      Memory Memory Memory Memory Memory  Naive  Naive 
10472501 6.075714 5.898929 6.644946 6.023901 6.332126 8.087944 7.520194 
10509163 6.168941 6.495393 5.951124 6.052527 6.404401 7.152890 8.335509 
10496091 10.125575 9.966211 10.075613 10.310952 10.090649 11.803949 11.274480 
10427035 6.644921 6.658567 6.569745 6.499243 6.990852 8.010784 7.798154 
10503695 8.379494 8.153917 8.246484 8.390747 8.346748 9.540236 9.091740 
10451763 10.986717 11.233819 10.643245 10.230697 10.541396 12.248487 11.823138 

y me gustaría encontrar la media de las columnas Memory y la media de las columnas Naive. La función aggregate agrega filas. Este data.frame podría tener un gran número de filas, y por lo tanto la transposición luego aplicar aggregate por el colnames del original data.frame me parece mal, y en general es molesto:

> head(t(aggregate(t(df),list(colnames(df)), mean))) 
     [,1]  [,2]  
Group.1 "Memory" "Naive" 
10472501 "6.195123" "8.125439" 
10509163 "6.214477" "7.733625" 
10496091 "10.11380" "11.55348" 
10427035 "6.672665" "8.266854" 
10503695 "8.303478" "9.340436" 

Cuál es la cosa salta a la vista que me falta ?

+1

agudo de ojos entre usted notará que 8,12 no es la media de 8,08 y 7,52: hay unas cuantas más columnas en realidad. ¡No muchos más! –

Respuesta

8

Soy un gran defensor de cambio de formato de datos para que sea en un formato "largo". La utilidad del formato largo es especialmente evidente cuando se trata de problemas como este. Afortunadamente, es bastante fácil remodelar datos como este en casi cualquier formato con el paquete reshape.

Si entendí bien su pregunta, quiere la media de Memory y Naive para cada fila. Por alguna razón, necesitamos hacer nombres de columnas únicos para reshape::melt().

colnames(df) <- paste(colnames(df), 1:ncol(df), sep = "_") 

Entonces, usted tiene que crear una columna ID. Usted podría hacer

df$ID <- 1:nrow(df) 

o, si esos son significativos rownames

df$ID <- rownames(df) 

Ahora, con el paquete de reshape

library(reshape) 
df.m <- melt(df, id = "ID") 
df.m <- cbind(df.m, colsplit(df.m$variable, split = "_", names = c("Measure", "N"))) 
df.agg <- cast(df.m, ID ~ Measure, fun = mean) 

df.agg debe parecerse a su snippit salida deseada.

O, si solo quiere los medios generales en todas las filas, la sugerencia de Zack funcionará. Algo así como

m <- colMeans(df) 
tapply(m, colnames(df), mean) 

Se puede obtener el mismo resultado, pero el formato de una trama de datos con

cast(df.m, .~variable, fun = mean) 
+0

Dandole a Jo el tic porque esta parece ser la manera correcta de hacer las cosas, ¡así que muchas gracias! Pero sí, como dice John, lo más obvio que me estaba perdiendo era simplemente la función rowMeans, que es algo que no olvidaré nunca más. –

+0

Erm - pregunta rápida. ¿Alguna idea de por qué 's <- cast (df.m, ID ~ variable, fun = var)' me devuelve un montón de ceros, cuando 'fun = mean' parece funcionar bien y 'fun = sum' también funciona? La varianza de estas columnas es def no cero. –

+0

¡Buena captura! No sé cuál fue el trato, pero dado que los nombres de las columnas no eran únicos, no se fundieron correctamente. ¡He editado mi respuesta para que funcione ahora! – JoFrhwld

0

Creo que ha cargado sus datos sin header=TRUE y lo que tiene es una matriz de factores, por lo que su generalmente buena idea falla.

3

¿Qué pasa algo parecido

lapply(unique(colnames(df)), function(x) rowMeans(df[,colnames(df) == x])) 
+0

Gracias Jonathan! Esto es lo que una parte de mi cerebro me decía que existía. Simplemente no podía recordarlo. –

3

Para aclarar la respuesta de Jonathan Chang ... la cosa ciegamente obvio que se está perdiendo es que sólo se puede seleccione las columnas y emita el comando rowMeans. Eso dará el vector de los medios para cada fila. Su comando obtiene los medios de fila para cada grupo de nombres de columna únicos y era exactamente lo que iba a escribir. Con sus datos de muestra, el resultado de su comando son dos listas.

rowMeans también es muy rápido.

Para romper hacia abajo, para obtener los medios de todas las columnas de la memoria solamente es sólo

rowMeans(df[,colnames(df) == 'Memory']) #or from you example, rowMeans(df[,1:5]) 

Es el más simple respuesta correcta completa, le votan y Mark lo correcto si te gusta.

(Por cierto, también me gusta la recomendación de Jo para mantener en general cosas como datos largos.)

0
m = matrix(1:12,3) 
colnames(m) = c(1,1,2,2) 

m 

    1 1 2 2 
[1,] 1 4 7 10 
[2,] 2 5 8 11 
[3,] 3 6 9 12 

mt = t(m) 
sapply(by(mt,rownames(mt),colMeans),identity) 

    1 2 
V1 2.5 8.5 
V2 3.5 9.5 
V3 4.5 10.5 
+0

¿Puede proporcionar una explicación? –

Cuestiones relacionadas