I have a function that reads supermarket product allocation data, uses data based on his horizontal position (x), shelf level, aisle, and item no. I want to determine the upwards/downwards neighbor products by checking products placed on the upper/lower shelf that reduce the x difference. For that I have the following code: # Directorios de entrada y salida input_dir <- "J:/Zippedi/Data/Stage 3/Product_Data/Simplified_by_section/Data_with_neighbors_UD_and_CPs" output_dir <- "J:/Zippedi/Data/Stage 3/Product_Data/Simplified_by_section/Data_with_neighbors_UD_and_CPs_ver_2" # Crear directorio de salida si no existe if (!dir.exists(output_dir)) { print("Directory does not exist. Creating...") dir.create(output_dir, recursive = TRUE) print("Directory successfully created.") } else { print("Directory already exists") } # Verificar archivos disponibles print("Checking facings files available...") files_list <- list.files(input_dir, pattern = "\\.csv$", full.names = TRUE) for (file in files_list) { # Leer archivo CSV setwd(input_dir) df <- fread(file) # fread es más eficiente para archivos grandes # DataFrame de salida output_df <- data.table() # Bucle por cada 'aisle' for (aisle_index in unique(df$aisle)) { print(aisle_index) df_aisle <- df[df$aisle == aisle_index, ] for (aisle_part_index in unique(df_aisle$aisle_part)) { print(aisle_part_index) df_aisle_part <- df_aisle[df_aisle$aisle_part == aisle_part_index, ] for (orient_index in unique(df_aisle_part$orient)) { print(orient_index) df_orient <- df_aisle_part[df_aisle_part$orient == orient_index, ] for (item_index in unique(df_orient$item)) { print(item_index) item_data <- df_orient[df_orient$item == item_index, ] for (date in unique(item_data$date_PD)) { print(date) data_for_date <- df_orient[df_orient$date_PD == date,] item_data <- df_orient[df_orient$item == item_index & df_orient$date_PD == date, ] current_shelf_level <- as.numeric(item_data$No_of_cluster[1]) print(current_shelf_level) current_loc_x <- as.numeric(item_data$Location_x_mean[1]) print(current_loc_x) uw_shelf_data <- data_for_date[data_for_date$No_of_cluster == current_shelf_level + 1, ] print(paste("No of rows in uw_shelf_data:", nrow(uw_shelf_data))) dw_shelf_data <- data_for_date[data_for_date$No_of_cluster == current_shelf_level - 1, ] print(paste("No of rows in dw_shelf_data:", nrow(dw_shelf_data))) if (nrow(uw_shelf_data) == 0) { # Procesar `neighbor_dw` dw_shelf_data$dist <- abs(dw_shelf_data$Location_x_mean - current_loc_x) closest_dw_neighbor <- dw_shelf_data[which.min(dw_shelf_data$dist), ] item_data$neighbor_dw <- as.character(closest_dw_neighbor$item[1]) item_data$neighbor_uw <- NA_character_ } else if (nrow(dw_shelf_data) == 0) { # Procesar `neighbor_uw` uw_shelf_data$dist <- abs(uw_shelf_data$Location_x_mean - current_loc_x) closest_uw_neighbor <- uw_shelf_data[which.min(uw_shelf_data$dist), ] item_data$neighbor_uw <- as.character(closest_uw_neighbor$item[1]) item_data$neighbor_dw <- NA_character_ } else if (nrow(dw_shelf_data) == 0 & nrow(uw_shelf_data) == 0) { item_data$neighbor_uw <- NA_character_ item_data$neighbor_dw <- NA_character_ } else { # Procesar ambos uw_shelf_data$dist <- abs(uw_shelf_data$Location_x_mean - current_loc_x) dw_shelf_data$dist <- abs(dw_shelf_data$Location_x_mean - current_loc_x) closest_uw_neighbor <- uw_shelf_data[which.min(uw_shelf_data$dist), ] closest_dw_neighbor <- dw_shelf_data[which.min(dw_shelf_data$dist), ] item_data$neighbor_uw <- as.character(closest_uw_neighbor$item[1]) item_data$neighbor_dw <- as.character(closest_dw_neighbor$item[1]) } # Crear columnas faltantes en output_df #print("Adding missing columns to output_df") #missing_columns <- setdiff(names(item_data), names(output_df)) #for (col in missing_columns) { # output_df[, (col) := NA] #} #print("success.") # Añadir item_data a output_df print("Binding item_data to output_df") output_df <- rbind(output_df, item_data, fill = TRUE) print("success.") # Limpiar memoria rm(item_data, closest_uw_neighbor, closest_dw_neighbor) gc() } } # Limpiar memoria rm(df_orient) gc() } rm(df_aisle_part) gc() } rm(df_aisle) gc() } # Guardar archivo output_filename <- paste0(output_dir, "/", basename(file)) fwrite(output_df, output_filename) # Limpiar memoria rm(output_df) gc() } } But it solves the task to slowly. It reads 5 products per second. I need to find a way to solve the task faster, either in R or Python. I tried using ChatGPT but it won't help. Continue reading...