[R-es] FW: Selección eficiente de individuos
"Olivier Nuñez"
onunez en unex.es
Vie Jul 18 10:26:52 CEST 2014
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)]
> DT
ID 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")
> DT
ID 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)]
> DT
ID 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
Más información sobre la lista de distribución R-help-es