Cálculo de estadísticas en subconjuntos de datos

Aquí hay un pequeño ejemplo reproducible de mis datos:

> mydata  mydata subject time measure 1 0 10 1 1 12 1 2 8 2 0 7 2 1 0 2 2 0 

Me gustaría generar una nueva variable que contenga la media de measure para ese tema en particular, así que:

 subject time measure mn_measure 1 0 10 10 1 1 12 10 1 2 8 10 2 0 7 2.333 2 1 0 2.333 2 2 0 2.333 

¿Hay una manera fácil de hacer esto, aparte de recorrer todos los registros de forma programática o remodelar primero en formato ancho?

Use la función R base ave() , que a pesar de su nombre confuso, puede calcular una variedad de estadísticas, incluida la mean :

 within(mydata, mean<-ave(measure, subject, FUN=mean)) subject time measure mean 1 1 0 10 10.000000 2 1 1 12 10.000000 3 1 2 8 10.000000 4 2 0 7 2.333333 5 2 1 0 2.333333 6 2 2 0 2.333333 

Tenga en cuenta que lo uso solo por el bien de un código más corto. Aquí está el equivalente sin within() :

 mydata$mean <- ave(mydata$measure, mydata$subject, FUN=mean) mydata subject time measure mean 1 1 0 10 10.000000 2 1 1 12 10.000000 3 1 2 8 10.000000 4 2 0 7 2.333333 5 2 1 0 2.333333 6 2 2 0 2.333333 

Alternativamente con el paquete data.table :

 require(data.table) dt <- data.table(mydata, key = "subject") dt[, mn_measure := mean(measure), by = subject] # subject time measure mn_measure # 1: 1 0 10 10.000000 # 2: 1 1 12 10.000000 # 3: 1 2 8 10.000000 # 4: 2 0 7 2.333333 # 5: 2 1 0 2.333333 # 6: 2 2 0 2.333333 

Puede usar ddply desde el paquete plyr :

 library(plyr) res = ddply(mydata, .(subject), mutate, mn_measure = mean(measure)) res subject time measure mn_measure 1 1 0 10 10.000000 2 1 1 12 10.000000 3 1 2 8 10.000000 4 2 0 7 2.333333 5 2 1 0 2.333333 6 2 2 0 2.333333