Francisco Javier
2014-Jul-21 18:42 UTC
[R-es] Inserción de condicionales en pequeño código
Buenas tardes, He construido la función “myfun” al objeto de considerar aquellas persones que a partir de una determinada fecha de Apertura tienen como mínimo 65 años. Se tiene su fecha de nacimiento, su fecha de inicio en la institución y su fecha de salida de la misma. Doy vueltas al script y no acabo se saber cómo poder aplicar de un modo eficiente las instrucciones “if” ó bien “ifelse”, y me dirijo al foro por si alguien puede darme alguna idea. El script actualmente ya funciona (adjunto un ejemplo), pero por lo que voy aprendiendo del foro, intuyo que la programación es mejorable, pues básicamente el script hace casi todo el rato lo mismo. Si además, alguien determina alguna otra parte mejorable, lo agradeceré mucho. Muchas gracias! DF <- data.frame(id=1:5, fnacim=as.Date(c("1939-10-28","1943-02-26","1946-03-09","1947-05-19","1932-04-03")), finicio=as.Date(c("2012-01-01","1980-07-15","1998-10-28","2011-10-28","2010-10-28")), fsal=as.Date(c("2012-05-01","2014-02-01","2012-10-20","2013-10-15","2012-08-25"))) myfun <- function(data, edad_u=65, Apertura=as.Date("2010-01-01")) { ### 1 ) Si "finicio" es ANTERIOR O IGUAL a la fecha de Apertura ### dd1 <- data[data$finicio <= Apertura,] # Variable temporal: Edad en la fecha de apertura dd1$edad_Apertura <- unclass(round(difftime(Apertura, dd1$fnacim, units="auto")/365.25,1)) # De estos individuos, identifico a aquellos CUYA EDAD EN FECHA DE APERTURA ES # INFERIOR O IGUAL A LOS 65 AÑOS, y añado las variables "edad_fent" y "fent" menor_t_Apertura <- dd1[dd1$edad_Apertura <= edad_u,] menor_t_Apertura$edad_fent <- edad_u tmp.1 <- as.POSIXlt(menor_t_Apertura$fnacim) tmp.1$year <- tmp.1$year+65 menor_t_Apertura$fent <- as.Date(tmp.1) # Individuos CUYA EDAD EN FECHA DE APERTURA ES SUPERIOR A LOS 65 AÑOS mayor_t_Apertura <- dd1[dd1$edad_Apertura> edad_u,]mayor_t_Apertura$edad_fent <- unclass(round(difftime(Apertura, mayor_t_Apertura$fnacim, units="auto")/365.25,1)) mayor_t_Apertura$fent <- Apertura dd1.new <- rbind(menor_t_Apertura, mayor_t_Apertura) dd1.new <- dd1.new[,-which(names(dd1.new) %in% c('edad_Apertura'))] ### 2) Si "finicio" es POSTERIOR a la fecha de Apertura ### dd2 <- data[ data$finicio > Apertura,] ; dd2$edad_fent <- NA ; dd2$fent <- NA ##### Resultado ##### union <- rbind(dd1.new, dd2) ; union <- union[with(union, order(id)), ] ; return(union) } # FINAL DE LA FUNCIÓN myfun(DF) [[alternative HTML version deleted]]
"Marcuzzi, Javier Rubén"
2014-Jul-21 19:45 UTC
[R-es] Inserción de condicionales en pequeño código
Estimado Francisco Javier Mi respuesta en una obervación y un comentario. La observación: su código anda, creo que sin problemas (no verifiqué las fechas), pero hace una diferencia en los <NA> para fent y edad_fent donde usa NA. copio y pego lo que da en mi consola:>myfun(DF)id fnacim finicio fsal edad_fent fent 1 1 1939-10-28 2012-01-01 2012-05-01 NA <NA> El comentario: yo en un trabajo realicé algo semejante, ¿usted tiene problemas de rendimiento con sus datos reales?. Porque mi forma de pensar es: funciona y no hay problemas de rendimiento ==> no tocar Hay otras formas para trabajar con fechas, se podría utilizar otra programación, ver cuál es la más eficiente, pero ¿necesita mejorar el rendimiento o es mejor usar ese tiempo en otras actividades? Si usted tiene problemas de rendimiento, yo no tengo inconvenientes en buscar el código que usé en mis actividades, pero de pronto es un trabajo incesesario, salvo para practivar, aprender, por curiocidad, o algún otro motivo muy respetable. Pienso en dos cosas, el tiempo para mantener algo que uno no penso (escrito por otro), el tiempo para aprender otra forma de hacer las cosas. Pero también es un buen ejemplo para abrir en la lista un intercambio de ideas sobre distintas formas de trabajar con fechas, lo cuál puede ser bueno para aprender entre muchos. Javier Marcuzzi El 21/07/2014 03:42 p.m., Francisco Javier escribió:> DF <- data.frame(id=1:5, > > fnacim=as.Date(c("1939-10-28","1943-02-26","1946-03-09","1947-05-19","1932-04-03")), > > finicio=as.Date(c("2012-01-01","1980-07-15","1998-10-28","2011-10-28","2010-10-28")), > > fsal=as.Date(c("2012-05-01","2014-02-01","2012-10-20","2013-10-15","2012-08-25"))) > > > > myfun <- > function(data, edad_u=65, Apertura=as.Date("2010-01-01")) { > > > > ### 1 ) Si "finicio" es ANTERIOR O > IGUAL a la fecha de Apertura ### > > dd1 > <- data[data$finicio <= Apertura,] > > > > # Variable temporal: Edad en la fecha de > apertura > > dd1$edad_Apertura <- > unclass(round(difftime(Apertura, dd1$fnacim, units="auto")/365.25,1)) > > > > # De estos individuos, identifico a aquellos > CUYA EDAD EN FECHA DE APERTURA ES > > # > INFERIOR O IGUAL A LOS 65 AÑOS, y añado las variables "edad_fent" y "fent" > > menor_t_Apertura <- dd1[dd1$edad_Apertura > <= edad_u,] > > > > menor_t_Apertura$edad_fent <- edad_u > > > > tmp.1 <- as.POSIXlt(menor_t_Apertura$fnacim) > > tmp.1$year <- tmp.1$year+65 > > menor_t_Apertura$fent <- as.Date(tmp.1) > > > > # Individuos CUYA EDAD EN FECHA DE APERTURA ES > SUPERIOR A LOS 65 AÑOS > > mayor_t_Apertura <- dd1[dd1$edad_Apertura >> >edad_u,] > mayor_t_Apertura$edad_fent <- > unclass(round(difftime(Apertura, mayor_t_Apertura$fnacim, > > units="auto")/365.25,1)) > > mayor_t_Apertura$fent <- Apertura > > > > dd1.new > <- rbind(menor_t_Apertura, mayor_t_Apertura) > > dd1.new <- dd1.new[,-which(names(dd1.new) > %in% c('edad_Apertura'))] > > > > ### 2) Si > "finicio" es POSTERIOR a la fecha de Apertura ### > > dd2 <- data[ data$finicio > > Apertura,] ; dd2$edad_fent <- NA ; dd2$fent <- NA > > > > ##### Resultado ##### > > union <- rbind(dd1.new, dd2) ; union <- union[with(union, order(id)), ] ; return(union) > > > > } # FINAL DE LA FUNCIÓN > > > > myfun(DF)[[alternative HTML version deleted]]
Francisco Javier
2014-Jul-22 09:46 UTC
[R-es] Inserción de condicionales en pequeño código
Hola Javier Rubén, Gracias por tu respuesta. Si bien ya sabía que el código funcionaba (de hecho, ya lo mencionaba en mi correo inicial), el motivo de adjuntarlo era por si dicho código fuese muy mejorable en condiciones de rendimiento, pues he de aplicarlo a decenas de miles de datos y funciona algo lento (posible motivo ya apuntado en tu respuesta). Dado que sé que en el foro hay gente que sabe muchísimo en el tratamiento de fechas, quizás (no lo sé) se puede establecer una clara mejora en términos de eficiencia computacional. En cualquier caso, lo dejo por si alguien realiza alguna vez algo similar o por si alguien tiene una aportación al respecto. Saludos. [[alternative HTML version deleted]]