2011-11-02 5 views
13

Quiero agregar una columna de promedios basada en la columna de factores en Rdata.frame. De esta manera:Agregando una columna de medias por grupo a los datos originales

df1 <- data.frame(X = rep(x = LETTERS[1:2], each = 3), Y = 1:6) 
df2 <- aggregate(data = df1, Y ~ X, FUN = mean) 
df3 <- merge(x = df1, y = df2, by = "X", suffixes = c(".Old",".New")) 
df3 
# X Y.Old Y.New 
# 1 A  1  2 
# 2 A  2  2 
# 3 A  3  2 
# 4 B  4  5 
# 5 B  5  5 
# 6 B  6  5 

Para llevar a cabo este problema tengo para crear dos innecesaria data.frames. Me gustaría saber cómo agregar una columna de medio por factor de columna en mi data.frame original sin crear ningún data.frames adicional. Gracias por tu tiempo y ayuda.

Respuesta

12

Esto es lo que la función ave es para.

df1$Y.New <- ave(df1$Y, df1$X) 
+0

Esto es lo que estaba buscando. Gracias – MYaseen208

7

ddply y transform al rescate (aunque estoy seguro de que obtendrá al menos 4 formas diferentes de hacer esto):

library(plyr) 
ddply(df1,.(X),transform,Y.New = mean(Y)) 
    X Y Y.New 
1 A 1  2 
2 A 2  2 
3 A 3  2 
4 B 4  5 
5 B 5  5 
6 B 6  5 
4

Joran respondió muy bien, esto no es una respuesta a su pregunta, pero una extensión de la conversación. Si usted está buscando para la tabla de medios para la relación de dos de variable categórica a un dependiente aquí está la función de Hadley para que:

cast(CO2, Type ~ Treatment, value="uptake", fun.aggregate=mean, margins=TRUE) 

Aquí es una visión responsable de los datos de CO2, y un vistazo a la tabla de medios:

> head(CO2) 
    Plant Type Treatment conc uptake 
1 Qn1 Quebec nonchilled 95 16.0 
2 Qn1 Quebec nonchilled 175 30.4 
3 Qn1 Quebec nonchilled 250 34.8 
4 Qn1 Quebec nonchilled 350 37.2 
5 Qn1 Quebec nonchilled 500 35.3 
6 Qn1 Quebec nonchilled 675 39.2 

> library(reshape) 

> cast(CO2, Type ~ Treatment, mean, margins=TRUE) 
     Type nonchilled chilled (all) 
1  Quebec 35.33333 31.75238 33.54286 
2 Mississippi 25.95238 15.81429 20.88333 
3  (all) 30.64286 23.78333 27.21310 
9

Dos maneras alternativas de hacer esto:

1. con el dplyr paquete:

library(dplyr) 
df1 <- df1 %>% 
    group_by(X) %>% 
    mutate(Y.new = mean(Y)) 

2. con el paquete data.table:

library(data.table) 
setDT(df1)[, Y.new := mean(Y), by = X] 

ambos dan el siguiente resultado:

> df1 
    X Y Y.new 
1: A 1  2 
2: A 2  2 
3: A 3  2 
4: B 4  5 
5: B 5  5 
6: B 6  5 
Cuestiones relacionadas