R запускать несколько сценариев одновременно в терминале

#r #terminal

Вопрос:

У меня есть функция R, которая загружает, обрабатывает и сохраняет много файлов. Вот фиктивная версия:

 load_process_saveFiles <- function(onlyFiles = c()){
    
  allFiles <- paste(LETTERS, '.csv', sep = '')
  
  # If desired, only include certain files
  if(length(onlyFiles) > 0){
    allFiles <- allFiles[allFiles %in% onlyFiles]
  }
  
  for(file in allFiles){
    # load file
    rawFile <- file
    
    # Run a super long function
    processedFile <- rawFile
    
    # Save file
    # write.csv(processedFile, paste('./Other/Path/', file, sep = ''), row.names = FALSE)
  
    cat('nDone with file ', file, sep = '')
  }  
}
 

Он должен выполнить около 30 файлов, и каждый из них занимает около 3 минут. Может потребоваться очень много времени, чтобы выполнить цикл целиком. Что я хотел бы сделать, так это запустить каждый из них отдельно в одно и то же время, чтобы все вместе заняло 3 минуты вместо 3 х 30 = 90 минут.

Я знаю, что могу добиться этого, создав кучу сеансов RStudio или множество вкладок терминала, но я не могу справиться с одновременным открытием такого количества сеансов или вкладок.

В идеале я хотел бы, чтобы все файлы с отдельными функциями были перечислены в одном batchRun.R файле, который я могу запускать с терминала:

 source('./PathToFunction/load_process_saveFiles.R')

load_process_saveFiles(onlyFiles = 'A.csv')
load_process_saveFiles(onlyFiles = 'B.csv')
load_process_saveFiles(onlyFiles = 'C.csv')
load_process_saveFiles(onlyFiles = 'D.csv')
load_process_saveFiles(onlyFiles = 'E.csv')
load_process_saveFiles(onlyFiles = 'F.csv')
 

Итак, затем запустите $ RScript batchRun.R из терминала.

Я пытался искать разные примеры на SO, пытаясь выполнить что-то подобное, но у каждого есть некоторые уникальные функции, и я просто не могу заставить его работать. Возможно ли то, что я пытаюсь сделать? Спасибо!

Комментарии:

1. Если вы работаете в Linux, вы можете сделать это в сценарии оболочки вместо R-скрипта с символом амперсанда фоновой задачи amp; между вашими R CMD BATCH . . . командами (или в цикле).

2. Вы также можете получить оболочку Bash в Windows: смотрите Здесь . И в случае, если вы сочтете это полезным, вот раздел руководства по Bash, в котором описывается amp; оператор.

Ответ №1:

Пакет parallel предоставляет вам несколько опций. Одним из вариантов является распараллеливание вызовов load_process_saveFiles и последовательное выполнение цикла внутри функции. Другой вариант — распараллелить цикл и выполнить вызовы последовательно. Лучший способ оценить, какой подход больше подходит для вашей работы, — это самостоятельно рассчитать их оба.

Вычисление вызовов load_process_saveFiles параллельно относительно просто с mclapply помощью параллельной версии базовой функции lapply (см. ?lapply ):

 parallel::mclapply(x, load_process_saveFiles, mc.cores = 2L)
 

Здесь x приведен список значений аргумента onlyFiles и mc.cores = 2L указывает, что вы хотите разделить вызовы между двумя процессами R.

Оценка цикла внутри load_process_saveFiles параллельно потребовала бы замены всего for оператора чем-то вроде

 f <- function(file) {
  cat("Processing file", file, "...")
  x <- read(file)
  y <- process(x)
  write(y, file = file.path("path", "to", file))
  cat(" done!n")
}
parallel::mclapply(allFiles, f, ...)
 

и переопределение load_process_saveFiles , чтобы разрешить необязательные аргументы:

 load_process_saveFiles <- function(onlyFiles = character(0L), ...) {
  ## body
}
 

Тогда вы могли бы сделать, например, load_process_saveFiles(onlyFiles, mc.cores = 2L) .

Я должен отметить, что mclapply это не поддерживается в Windows. В Windows вы можете использовать parLapply вместо этого, но для этого потребуется несколько дополнительных шагов. Они описаны в parallel виньетке, которую можно открыть из R с vignette("parallel", "parallel") помощью . Виньетка действует как общее введение в параллелизм в R, поэтому ее все равно стоит прочитать.

Ответ №2:

В этом случае полезен параллельный пакет. И если вы используете ОС Linux, я бы рекомендовал пакет doMC вместо parallel. Этот пакет doMC полезен даже для перебора больших данных, используемых в проектах машинного обучения.