Как я могу прочитать параметры командной строки из сценария R?
У меня есть R-скрипт, для которого я хотел бы иметь возможность предоставлять несколько параметров командной строки (а не значения параметров жесткого кода в самом коде). Скрипт работает на Windows.
Я не могу найти информацию о том, как читать параметры, указанные в командной строке, в мой R-скрипт. Я был бы удивлен, если это не может быть сделано, поэтому, возможно, я просто не использую лучшие ключевые слова в моем поиске Google...
Любые указатели или рекомендации?
10 ответов
Ответ Дирка здесь - все, что вам нужно. Вот минимальный воспроизводимый пример.
Я сделал два файла: exmpl.bat
а также exmpl.R
,
exmpl.bat
:set R_Script="C:\Program Files\R-3.0.2\bin\RScript.exe" %R_Script% exmpl.R 2010-01-28 example 100 > exmpl.batch 2>&1
В качестве альтернативы, используя
Rterm.exe
:set R_TERM="C:\Program Files\R-3.0.2\bin\i386\Rterm.exe" %R_TERM% --no-restore --no-save --args 2010-01-28 example 100 < exmpl.R > exmpl.batch 2>&1
exmpl.R
:options(echo=TRUE) # if you want see commands in output file args <- commandArgs(trailingOnly = TRUE) print(args) # trailingOnly=TRUE means that only your arguments are returned, check: # print(commandArgs(trailingOnly=FALSE)) start_date <- as.Date(args[1]) name <- args[2] n <- as.integer(args[3]) rm(args) # Some computations: x <- rnorm(n) png(paste(name,".png",sep="")) plot(start_date+(1L:n), x) dev.off() summary(x)
Сохраните оба файла в одном каталоге и запустите exmpl.bat
, В результате вы получите:
example.png
с некоторым сюжетомexmpl.batch
со всем, что было сделано
Вы также можете добавить переменную среды %R_Script%
:
"C:\Program Files\R-3.0.2\bin\RScript.exe"
и использовать его в своих пакетных сценариях как %R_Script% <filename.r> <arguments>
Различия между RScript
а также Rterm
:
Rscript
имеет более простой синтаксисRscript
автоматически выбирает архитектуру на x64 (подробнее см. Установка и администрирование R, 2.6 Суб-архитектуры)Rscript
потребностиoptions(echo=TRUE)
в файле.R, если вы хотите записать команды в выходной файл
Несколько моментов:
Параметры командной строки доступны через
commandArgs()
так что смотритеhelp(commandArgs)
для обзора.Ты можешь использовать
Rscript.exe
на всех платформах, включая Windows. Будет поддерживатьcommandArgs()
, littler может быть портирован на Windows, но сейчас живет только на OS X и Linux.В CRAN есть два пакета дополнений - getopt и optparse, которые были написаны для анализа командной строки.
Редактирование в ноябре 2015 года: появились новые альтернативы, и я искренне рекомендую docopt.
Добавьте это в начало вашего скрипта:
args<-commandArgs(TRUE)
Затем вы можете ссылаться на аргументы, переданные как args[1]
, args[2]
и т.п.
Тогда беги
Rscript myscript.R arg1 arg2 arg3
Если ваши аргументы являются строками с пробелами, заключите их в двойные кавычки.
Поскольку optparse
был упомянут пару раз в ответах, и он предоставляет всеобъемлющий набор для обработки командной строки, вот краткий упрощенный пример того, как вы можете его использовать, предполагая, что входной файл существует:
script.R:
library(optparse)
option_list <- list(
make_option(c("-n", "--count_lines"), action="store_true", default=FALSE,
help="Count the line numbers [default]"),
make_option(c("-f", "--factor"), type="integer", default=3,
help="Multiply output by this number [default %default]")
)
parser <- OptionParser(usage="%prog [options] file", option_list=option_list)
args <- parse_args(parser, positional_arguments = 1)
opt <- args$options
file <- args$args
if(opt$count_lines) {
print(paste(length(readLines(file)) * opt$factor))
}
Учитывая произвольный файл blah.txt
с 23 строками.
В командной строке:
Rscript script.R -h
выходы
Usage: script.R [options] file
Options:
-n, --count_lines
Count the line numbers [default]
-f FACTOR, --factor=FACTOR
Multiply output by this number [default 3]
-h, --help
Show this help message and exit
Rscript script.R -n blah.txt
выходы [1] "69"
Rscript script.R -n -f 5 blah.txt
выходы [1] "115"
Попробуйте библиотеку (getopt) ... если вы хотите, чтобы все было лучше. Например:
spec <- matrix(c(
'in' , 'i', 1, "character", "file from fastq-stats -x (required)",
'gc' , 'g', 1, "character", "input gc content file (optional)",
'out' , 'o', 1, "character", "output filename (optional)",
'help' , 'h', 0, "logical", "this help"
),ncol=5,byrow=T)
opt = getopt(spec);
if (!is.null(opt$help) || is.null(opt$in)) {
cat(paste(getopt(spec, usage=T),"\n"));
q();
}
Вам нужно немного (произносится "маленький г")
Дирк будет около 15 минут, чтобы уточнить;)
В bash вы можете создать командную строку следующим образом:
$ z=10
$ echo $z
10
$ Rscript -e "args<-commandArgs(TRUE);x=args[1]:args[2];x;mean(x);sd(x)" 1 $z
[1] 1 2 3 4 5 6 7 8 9 10
[1] 5.5
[1] 3.027650
$
Вы можете видеть, что переменная $z
заменяется оболочкой bash на "10", и это значение выбирается commandArgs
и подается в args[2]
и команда диапазона x=1:10
успешно выполнено R и т. д.
К вашему сведению: есть функция args(), которая извлекает аргументы функций R, не путать с вектором аргументов с именем args
Если вам нужно указать опции с флагами (например, -h, --help, --number=42 и т. Д.), Вы можете использовать пакет optparse (вдохновленный Python): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf.
По крайней мере, так я понимаю ваш вопрос, потому что я нашел этот пост, когда искал эквивалент bash getopt, или perl Getopt, или python argparse и optparse.
Я просто собрал красивую структуру данных и цепочку обработки для генерации такого поведения переключения, библиотеки не нужны. Я уверен, что это будет реализовано много раз, и наткнулся на эту тему в поисках примеров - думал, что я скинуся.
Мне даже не нужны были флаги (единственный флаг здесь - режим отладки, создающий переменную, которую я проверяю как условие запуска функции ниже по течению) if (!exists(debug.mode)) {...} else {print(variables)})
, Проверка флага lapply
утверждения ниже производят так же как:
if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args)
где args
переменная, считанная из аргументов командной строки (символьный вектор, эквивалентный c('--debug','--help')
когда вы поставите их, например)
Он может быть использован для любого другого флага, и вы избегаете всех повторений, и никаких библиотек, поэтому нет никаких зависимостей:
args <- commandArgs(TRUE)
flag.details <- list(
"debug" = list(
def = "Print variables rather than executing function XYZ...",
flag = "--debug",
output = "debug.mode <- T"),
"help" = list(
def = "Display flag definitions",
flag = c("-h","--help"),
output = "cat(help.prompt)") )
flag.conditions <- lapply(flag.details, function(x) {
paste0(paste0('"',x$flag,'"'), sep = " %in% args", collapse = " || ")
})
flag.truth.table <- unlist(lapply(flag.conditions, function(x) {
if (eval(parse(text = x))) {
return(T)
} else return(F)
}))
help.prompts <- lapply(names(flag.truth.table), function(x){
# joins 2-space-separatated flags with a tab-space to the flag description
paste0(c(paste0(flag.details[x][[1]][['flag']], collapse=" "),
flag.details[x][[1]][['def']]), collapse="\t")
} )
help.prompt <- paste(c(unlist(help.prompts),''),collapse="\n\n")
# The following lines handle the flags, running the corresponding 'output' entry in flag.details for any supplied
flag.output <- unlist(lapply(names(flag.truth.table), function(x){
if (flag.truth.table[x]) return(flag.details[x][[1]][['output']])
}))
eval(parse(text = flag.output))
Обратите внимание, что в flag.details
здесь команды хранятся в виде строк, а затем оцениваются с eval(parse(text = '...'))
, Optparse явно желателен для любого серьезного скрипта, но код с минимальной функциональностью тоже иногда хорош.
Образец вывода:
$ Rscript check_mail.Rscript --help --debug Печатать переменные, а не выполнять функцию XYZ... -h --help Показать определения флага