varias una tabla studio seleccionar recodificar graficos graficas filas extraer eliminar data contar columna r join dataframe

tabla - R: Usar valores del marco de datos A a partir de una fecha anterior a rellenar una fila en el marco de datos B



seleccionar filas en r (3)

Esto puede ser muy complicado y sospecho que requiere un conocimiento avanzado. Ahora tengo dos tipos diferentes de marcos de datos. Necesito combinar:

Los datos:

Dataframe A:

enumera todas las fechas de transfusión según el ID del paciente. Cada transfusión está representada por una fila separada, los pacientes pueden tener transfusiones múltiples. Diferentes pacientes pueden tener transfusiones en la misma fecha.

Patient ID Transfusion.Date 1 01/01/2000 1 01/30/2000 2 04/01/2003 3 04/01/2003

Los marcos de datos de Tipo B contienen resultados de pruebas en otras fechas, también por ID del paciente:

Patient ID Test.Date Test.Value 1 11/30/1999 negative 1 01/15/2000 700 copies/uL 1 01/27/2000 900 copies/uL 2 03/30/2003 negative

Lo que me gustaría tener es el Dataframe A con el mismo número de filas (1 por cada transfusión), y con el Test.Value más reciente como una columna separada. Cada fecha de transfusión debe tener el resultado de la prueba más cercana (previa) a la transfusión.

salida deseada:

->

Patient ID Transfusion.Date Pre.Transfusion.Test 1 01/01/2000 negative 1 01/30/2000 900 copies/ul 2 04/01/2003 negative 3 04/01/2003 NA

Creo que la estrategia general sería subconjunto de los marcos de datos por las ID de los pacientes. Luego, tome todas las fechas de transfusión para el paciente 1, verifique cuál es el resultado más cercano a todas las fechas de prueba disponibles para cada elemento y luego devuelva el valor más cercano.

¿Cómo puedo explicarle a R que haga eso?

Edición 1 : Aquí está el código R para estos ejemplos

df_A <- data.frame(MRN = c(1,1,2,3), Transfusion.Date = as.Date(c(''01/01/2000'', ''01/30/2000'', ''04/01/2003'',''04/01/2003''),''%m/%d/%Y'')) df_B <- data.frame(MRN = c(1,1,1,2), Test.Date = as.Date(c(''11/30/1999'', ''01/15/2000'', ''01/27/2000'', ''03/30/2003''),''%m/%d/%Y''), Test.Result = c(''negative'', ''700 copies/ul'',''900 copies/ul'',''negative''))

Editar 2:

Para aclarar, los datos resultantes deberían ser: Paciente A recibió transfusiones el Día X y el Día Y. (para df_A). Antes de la transfusión en el día X, su resultado de la prueba más reciente fue X (fecha de la prueba más cercana a la primera transfusión, en df_B). Antes de la transfusión en el día Y, su resultado de la prueba más reciente fue Y (antes de la segunda transfusión, también en df_B. Df_B también contiene un grupo de otras fechas de prueba, que no son necesarias para el resultado final.


Aquí está usando las data.table rolling de data.table :

require(data.table) setkey(setDT(df_A), MRN, Transfusion.Date) setkey(setDT(df_B), MRN, Test.Date) df_B[df_A, roll=TRUE] # MRN Test.Date Test.Result # 1: 1 2000-01-01 negative # 2: 1 2000-01-30 900 copies/ul # 3: 2 2003-04-01 negative # 4: 3 2003-04-01 NA

  • setDT convierte data.frame en data.table por referencia (sin ninguna copia adicional). Eso dará como resultado df_A y df_B ahora siendo data.tables.

  • setkey clasifica el data.table por las columnas que proporcionamos, y marca esas columnas como columnas de clave, lo que nos permite usar combinaciones basadas en búsquedas binarias .

  • Realizamos una combinación de la forma x[i] en las columnas clave, donde para cada fila de i , se devuelven las filas coincidentes de x (si hay alguna, más NA) junto con las filas de i . Esto es lo que llamamos un equi-join . Al agregar roll = TRUE , en el caso de una falta de coincidencia, la última observación se traslada hacia adelante (LOCF). Esto es lo que llamamos una unión rodante . La ordenación en orden creciente (debido a setkey() ) asegura que la última observación es la fecha más reciente.

HTH


OK gracias por la ayuda de todos. Me llevó mucho trabajo, sangre, sudor y lágrimas, pero esta es la solución que se me ocurrió:

  1. Combina ambos marcos de datos:

df_AB <- fusionar (df_A, df_B, all.x = T)

df_AB:

MRN Transfusion.Date Test.Date Test.Result 1 1 2000-01-01 1999-11-30 negative 2 1 2000-01-01 2000-01-15 700 copies/ul 3 1 2000-01-01 2000-01-27 900 copies/ul 4 1 2000-01-30 1999-11-30 negative 5 1 2000-01-30 2000-01-15 700 copies/ul 6 1 2000-01-30 2000-01-27 900 copies/ul 7 2 2003-04-01 2003-03-30 negative 8 3 2003-04-01 <NA> <NA>

Usando dplyr

df_tests <- df_AB %>% group_by(MRN, Transfusion.Date) %>% mutate(Time.Difference = Transfusion.Date - Test.Date) %>% filter(Time.Difference > 0) %>% arrange(Time.Difference) %>% summarize(Test.Date = Test.Date[1], Test.Result = Test.Result[1])

df_tests:

MRN Transfusion.Date Test.Date Test.Result 1 1 2000-01-01 1999-11-30 negative 2 1 2000-01-30 1999-11-30 negative 3 2 2003-04-01 2003-03-30 negative

using merge again for MRN3:

df_desired <- merge(df_A, df_tests, all.x = T) MRN Transfusion.Date Test.Date Test.Result 1 1 2000-01-01 1999-11-30 negative 2 1 2000-01-30 2000-01-27 900 copies/ul 3 2 2003-04-01 2003-03-30 negative 4 3 2003-04-01 <NA> <NA>


dfLast <- df_B[ df_B$Test.Date %in% as.Date( tapply(df_B$Test.Date, df_B$MRN, tail,1),"1970-01-01"), ] merge(df_A, dfLast, by=c(1:2,1:2) ,all.y=TRUE) MRN Transfusion.Date Test.Result 1 1 2000-01-27 900 copies/ul 2 2 2003-03-30 negative

Editado Tenía algunos errores lógicos y algunos errores de síntesis. respondí tapply los valores enteros de las Fechas y como señaló que estaba usando el nombre de columna incorrecto en el paso de reducción de datos.