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]]
Hola Carlos, ¿No es posible trabajar con el primer script y ejemplo que me enviaste? El motivo es que no acabo de entender el funcionamiento de este segundo script (he cambiado algún dato), pues creo que presenta 2 inconvenientes (por favor, corrígeme si me equivoco): datos <- data.frame( id=1:3, entra=c('2001-01-01','2002-06-01','2003-01-01'), sale=c('2002-01-01','2002-12-31','2004-01-01')) # Entiendo que ref define los puntos que ha de cruzar el individuo:ref <- new_interval(ymd('2001-12-31'), ymd('2003-12-31')) logical <- mapply( function(x,y,z) {int_overlaps(new_interval(x,y),z)} ,datos$entra, datos$sale, ref) TRUE TRUE TRUE El primer y el tercer individuo cruzan respectivamente el 31 dic 2001 y el 31 dic 2003, correcto. Pero el segundo individuo NO llega a cruzar el 31 de diciembre de 2002 (pues sale justo en esa fecha), y en cambio el vector me devuelve ¿TRUE? [[alternative HTML version deleted]]
Bueno, aquí una posible solución ilustrada por una pequeña simulación, que procura resolver la dificultad al fin del año (entrada en el 31 de diciembre):> n=10 #10 individuos > set.seed(1000) > require(data.table) > entrada=as.Date(sample(-300:100,n),origin="1998-01-01") > salida=entrada+sample(1:600,n) > DT=data.table(ID=1:n,entrada=entrada,salida=salida) > DT[,Cambios:=year(salida)-year(entrada)] > DTID entrada salida Cambios 1: 1 1997-07-16 1998-02-11 1 2: 2 1998-01-04 1999-04-02 1 3: 3 1997-04-21 1997-10-28 0 4: 4 1997-12-06 1999-05-07 2 5: 5 1997-09-28 1998-12-28 1 6: 6 1997-04-02 1997-05-16 0 7: 7 1997-12-23 1998-10-12 1 8: 8 1997-10-22 1998-11-03 1 9: 9 1997-05-30 1997-07-20 0 10: 10 1997-06-15 1998-05-27 1 Donde la variable "Cambios" cuenta el número de veces que el contrato del empleado experimentó un cambio de año. Ahora considero el caso de en empleado (por ejemplo el empleado "10") que entra en la empresa a final del año:> DT[10,"entrada"]=as.Date("1997-12-31") > DTID entrada salida Cambios 1: 1 1997-07-16 1998-02-11 1 2: 2 1998-01-04 1999-04-02 1 3: 3 1997-04-21 1997-10-28 0 4: 4 1997-12-06 1999-05-07 2 5: 5 1997-09-28 1998-12-28 1 6: 6 1997-04-02 1997-05-16 0 7: 7 1997-12-23 1998-10-12 1 8: 8 1997-10-22 1998-11-03 1 9: 9 1997-05-30 1997-07-20 0 10: 10 1997-12-31 1998-05-27 1 Adaptando el criterio anterior, obtenemos lo deseado:> DT[,Cambios:=year(salida)-year(entrada+1)] > DTID entrada salida Cambios 1: 1 1997-07-16 1998-02-11 1 2: 2 1998-01-04 1999-04-02 1 3: 3 1997-04-21 1997-10-28 0 4: 4 1997-12-06 1999-05-07 2 5: 5 1997-09-28 1998-12-28 1 6: 6 1997-04-02 1997-05-16 0 7: 7 1997-12-23 1998-10-12 1 8: 8 1997-10-22 1998-11-03 1 9: 9 1997-05-30 1997-07-20 0 10: 10 1997-12-31 1998-05-27 0 Un saludo. Olivier> 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.chas > entra 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 en 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 en r-project.org >> https://stat.ethz.ch/mailman/listinfo/r-help-es >> >> > > > -- > Saludos, > Carlos Ortega > www.qualityexcellence.es > > [[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 >-- ____________________________________ Olivier G. Nuñez Email: onunez en unex.es http://kolmogorov.unex.es/~onunez Tel : +34 663 03 69 09 Departamento de Matemáticas Universidad de Extremadura
Hola, No, fíjate que en "ref" he puesto un intervalo mínimo de un día: el fin de año del 2001 (2001-12-31) y el año nuevo del 2002 (2002-01-01). La idea de que este intervalo sea mínimo tiene justamente esta idea de confirmar si el empleado estuvo contratado tanto el 31 como el 1 del siguiente año. Si amplias mucho este intervalo como has hecho a dos años enteros (2002 y 2003) se produce el overlap. Saludos, Carlos Ortega www.qualityexcellence.es El 18 de julio de 2014, 10:17, Francisco Javier <iterador10@hotmail.com> escribió:> Hola Carlos, > > ¿No es posible trabajar con el primer script y ejemplo que me enviaste? > El motivo es que no acabo de entender el funcionamiento de este segundo > script (he cambiado algún dato), pues creo que presenta 2 inconvenientes > (por favor, corrígeme si me equivoco): > > > > datos <- data.frame( id=1:3, > > entra=c('2001-01-01','2002-06-01','2003-01-01'), > > sale=c('2002-01-01','2002-12-31','2004-01-01')) > > # Entiendo que ref define los puntos que ha de cruzar el individuo: > ref <- new_interval(ymd('2001-12-31'), ymd('2003-12-31')) > > logical <- mapply( > function(x,y,z) > {int_overlaps(new_interval(x,y),z)} > ,datos$entra, datos$sale, ref) > > TRUE TRUE TRUE > > El primer y el tercer individuo cruzan respectivamente el 31 dic 2001 y el > 31 dic 2003, correcto. Pero el segundo individuo NO llega a cruzar el 31 de > diciembre de 2002 (pues sale justo en esa fecha), y en cambio el vector me > devuelve ¿TRUE? >-- Saludos, Carlos Ortega www.qualityexcellence.es [[alternative HTML version deleted]]