Estoy tratando de fusionar 2 marcos de datos que se ven así:

library(data.table)

#transactions
colNames<-c("id","tran")
df2 <- data.table(c("010","010","030","210","310","050"), as.Date(c("2012-12-28","2014-01-01","2011-07-05","2015-04-05","2013-07-05","2012-08-01")))
names(df2) <- colNames

#status change
colNames<-c("id","status")
df1 <- data.table(c("010","010","010","030","030","210","210","310","050"),
as.Date(c("2012-10-28","2013-11-01","2014-01-01","2011-05-09","2011-08-04","2013-07-06","2015-01-01","2013-05-04","2010-09-10")))
names(df1) <- colNames

En el siguiente resultado:

df3
    id       tran       status
1: 010 2012-12-28   2012-10-28
2: 010 2014-01-02   2014-01-01
3: 030 2011-07-05   2011-05-09
4: 210 2015-04-05   2015-01-01
5: 310 2013-07-05   2013-05-04
6: 050 2012-08-01   2010-09-10
  • Hay más transacciones que cambios de estado.
  • Las fechas están bien formateadas.
  • Hay muchas columnas en cada marco de datos, pero estas son las importantes para la fusión.

Básicamente, todas las transacciones ocurren en algún momento después de un cambio de estado. Estoy tratando de fusionar todas las transacciones con su cambio de estado apropiado para cada ID. La parte complicada es que las fechas casi nunca son las mismas. Necesito la fecha de cambio de estado correspondiente a cada transacción ...

Estoy mirando? Fusionar pero no veo cómo puede hacer algo así. ¿Quizás? Agregado, pero ¿cómo sabría que la agregación está condicionada a otro marco de datos?

¡Gracias!

2
Soran 13 ene. 2017 a las 00:19
1
Creo que tienes un error en la tercera línea, pero esto probablemente debería funcionar df2[df1, status := i.status, on = .(id, tran = status), roll = -Inf] o tal vez quieras df2[df1, status := i.status, on = .(id, tran = status), roll = "nearest"].
 – 
David Arenburg
13 ene. 2017 a las 00:40
Corregido el error. Bien, la primera versión se parece a lo que busco. Si lo pones como solución, lo aceptaré. ¿Hay algún lugar donde pueda leer sobre ese tipo de manipulación? Es nuevo para mi ¡Muchas gracias!
 – 
Soran
13 ene. 2017 a las 01:19
Consulte esto tal vez
 – 
David Arenburg
13 ene. 2017 a las 01:34

1 respuesta

La mejor respuesta

Simplemente puede realizar una combinación rodante.

df2[df1, status := i.status, on = .(id, tran = status), roll = -Inf]
df2
#     id       tran     status
# 1: 010 2012-12-28 2012-10-28
# 2: 010 2014-01-01 2014-01-01
# 3: 030 2011-07-05 2011-05-09
# 4: 210 2015-04-05 2015-01-01
# 5: 310 2013-07-05 2013-05-04
# 6: 050 2012-08-01 2010-09-10
  • roll = -Inf solo significa que para cada incidente en df2, queremos hacer coincidir el incidente inferior más cercano en df1 sin importar qué tan lejos esté.
  • status := i.status significa que queremos crear una columna llamada status en df2 por referencia (en su lugar) mientras tomamos prestados los valores coincidentes de df1$status. i. estados para la columna de la tabla en la i ésima ubicación en df2
2
David Arenburg 13 ene. 2017 a las 01:54