Открытие нового экземпляра 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. Одной из причин создания будущего было создание крупномасштабной биоинформатики параллельно / распределенно.

Другие вопросы по тегам