Как сохранить файлы параллельно без автоматического увеличения размера файла?

9

У меня есть 2 сценария, которые делают точно так же.

Но один сценарий создает 3 файла RData, который весит 82,7 КБ, а другой сценарий создает 3 файла RData, который весит 120 КБ.

первый без параллели:

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)))

 })

Вторая с параллельной:

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)

второй скрипт создает файлы, которые весят на 42% больше.

Как сохранить файлы параллельно без автоматического увеличения размера файла?

Дима Ха
источник
Вы хотите уменьшить общий размер файлов моделей или это технический интерес к тому, почему файлы больше? Какую большую цель вы ищете?
Роджер-123
Вы должны заблокировать доступ к файлу, пока он пишет потоком. Другой путь? файл будет сломан.
Profesor08
@ Profesor08 Как заблокировать доступ к файлу во время записи?
Дима Ха
@ Roger-123 Я пытаюсь уменьшить объем памяти сохраняемых файлов.
Дима Ха
@DimaHa может попытаться гуглить что-то вроде, r lang lock fileи через 5 секунд вы найдете нужный пакет cran.r-project.org/web/packages/filelock/filelock.pdf
Profesor08

Ответы:

2

Как уже упоминалось, может быть небольшое количество информации об окружающей среде, которая сохраняется в файлах или аналогичной, которую вы, вероятно, не заметите, за исключением того, что файлы настолько малы.

Если вас интересует только размер файла, попробуйте сохранить модели в одном списке, а затем сохранить его в одном файле. ddplyможет обрабатывать только data.frame в результате выполнения функции, поэтому мы должны dlplyвместо этого использовать его, чтобы сообщить о необходимости сохранения результатов в списке. При этом сохраняется только один файл, который был 60 КБ.

Вот пример того, о чем я говорю:

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
источник
3

Я не использовал ddply для распараллеливания сохраняемых объектов, поэтому я предполагаю, что файл становится намного больше, потому что когда вы сохраняете объект модели, он также несет некоторую информацию о среде, из которой он был сохранен.

Таким образом, используя приведенный выше код ddply, я имею следующие размеры:

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

Есть два варианта, один из них - использовать 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

Или использовать saveRDS (и ddply?), Поскольку у вас есть только один объект для сохранения:

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 

Вы сделаете readRDSвместо того, loadчтобы получить файл:

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  

Мы можем посмотреть на коэффициенты в сравнении с объектом 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  

Объекты не идентичны из-за частей среды, но с точки зрения предсказания или других вещей, для которых мы обычно используем это, это работает:

identical(predict(m1,data.frame(iris[1:10,])),predict(m2,data.frame(iris[1:10,])))
StupidWolf
источник