es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Una forma eficiente en términos de memoria de leer y fusionar una gran lista de archivos de datos SPSS en un dataframe y guardar como RDS.

Tengo cuatro vectores en una lista, donde cada vector contiene 92 elementos de rutas a archivos de datos de SPSS que deseo combinar y convertir en un archivo RDS.

Cada vector de archivos de datos de SPSS debe leerse primero y combinarse en un marco de datos por fila, y luego los cuatro marcos de datos resultantes deben unirse por columnas. Quiero hacer algo como esto:

library(dplyr)

'pathlistX' son vectores, cada uno contiene 92 elementos de ruta

paths <- list(pathlist1, pathlist2, pathlist3, pathlist4)
my_df <- lapply(paths, function(x) {
                                lapply(x, haven::read_spss) %>%
                                reduce(bind_rows)
                               }
                        ) %>%
                 reduce(full_join) %>%
                 saveRDS(., "/path/to/folder/my_data.RDS")

Sin embargo, esto presenta un problema ya que me quedo sin memoria (32 GB de RAM). No estoy seguro de por qué el proceso requiere tanta memoria, ya que el tamaño total de todos los archivos de SPSS es de aproximadamente 2,5 GB. Por lo tanto, estoy buscando una forma más eficiente en cuanto a la memoria para realizar esta tarea.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible razón para quedarse sin memoria es que todos los datos se carguen en la RAM de una vez. Esto puede ser intensivo en memoria si los datos son grandes. Una solución potencial para esto es usar el paquete data.table, que tiene una huella de memoria más baja en comparación con otros paquetes de R.

    library(data.table)
    
    # 'pathlistX' son vectores, cada uno de ellos contiene 92 elementos de ruta
    paths <- list(pathlist1, pathlist2, pathlist3, pathlist4)
    my_df <- lapply(paths, function(x) {
                # Para cada vector, lee y une los archivos SPSS en un objeto data.table
                lapply(x, function(file_path) {
                    data.table::fread(file_path, sep = ',', header = TRUE, na.strings = c("", "NA"))
                }) %>% 
                # luego concatena la lista de data.tables en un único data.table
                rbindlist
                }
            ) %>% 
            # finalmente, mezcla la lista de data.tables por columnas
            Reduce(function(...) merge(..., all = TRUE, by = NULL), .) %>% 
            # guarda el dataframe resultante en un archivo RDS
            saveRDS(., "/ruta/a/carpeta/mis_datos.RDS")
    

    Aquí, se utiliza la función data.table::fread para leer cada archivo SPSS y se reemplaza bind_rows con rbindlist para unir los data.tables. La lista resultante de data.tables se fusiona por columnas utilizando la función Reduce. Esto debería conducir a una reducción significativa en el uso de la memoria, lo que permitirá completar el procesamiento sin quedarse sin memoria.

Comments are closed.