Para cada nivel de factor de los valores agregados más de todos los niveles a excepción de la actual

StackOverflow https://stackoverflow.com//questions/12660211

  •  11-12-2019
  •  | 
  •  

Pregunta

Para cada nivel del factor necesito para extraer valores agregados sobre todos los subconjuntos de datos.marco a excepción de la actual.Por ejemplo, hay varios temas haciendo un tiempo de reacción de la tarea durante varios días, y tengo que calcular la media de tiempo de reacción para todas las materias y todos los días, pero no incluye el tema para quien la media es calculada.En la actualidad, yo lo hago así:

 library(lme4)
 ddply(sleepstudy, .(Subject, Days), summarise, 
       avg_rt = mean(sleepstudy[sleepstudy$Subject != Subject &
                   sleepstudy$Days == Days,"Reaction"]), .progress="text")

Funciona muy bien para pequeños conjuntos de datos, pero para grandes puede ser muy lento.Hay una manera de hacerlo más rápido?

¿Fue útil?

Solución

#create big dataset
n <- 1e4
set.seed(1)
sleepstudy <- data.frame(Reaction=rnorm(n),Subject=1:4,Days=sort(rep((1:(n/4)),4)))


library(plyr)
system.time(
  res <- ddply(sleepstudy, .(Subject, Days), summarise, 
               avg_rt = mean(sleepstudy[sleepstudy$Subject != Subject &
                 sleepstudy$Days == Days,"Reaction"]))
)
#User      System      elapsed 
#6.532       0.013       6.556  

#use data.table for big datasets
library(data.table)

dt<- as.data.table(sleepstudy)
system.time(
 {dt[,avg_rt:=mean(Reaction),by=Days];
  dt[,n:=.N,by=Days];
  dt[,avg_rt:=(avg_rt*n-Reaction)/(n-1)]}
)
#User      System      elapsed 
#0.005       0.001       0.005 


#test if results are equal
dt2 <- as.data.table(res)
setkey(dt2,Subject,Days)
setkey(dt,Subject,Days)
all.equal(dt[,avg_rt],dt2[,avg_rt])
#[1] TRUE

Para realmente grandes conjuntos de datos, la ganancia de velocidad debería ser más pronunciado.Yo no podía comparar con grandes conjuntos de datos desde ddply es tan lento.

Otros consejos

Maybe it's faster with lapply and aggregate:

do.call("rbind", (lapply(unique(sleepstudy$Subject),
                         function(x)
                           cbind(Subject = x,
                                 aggregate(Reaction ~ Days,
                                           subset(sleepstudy, Subject != x),
                                           mean)))))

Update:

I compared both commands with system.time and it appears the original is slower.

library(lme4)
library(plyr)

system.time(
ddply(sleepstudy, .(Subject, Days), summarise, 
      avg_rt = mean(sleepstudy[sleepstudy$Subject != Subject &
                    sleepstudy$Days == Days,"Reaction"]))
)

   # user  system elapsed 
   # 0.17    0.00    0.22 

system.time(
do.call("rbind", (lapply(unique(sleepstudy$Subject),
                         function(x) 
                           cbind(Subject = x,
                                 aggregate(Reaction ~ Days,
                                           subset(sleepstudy, Subject != x),
                                           mean)))))
)


   # user  system elapsed 
   # 0.12    0.00    0.12 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top