Открытие нового экземпляра R и поиск сценария в этом экземпляре
Предпосылки / мотивация: я использую конвейер биоинформатики, который, если он выполняется от начала до конца линейно, занимает несколько дней до конца. К счастью, некоторые задачи не зависят друг от друга, поэтому их можно выполнять индивидуально. Например, задачи 2, 3 и 4 зависят от выходных данных задачи 1, но не нуждаются в информации друг от друга. Задача 5 использует выходные данные 2, 3 и 4 в качестве входных данных.
Я пытаюсь написать скрипт, который будет открывать новые экземпляры R для каждой из трех задач и запускать их одновременно. Когда все три будут выполнены, я могу продолжить работу с оставшимся конвейером.
То, что я делал в прошлом для более линейных рабочих процессов, - это наличие одного "основного" сценария, который по очереди (source()) выполняет нижний индекс каждой задачи.
Я искал SO и Google и не смог найти решение для этой конкретной проблемы. Надеюсь, вы, ребята, можете помочь.
Изнутри R вы можете запустить system() для вызова команд в терминале и открыть, чтобы открыть файл. Например, следующее откроет новый экземпляр терминала:
system("open -a Terminal .",wait=FALSE)
Точно так же я могу начать новый сеанс с помощью
system("open -a r .")
Что я не могу понять для себя, так это как установить аргумент "input" так, чтобы он исходил из одного из моих сценариев. Например, я ожидал бы, что следующее откроет новый экземпляр терминала, вызовет r в новом экземпляре, а затем сгенерирует скрипт.
system("open -a Terminal .",wait=FALSE,input=paste0("r; source(\"/path/to/script/M_01-A.R\",verbose=TRUE,max.deparse.length=Inf)"))
2 ответа
Отвечая на мой собственный вопрос в случае, если кто-то еще заинтересован в будущем.
После нескольких дней работы над этим, я думаю, что лучший способ выполнить этот рабочий процесс - не ограничивать себя работой только на R. Написание сценария bash предлагает большую гибкость и, вероятно, является более прямым решением. Следующий пример был предложен мне на другом сайте.
#!/bin/bash
# Run task 1
Rscript Task1.R
# now run the three jobs that use Task1's output
# we can fork these using '&' to run in the background in parallel
Rscript Task2.R &
Rscript Task3.R &
Rscript Task4.R &
# wait until background processes have finished
wait %1 %2 %3
Rscript Task5.R
Возможно, вас заинтересует будущий пакет (я автор). Это позволяет вам написать свой код как:
library("future")
v1 %<-% task1(args_1)
v2 %<-% task2(v1, args_2)
v3 %<-% task3(v1, args_3)
v4 %<-% task4(v1, args_4)
v5 %<-% task5(v2, v3, v4, args_5)
Каждый из тех v %<-% expr
заявления создает будущее на основе выражения R expr
(и все его зависимости) и присваивает его обещанию v
, Это только когда v
используется, он будет блокировать и ждать значения v
быть доступным.
Как и где разрешаются эти фьючерсы, определяется пользователем приведенного выше кода. Например, указав:
library("future")
plan(multiprocess)
вверху, тогда фьючерсы (= различные задачи) решаются параллельно на вашем локальном компьютере. Если вы используете,
plan(cluster, workers = c("n1", "n3", "n3", "n5"))
они разрешены на тех для машины (где n3
принимает две одновременные работы).
Это работает во всех операционных системах (включая Windows).
Если у вас есть доступ к вычислениям HPC с помощью таких планировщиков, как Slurm, SGE и TORQUE / PBS, вы можете использовать пакет future.BatchJobs, например:
plan(future.BatchJobs::batchjobs_torque)
PS. Одной из причин создания будущего было создание крупномасштабной биоинформатики параллельно / распределенно.