Как я могу прочитать параметры командной строки из сценария 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:

Несколько моментов:

  1. Параметры командной строки доступны через commandArgs()так что смотрите help(commandArgs) для обзора.

  2. Ты можешь использовать Rscript.exe на всех платформах, включая Windows. Будет поддерживать commandArgs(), littler может быть портирован на Windows, но сейчас живет только на OS X и Linux.

  3. В 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 Показать определения флага
Другие вопросы по тегам