¿Cómo puedo guardar archivos en paralelo sin aumentar automáticamente el tamaño del archivo?

9

Tengo 2 scripts que hacen exactamente lo mismo.

Pero un script está produciendo 3 archivos RData que pesan 82.7 KB, y el otro script está creando 3 archivos RData que pesan 120 KB.

el primero es sin paralelo:

library("plyr")
ddply(.data = iris,
      .variables = "Species",
      ##.parallel=TRUE,##Without parallel
      .fun = function(SpeciesData){

      #Create Simple Model -------------------------------------------------------------  
      Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)

      #Save The Model -------------------------------------------------------------               
       save(Model,
            compress = FALSE,
            file = gsub(x =  "Species.RData",
                        pattern = "Species",
                        replacement = unique(SpeciesData$Species)))

 })

El segundo es con paralelo:

library("plyr")
doSNOW::registerDoSNOW(cl<-snow::makeCluster(3))
ddply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){

      #Create Simple Model -------------------------------------------------------------  
      Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)

      #Save The Model -------------------------------------------------------------               
       save(Model,
            compress = FALSE,
            file = gsub(x =  "Species.RData",
                        pattern = "Species",
                        replacement = unique(SpeciesData$Species)))

 })
snow::stopCluster(cl)

El segundo script crea archivos que pesan un 42% más.

¿Cómo puedo guardar archivos en paralelo sin aumentar automáticamente el tamaño del archivo?

Dima Ha
fuente
¿Desea reducir el tamaño general de los archivos de los modelos o es esto una curiosidad más técnica sobre por qué los archivos son más grandes? ¿Cuál es el objetivo más grande que estás buscando?
Roger-123
Tienes que bloquear el acceso al archivo, mientras se escribe por el hilo. ¿De otra manera? El archivo se romperá.
Profesor08
@ Profesor08 ¿Cómo bloqueo el acceso al archivo mientras está escribiendo?
Dima Ha
@ Roger-123 Intento reducir el tamaño de la memoria de los archivos guardados.
Dima Ha
@DimaHa puede intentar buscar en Google algo así r lang lock filey después de 5 segundos encontrará el paquete deseado cran.r-project.org/web/packages/filelock/filelock.pdf
Profesor08

Respuestas:

2

Como otros mencionaron, puede haber una pequeña cantidad de información sobre el entorno que se está guardando en los archivos o similar que probablemente no notaría, excepto que los archivos son tan pequeños.

Si solo le interesa el tamaño del archivo, intente guardar los modelos en una sola lista y luego guárdelos en un archivo. ddplysolo puede manejar un data.frame como resultado de la función, por lo que debemos usarlo dlplypara indicarle que almacene los resultados en una lista. Hacer esto se guardó en un solo archivo que tenía 60k.

Aquí hay un ejemplo de lo que estoy hablando:

library("plyr")
doSNOW::registerDoSNOW(cl<-snow::makeCluster(3))
models<-dlply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){

        #Create Simple Model -------------------------------------------------------------  
        lm(formula = Sepal.Length~Sepal.Width+Petal.Length+Petal.Width, data = SpeciesData)
      })
snow::stopCluster(cl)

save(models, compress= FALSE, file= 'combined_models')
Roger-123
fuente
3

No he usado ddply para paralelizar los objetos guardados, así que supongo que el archivo se hace mucho más grande porque cuando guarda el objeto modelo, también contiene información sobre el entorno desde el que se guarda.

Entonces, usando su código ddply anterior, los tamaños que tengo son:

sapply(dir(pattern="RData"),file.size)
setosa.RData versicolor.RData  virginica.RData 
       36002            36002            36002 

Hay dos opciones, una es usar purrr / furrr:

library(furrr)
library(purrr)

func = function(SpeciesData){
  Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)
  save(Model,
       compress = FALSE,
       file = gsub(x =  "Species.RData",
                   pattern = "Species",
                   replacement = unique(SpeciesData$Species)))
}

split(iris,iris$Species) %>% future_map(func)

sapply(dir(pattern="RData"),file.size)
    setosa.RData versicolor.RData  virginica.RData 
           25426            27156            27156

O para usar saveRDS (y ddply?) Ya que solo tiene un objeto para guardar:

ddply(.data = iris,
      .variables = "Species",
      .parallel=TRUE,##With parallel
      .fun = function(SpeciesData){
        Model <- lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width",data = SpeciesData)
        saveRDS(Model,
             gsub(x =  "Species.rds",
                         pattern = "Species",
                         replacement = unique(SpeciesData$Species)))

      })

sapply(dir(pattern="rds"),file.size)
    setosa.rds versicolor.rds  virginica.rds 
          6389           6300           6277 

Lo harás en readRDSlugar de loadobtener el archivo:

m1 = readRDS("setosa.rds")
m1
Call:
lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width", 
    data = SpeciesData)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      2.3519        0.6548        0.2376        0.2521  

Podemos ver los coeficientes en comparación con el objeto rda:

m2 = get(load("setosa.RData"))
m2

Call:
lm(formula = "Sepal.Length~Sepal.Width+Petal.Length+Petal.Width", 
    data = SpeciesData)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      2.3519        0.6548        0.2376        0.2521  

Los objetos no son idénticos debido a las partes del entorno, pero en términos de predicción u otras cosas para las que normalmente los usamos, funciona:

identical(predict(m1,data.frame(iris[1:10,])),predict(m2,data.frame(iris[1:10,])))
Estúpido Lobo
fuente