Допустим, у меня есть рабочий процесс Nextflow:
#!/usr/bin/env nextflow
nextflow.enable.dsl=2
process f_to_c {
input:
val f
output:
stdout
script:
"""
gettemp.R $f
"""
}
workflow {
Channel.of(80,60) | f_to_c | view
}
gettemp.R
код в каталоге bin
:
#!/usr/bin/env Rscript
source("lib/farenheit_to_celcius.R")
args <- commandArgs(trailingOnly=TRUE)
cat(fahrenheit_to_celsius(args[[1]]))
С lib/farenheit_to_celcius.R
содержит:
fahrenheit_to_celsius <- function(farenheit) {
return((as.numeric(farenheit) - 32) * 5 / 9)
}
При выполнении рабочего процесса я получаю:
cannot open file 'lib/farenheit_to_celcius.R': No such file or directory
Я понимаю, почему, поскольку Nextflow выполняет gettemp.R
в каждом рабочем каталоге. Но как тогда я могу вызвать функцию в другом R-скрипте? Похоже, что source
не лучший вариант, поэтому лучшим вариантом может быть создание моей собственной библиотеки с функциями. Однако будет ли возможно, чтобы Nextflow автоматически устанавливал/обновлял пользовательскую библиотеку во время выполнения?
Есть несколько проблем, которые делают это нетривиальным, но одна из них заключается в том, что R разрешает все пути к файлам относительно текущего рабочего каталога. Обычно это то, что вам нужно; за исключением зависимостей исходного файла.
source
принципиально не поддерживает разрешение пути к другому исходному файлу относительно исполняемого в данный момент файла, и ядро R не имеет хорошего способа обойти это ограничение.
Однако, если вместо этого вы используете «коробочные» модули, это работает.
В вашем конкретном случае вы бы изменили строку
source("lib/farenheit_to_celcius.R")
к
box::use(lib/farenheit_to_celsius[...])
(box::use
используется для объявления импорта; его аргументы, разделенные запятыми, являются спецификациями пакета или модуля, а [...]
означает «прикрепить все экспортированные имена модуля», что приблизительно соответствует тому, что делает source
.)
И чтобы превратить lib/farenheit_to_celcius.R
в модуль, вы должны добавить объявление экспорта над своей функцией:
#' @export
fahrenheit_to_celsius <- function(farenheit) {
return((as.numeric(farenheit) - 32) * 5 / 9)
}