tutorial - superponer graficas en r
Combinación no equi usando data.table: columna que falta en la salida (1)
Estoy haciendo un join no equi izquierdo usando data.table
:
OUTPUT <- DT2[DT1, on=.(DOB, FORENAME, SURNAME, POSTCODE, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
La OUTPUT
contiene una combinación correcta a la izquierda, con la excepción de que falta la columna MONTH
(que está presente en DT1).
¿Es esto un error en data.table
?
NB: por supuesto, START_DATE
, EXPIRY_DATE
y MONTH
están en el mismo formato AAAA-MM-DD, IDate. Los resultados de la unión son correctos basados en estos criterios no equi. Es solo que la columna falta y necesito usarla en trabajos posteriores.
Edición 1 : Ejemplo reproducible simplificado
DT1 <- structure(list(ID = c(1, 2, 3), FORENAME = c("JOHN", "JACK",
"ROB"), SURNAME = c("JOHNSON", "JACKSON", "ROBINSON"), MONTH = structure(c(16953L,
16953L, 16953L), class = c("IDate", "Date"))), .Names = c("ID",
"FORENAME", "SURNAME", "MONTH"), row.names = c(NA, -3L), class = c("data.table",
"data.frame"))
DT2 <- structure(list(CERT_NUMBER = 999, FORENAME = "JOHN", SURNAME = "JOHNSON",
START_DATE = structure(16801L, class = c("IDate", "Date")),
EXPIRY_DATE = structure(17166L, class = c("IDate", "Date"
))), .Names = c("CERT_NUMBER", "FORENAME", "SURNAME", "START_DATE",
"EXPIRY_DATE"), row.names = c(NA, -1L), class = c("data.table",
"data.frame"))
OUTPUT <- DT2[DT1, on=.(FORENAME, SURNAME, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
> OUTPUT
CERT_NUMBER FORENAME SURNAME START_DATE EXPIRY_DATE ID
1: 999 JOHN JOHNSON 2016-06-01 2016-06-01 1
2: NA JACK JACKSON 2016-06-01 2016-06-01 2
3: NA ROB ROBINSON 2016-06-01 2016-06-01 3
-
FORENAME
ySURNAME
se unen y están presentes en la salida. -
MONTH
también está (no equi) unido, y está ausente de la salida.
¿Por qué es este comportamiento esperado?
Incluso si se trata de un comportamiento esperado, no es útil en mi caso, porque necesito retener el MONTH
para una mayor manipulación de datos.
Mi resultado esperado sería la misma tabla, pero con la columna MONTH
retenida como está en DT1. Después de todo, lo que espero de una combinación a la izquierda es que se retengan todas las filas y columnas de la tabla izquierda (DT1) y para todas las columnas y solo se agreguen las filas coincidentes de la tabla correcta (DT2).
CERT_NUMBER FORENAME SURNAME START_DATE EXPIRY_DATE ID MONTH
1: 999 JOHN JOHNSON 2016-01-01 2016-12-31 1 2016-06-01
2: NA JACK JACKSON <NA> <NA> 2 2016-06-01
3: NA ROB ROBINSON <NA> <NA> 3 2016-06-01
Editar 2 : aparentemente en la salida producida por mi código, las fechas de INICIO y FIN también son incorrectas. ¡Solo la persona 1 tenía un certificado con una fecha de inicio el 1 de enero y una fecha de finalización el 31 de diciembre! El resultado esperado es lo que debería ser. Pero la producción real hizo todo 1-ene.
En data.table, las uniones de la forma x[i]
tradicionalmente usan valores de i
pero usan nombres de columna de x
. Aunque esto es diferente de SQL, que devuelve ambos, este valor predeterminado tiene mucho sentido para equi join ya que estamos interesados en todas las filas de i
y si coinciden, ambos data.tables tienen valores iguales de todos modos, y si no lo hacen tenemos que mantener esos valores sin igual de i
en el resultado.
Pero para las combinaciones no equitativas , dado que los valores pueden no coincidir exactamente , es decir, pueden estar dentro de un rango, puede haber casos donde tendremos que devolver resultados similares a SQL (o identificar tales casos y devolver el resultado esperado por el usuario, similar al caso de equi une). Esto no se ha hecho todavía, pero he colocado una provisión para él en este momento, que es hacer referencia explícitamente a las columnas con una x.
prefijo. No es conveniente, estoy de acuerdo. Espero que esto se solucione automáticamente pronto.
A continuación, le mostramos cómo obtener su resultado usando x.
prefijo.
ans <- DT2[DT1, .(CERT_NUMBER, FORENAME, SURNAME, x.START_DATE, x.EXPIRY_DATE, ID, MONTH),
on=.(FORENAME, SURNAME, START_DATE <= MONTH, EXPIRY_DATE >= MONTH)]
IIRC hay un problema archivado en la página del proyecto GitHub sobre esto también.