[R-es] Encontrar la primera columna no NA
Javier Villacampa González
javier.villacampa.gonzalez en gmail.com
Jue Oct 27 19:16:39 CEST 2016
Tengo que comprobar si todos hacen lo mismo del todo. Pero los resultados
no dejan de sorprenderme. Carlos, ya no programa nadie en base y empiezo a
sospechar que igual nos equivocamos.
===================================================================================================
# Unit: seconds
expr min lq mean median
uq max neval Lift
# JVG 0,6716004 0,7210757 1,0513104 0,9597415 1,1624642
2,0997470 10 3,17
# Olivier 3,0642166 3,424266 3,7383201 3,745616 3,9909474
4,4795947 10 12,3
# Olivier2 1,2263557 1,340338 1,5031451 1,5140908 1,6264349
1,7548450 10 5,00
# Adolfo 0,3401764 0,3425798 0,446328 0,3992639 0,5313764
0,7357900 10 1,32
# Olivier3 0,3684704 0,3875006 0,5157852 0,4959741 0,6414696
0,6954977 10 1,64
# GilBellosta 0,2089104 0,265419 0,3599796 0,3023052 0,4038109
0,7859248 10 1
===================================================================================================
#
===================================================================================================
# Codigo
#
===================================================================================================
library(microbenchmark)
N <- 1e1
tabla <-
microbenchmark(
# JVG_dplyr ={
# dat %>%
# apply( MARGIN = 1, FUN =
# function(x){
# which( !is.na(x) ) %>% min( na.rm = TRUE ) %>%
return()
# }
# )
# dat[ , First_month := First_month]
# N_for <- length( unique(First_month ))
# for( j in 1:N_for){
# x <- dat[ First_month == j, j, with = FALSE]
# dat[ First_month == j , Value_First_month := x ]
# }
# },
JVG ={
dat <-
data.table( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
apply(X = dat, MARGIN = 1, FUN =
function(x){
return( min( which( !is.na(x) ), na.rm = TRUE ) )
}
)
dat[ , First_month := First_month]
N_for <- length( unique(First_month ))
for( j in 1:N_for){
x <- dat[ First_month == j, j, with = FALSE]
dat[ First_month == j , Value_First_month := x ]
}
},
Olivier ={
dat <-
data.table( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
dat[,First_month := apply(X = .SD,MARGIN = 1,FUN = function(x)
colnames(.SD)[min(which(!is.na(x)))])]
dat[,Value_First_month := apply(X = .SD,MARGIN = 1,FUN = function(x)
x[min(which(!is.na(x)))])]
},
Olivier2={
dat <-
data.table( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
dat[,jugador:=1:.N]
dat2=melt(dat,id.vars="jugador")
setkey(dat2,jugador)
dat2[,index:=min(which(!is.na(value))),by=jugador]
dat3 <- dat2[,list(First_month_Olivier
=variable[index[1]],Value_First_month_Olivier =value[index[1]]),by=jugador]
setkey(x = dat, jugador)
dat0 <- merge( x = dat, y = dat3, all.x = TRUE, all.y = FALSE)
},
Adolfo = {
dat <-
data.table( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
# 1) Creamos una columna con la informacion de los jugadores,
# Como es un jugador por fila, hacemos 1:nrow.
step1 <- dat %>%
mutate(player = 1:nrow(dat))
#2) Convertimos las columnas de tiempo (uno, dos, tres, ...) en dos
columnas, mes y numero de juegos. (Ojo, asumimos que en los datos las
columnas estan ordenadas como en el ejemplo, es decir uno, dos, tres y no
tres, uno, dos)
step2 <- gather(step1, month, games, -player)
#y 3) Filtramos los meses con NA y por cada jugador nos quedamos con
el primer dato:
step3 <- step2 %>%
filter(!is.na(games)) %>%
group_by(player) %>%
slice(1)
dat %>% print
},
Olivier3 = {
dat <-
data.table( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
M=as.matrix(dat)
index <- which(!is.na(M)) - 1
meses<-colnames(M)
M2<- data.table(columna=index %/% nrow(M) +1L, jugador=index %%
nrow(M) +1L , valor=M[index+1L])
setkey(M2,jugador,columna)
M2[,.(First_month=meses[columna[1]],Value_First_month=valor[1]),by=jugador]
},
GilBellosta = {
dat <-
data.frame( Uno = sample( c(runif(numero) , rep(NA , numero /2e0
)) , size = numero ) ,
dos = sample( c(runif(numero) , rep(NA , numero /1e1
)) , size = numero ) ,
tres = sample( c(runif(numero) , rep(NA , numero /2e1
)) , size = numero ) ,
cuatro = sample( c(runif(numero) , rep(NA , numero /1e2
)) , size = numero ) ,
cinco = sample( c(runif(numero) , rep(NA , numero /2e2
)) , size = numero ) ,
seis = sample( c(runif(numero) , rep(NA , numero /1e3
)) , size = numero )
)
tmp <- (as.matrix(dat))
cols <- col(tmp)
cols[is.na(tmp)] <- Inf
my.cols <- apply(cols, 1, min)
my.values <- tmp[cbind(1:nrow(tmp), my.cols)]
difftime(Sys.time(), t)
},
times = N, unit = "s")
tabla %>% print
beepr::beep(3)
# Unit: seconds
# expr min lq mean median uq max
neval
# JVG 0.6716004 0.7210757 1.0513104 0.9597415 1.1624642
2.0997470 10
# Olivier 3.0642166 3.4242660 3.7383201 3.7456160 3.9909474
4.4795947 10
# Olivier2 1.2263557 1.3403380 1.5031451 1.5140908 1.6264349
1.7548450 10
# Adolfo 0.3401764 0.3425798 0.4463280 0.3992639 0.5313764
0.7357900 10
# Olivier3 0.3684704 0.3875006 0.5157852 0.4959741 0.6414696
0.6954977 10
# GilBellosta 0.2089104 0.2654190 0.3599796 0.3023052 0.4038109
0.7859248 10
[[alternative HTML version deleted]]
Más información sobre la lista de distribución R-help-es