[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