[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