Buenas tardes, Tengo un data frame denominado “trabajadores”, que cubre desde el 1 de enero de 1997 hasta el 30 junio de 1999, con 3 columnas: Identificador (ID), la fecha de entrada en la empresa (ENT) y la fecha de salida (SAL). Deseo localizar aquellos trabajadores que, durante dicho periodo, NO han llegado a pasar un 31 de diciembre y un 1 de enero seguidos (cambio de año) como asalariados de la empresa, para lo cual hago: ## Los que entran durante 1997 pero no llegan al 1 de enero de 1998 t1 <- intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID , trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID ) t2 <- intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID , trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID ) t3 <- intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID , trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID ) t4 <- intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID , trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID ) ## Los que entran durante 1998 pero no llegan al 1 de enero de 1999 t5 <- intersect ( trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID , trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID ) t6 <- intersect ( trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID , trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID ) t7 <- intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID , trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID ) t8 <- intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID ) localizados <- c(t1, t2, t3, t4, t5, t6, t7, t8) ¿Existe alguna forma más eficiente de localizar a los mismos individuos? ¡¡ Muchísimas gracias !! [[alternative HTML version deleted]]
Simplificando (i.e., asumiendo que los días fin de año son los múltiplos de 10): # datos simulados dat <- data.frame(id = letters[1:4], ini = c(1, 15, 15, 11), fin = c(11, 19, 25, 22)) fin.anno <- 10 * 1:3 # resultado dat[mapply(function(x,y) ! any(fin.anno %in% x:y), dat$ini, dat$fin),] Un saludo, Carlos J. Gil Bellosta http://www.datanalytics.com El día 17 de julio de 2014, 17:19, Francisco Javier <iterador10 en hotmail.com> escribió:> > Buenas > tardes, > > Tengo un > data frame denominado ?trabajadores?, que cubre desde el 1 de > enero de 1997 hasta el 30 junio de 1999, con 3 columnas: Identificador (ID), la > fecha de entrada en la empresa (ENT) y la fecha de salida (SAL). Deseo localizar > aquellos trabajadores que, durante dicho periodo, NO han llegado a pasar un 31 > de diciembre y un 1 de enero seguidos (cambio de año) como asalariados de la > empresa, para lo cual hago: > > ## Los > que entran durante 1997 pero no llegan al 1 de enero de 1998 > > t1 <- > intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID > , > > trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID > ) > > t2 <- > intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID > , > > trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID > ) > > t3 <- > intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID > , > > trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID > ) > > t4 <- > intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID > , > > trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID > ) > > ## Los > que entran durante 1998 pero no llegan al 1 de enero de 1999 > > t5 <- > intersect ( trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID > , > > trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID > ) > > t6 <- > intersect ( trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID > , > > trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID > ) > > t7 <- > intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID > , > > trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID > ) > > t8 <- > intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID > > trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID > ) > > localizados > <- c(t1, t2, t3, t4, t5, t6, t7, t8) > > > > ¿Existe > alguna forma más eficiente de localizar a los mismos individuos? ¡¡ Muchísimas gracias !! > > > [[alternative HTML version deleted]] > > > _______________________________________________ > R-help-es mailing list > R-help-es en r-project.org > https://stat.ethz.ch/mailman/listinfo/r-help-es >
Poniendo las fechas de entrada y salida en año (%Y) y calculando la diferencia D entre estas fechas , se obtiene un criterio sencillo : si D≧1, el asalariado experimentó un cambio de año en la empresa. Un saludo. Olivier On 17 de julio de 2014 18:42:56 CEST, "Carlos J. Gil Bellosta " <cgb@datanalytics.com> wrote:>Simplificando (i.e., asumiendo que los días fin de año son los >múltiplos de 10): > ># datos simulados >dat <- data.frame(id = letters[1:4], > ini = c(1, 15, 15, 11), > fin = c(11, 19, 25, 22)) > >fin.anno <- 10 * 1:3 > ># resultado >dat[mapply(function(x,y) ! any(fin.anno %in% x:y), dat$ini, dat$fin),] > >Un saludo, > >Carlos J. Gil Bellosta >http://www.datanalytics.com > > > > >El día 17 de julio de 2014, 17:19, Francisco Javier ><iterador10@hotmail.com> escribió: >> >> Buenas >> tardes, >> >> Tengo un >> data frame denominado “trabajadores”, que cubre desde el 1 de >> enero de 1997 hasta el 30 junio de 1999, con 3 columnas: >Identificador (ID), la >> fecha de entrada en la empresa (ENT) y la fecha de salida (SAL). >Deseo localizar >> aquellos trabajadores que, durante dicho periodo, NO han llegado a >pasar un 31 >> de diciembre y un 1 de enero seguidos (cambio de año) como >asalariados de la >> empresa, para lo cual hago: >> >> ## Los >> que entran durante 1997 pero no llegan al 1 de enero de 1998 >> >> t1 <- >> intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID >> ) >> >> t2 <- >> intersect ( trabajadores[trabajadores$ENT==as.Date("1997-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID >> ) >> >> t3 <- >> intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL==as.Date("1997-12-31"),]$ID >> ) >> >> t4 <- >> intersect ( trabajadores[trabajadores$ENT>as.Date("1997-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL<as.Date("1997-12-31"),]$ID >> ) >> >> ## Los >> que entran durante 1998 pero no llegan al 1 de enero de 1999 >> >> t5 <- >> intersect ( trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID >> ) >> >> t6 <- >> intersect ( >trabajadores[trabajadores$ENT==as.Date("1998-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID >> ) >> >> t7 <- >> intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID >> , >> >> trabajadores[trabajadores$SAL==as.Date("1998-12-31"),]$ID >> ) >> >> t8 <- >> intersect ( trabajadores[trabajadores$ENT>as.Date("1998-01-01"),]$ID >> >> trabajadores[trabajadores$SAL<as.Date("1998-12-31"),]$ID >> ) >> >> localizados >> <- c(t1, t2, t3, t4, t5, t6, t7, t8) >> >> >> >> ¿Existe >> alguna forma más eficiente de localizar a los mismos individuos? ¡¡ >Muchísimas gracias !! >> >> >> [[alternative HTML version deleted]] >> >> >> _______________________________________________ >> R-help-es mailing list >> R-help-es@r-project.org >> https://stat.ethz.ch/mailman/listinfo/r-help-es >> > >_______________________________________________ >R-help-es mailing list >R-help-es@r-project.org >https://stat.ethz.ch/mailman/listinfo/r-help-es-- Enviado desde mi teléfono con K-9 Mail. [[alternative HTML version deleted]]
En primer lugar, muchas gracias Carlos por la rápida y elegante respuesta. La he aplicado a mi base de datos, y rápidamente he obtenido "casi" el mismo resultado que obtenía de forma rudimentaria. Digo "casi" porque hay una pequeña diferencia de valor. Me ha faltado decir (me disculpo) que también hay que seleccionar a las personas que entran el 31 de diciembre en caso de que éstas no llegan a permanecer como mínimo hasta el 1 de enero que tiene lugar 1 año y un día después.Adaptando este hecho a tu ejemplo de resolución (he cambiado a 20 el valor de "ini" del individuo "d"): # Datos simuladosdat <- data.frame(id = letters[1:4], ini = c(1, 15, 15, 20), fin = c(11, 19, 25, 22))fin.anno <- 10 * 1:3 # Resultado que retorna:dat[mapply(function(x,y) ! any(fin.anno %in% x:y), dat$ini, dat$fin),] id ini fin2 b 15 19 Sin embargo, el último caso tampoco sería válido, pues reúne las dos condiciones comentadas: a) Ha entrado justo en un número del vector "fin.anno" y b) Su dato del vector "fin" es 22, es decir, no llega a superar el siguiente valor del vector "fin.anno" (en este caso sería 30): # Resultado que esperaría: id ini fin2 b 15 194 d 20 22 No sé si me explico, y muchas gracias. [[alternative HTML version deleted]]
Hola, Otra forma, utilizando la función de intervalos y la que comprueba si otro intervalo se solapa del paquete "lubridate": #---------------------- library(lubridate) fe.chas <- data.frame( entra=c('2001-01-01','2001-06-01','2003-01-01') ,sale=c('2002-01-01','2002-06-01','2004-01-01') ) ref <- new_interval(ymd('2001-12-01'), ymd('2002-01-01')) mapply( function(x,y,z) {int_overlaps(new_interval(x,y),z)} ,fe.chas$entra, fe.chas$sale, ref ) #--------------------- Produce este resultado:> fe.chas <- data.frame(+ entra=c('2001-01-01','2001-06-01','2003-01-01') + ,sale=c('2002-01-01','2002-06-01','2004-01-01') + )> fe.chasentra sale 1 2001-01-01 2002-01-01 2 2001-06-01 2002-06-01 3 2003-01-01 2004-01-01> ref <- new_interval(ymd('2001-12-01'), ymd('2002-01-01')) > ref[1] 2001-12-01 UTC--2002-01-01 UTC> > mapply(+ function(x,y,z) {int_overlaps(new_interval(x,y),z)} + ,fe.chas$entra, fe.chas$sale, ref + ) [1] TRUE TRUE FALSE> Saludos, Carlos Ortega www.qualityexcellence.es El 17 de julio de 2014, 21:18, Francisco Javier <iterador10@hotmail.com> escribió:> > > En primer lugar, muchas gracias Carlos por la rápida y elegante respuesta. > La he aplicado a mi base de datos, y rápidamente he obtenido "casi" el > mismo resultado que obtenía de forma rudimentaria. Digo "casi" porque hay > una pequeña diferencia de valor. Me ha faltado decir (me disculpo) que > también hay que seleccionar a las personas que entran el 31 de diciembre en > caso de que éstas no llegan a permanecer como mínimo hasta el 1 de enero > que tiene lugar 1 año y un día después.Adaptando este hecho a tu ejemplo de > resolución (he cambiado a 20 el valor de "ini" del individuo "d"): # Datos > simuladosdat <- data.frame(id = letters[1:4], ini = c(1, 15, 15, 20), fin > c(11, 19, 25, 22))fin.anno <- 10 * 1:3 # Resultado que > retorna:dat[mapply(function(x,y) ! any(fin.anno %in% x:y), dat$ini, > dat$fin),] id ini fin2 b 15 19 Sin embargo, el último caso tampoco > sería válido, pues reúne las dos condiciones comentadas: a) Ha entrado > justo en un número del vector "fin.anno" y b) Su dato del vector "fin" es > 22, es decir, no llega a superar el siguiente valor del vector "fin.anno" > (en este caso sería 30): # Resultado que esperaría: id ini fin2 b 15 > 194 d 20 22 No sé si me explico, y muchas gracias. > [[alternative HTML version deleted]] > > > _______________________________________________ > R-help-es mailing list > R-help-es@r-project.org > https://stat.ethz.ch/mailman/listinfo/r-help-es > >-- Saludos, Carlos Ortega www.qualityexcellence.es [[alternative HTML version deleted]]