[R-es] Optimizar bucle for
Griera
gr|er@ @end|ng |rom y@ndex@com
Lun Oct 7 12:01:15 CEST 2024
Hola a todos:
Tengo un bucle que tarda horas y me gustaría optimizarlo. Me explico. Simplificando, tengo una tabla con 332.505 registros de 63.738 individuos. Cada registro es una medida realiza de unos
días a unos meses o años después de la anterior. Lo que quiero es borrar aquellos registros que entre él y el anterior hayan transcurrido menos
de 6 meses, de manera que me quede una tabla con sólo aquellas medidas realizadas al menos 6 meses después de la anterior.
La tabla simplificada (no diferencio entre medida y ID y con una nueva columna “BORRAR”) seria:
## Código
df <- data.frame(
ID = c(1, 1, 1, 2, 2, 2, 1, 3),
date = as.Date(c("2023-01-01", "2023-05-15", "2023-12-01", "2023-01-01", "2023-04-01", "2023-12-01", "2023-03-15", "2023-01-01")),
BORRAR = 0)
## El código con el bucle (doble bucle) es:
# Definir umbral : 6 meses: si registro posterior menor 6 meses: borrar
umbral <- 30.5 * 6
# Ordenar por ID i fecha
df <- df[order(df$ID, df$date), ]
# Bucle per cada ID
for (id in unique(df$ID)) {
# Filtrar per ID actual
subset_df <- df[df$ID == id, ]
# Si hay más de un registro borrar aquellos de más de 6 meses
if (nrow(subset_df) > 1) {
# Inicializar la referencia del primer registro no borrado
reference_date <- subset_df$date[1]
for (i in 2:nrow(subset_df)) {
# Calcular la diferencia en días respecto a la referencia
diff_days <- as.numeric(difftime(subset_df$date[i], reference_date, units = "days"))
# Si la diferencia es menor que el umbral, marcado para borrar
if (diff_days < umbral) {
df$BORRAR[df$ID == id & df$date == subset_df$date[i]] <- 1
} else {
# Actualizar la fecha referencia al nuevo registro no borrado
reference_date <- subset_df$date[i]
} ## Fin de if (diff_days < umbral)
} ## Fin del for (I in 2:nrow(subset_df))
} ## Fin de (nrow(subset_df) > 1)
}
# Resultado sin borrar registros
df
## fin Código
El problema es que tarda muchas horas en ejecutarse. He intentado
optimizarlo (antes tardaba más), pero ya no se más R. ¿Algunas
sugerencias pera que vaya más rápido?
Muchas gracias de antemano por su ayuda.
Más información sobre la lista de distribución R-help-es