O con ave
df <- data.frame(years=sort(rep(2005:2010, 12)),
months=1:12,
value=c(rnorm(60),NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA))
df$value[is.na(df$value)] <- with(df, ave(value, months,
FUN = function(x) median(x, na.rm = TRUE)))[is.na(df$value)]
Puesto que hay tantas respuestas vamos a ver que es más rápido.
plyr2 <- function(df){
medDF <- ddply(df,.(months),summarize,median=median(value,na.rm=TRUE))
df$value[is.na(df$value)] <- medDF$median[match(df$months,medDF$months)][is.na(df$value)]
df
}
library(plyr)
library(data.table)
DT <- data.table(df)
setkey(DT, months)
benchmark(ave = df$value[is.na(df$value)] <-
with(df, ave(value, months,
FUN = function(x) median(x, na.rm = TRUE)))[is.na(df$value)],
tapply = df$value[61:72] <-
with(df, tapply(value, months, median, na.rm=TRUE)),
sapply = df[61:72, 3] <- sapply(split(df[1:60, 3], df[1:60, 2]), median),
plyr = ddply(df, .(months), transform,
value=ifelse(is.na(value), median(value, na.rm=TRUE), value)),
plyr2 = plyr2(df),
data.table = DT[,value := ifelse(is.na(value), median(value, na.rm=TRUE), value), by=months],
order = "elapsed")
test replications elapsed relative user.self sys.self user.child sys.child
3 sapply 100 0.209 1.000000 0.196 0.000 0 0
1 ave 100 0.260 1.244019 0.244 0.000 0 0
6 data.table 100 0.271 1.296651 0.264 0.000 0 0
2 tapply 100 0.271 1.296651 0.256 0.000 0 0
5 plyr2 100 1.675 8.014354 1.612 0.004 0 0
4 plyr 100 2.075 9.928230 2.004 0.000 0 0
Hubiera apostado a que data.table fue el más rápido.
[Matthew Dowle] La tarea que se está programando aquí toma como máximo 0.02 segundos (2.075/100). data.table
considera que es insignificante. Intente configurar replications
en 1
y aumente el tamaño de los datos, en su lugar. O cronometrar el más rápido de 3 carreras también es una regla práctica común. Una discusión más detallada de estos enlaces:
+1 porque logró conectar 5 respuestas diferentes en 10 minutos. – Andrie
Edité la pregunta para incluir 'set.seed (1)' – Andrie