Как я могу прочитать параметры командной строки из сценария R? - PullRequest
272 голосов
/ 28 января 2010

У меня есть R-скрипт, для которого я хотел бы иметь возможность предоставить несколько параметров командной строки (а не значения параметров жесткого кода в самом коде). Скрипт работает на Windows.

Я не могу найти информацию о том, как считывать параметры, указанные в командной строке, в мой R-скрипт. Я был бы удивлен, если это не может быть сделано, поэтому, возможно, я просто не использую лучшие ключевые слова в моем поиске Google ...

Есть указатели или рекомендации?

Ответы [ 10 ]

205 голосов
/ 28 января 2010

Ответ Дирка здесь - это все, что вам нужно. Вот минимальный воспроизводимый пример.

Я сделал два файла: 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:

123 голосов
/ 28 января 2010

Несколько баллов:

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

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

  3. В CRAN существует два пакета дополнений - getopt и optparse - оба написаны для анализа командной строки.

Редактировать в ноябре 2015 года: Появились новые альтернативы, и я искренне рекомендую docopt .

89 голосов
/ 28 января 2010

Добавьте это в начало вашего скрипта:

args<-commandArgs(TRUE)

Затем вы можете ссылаться на аргументы, передаваемые как args[1], args[2] и т. Д.

Затем запустите

Rscript myscript.R arg1 arg2 arg3

Если ваши аргументы являются строками с пробелами в них, заключите их в двойные кавычки.

15 голосов
/ 27 декабря 2012

Попробуйте библиотеку (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();
}
11 голосов
/ 15 октября 2015

Поскольку в ответах пару раз упоминалось 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"

10 голосов
/ 28 января 2010

вам нужно littler (произносится как 'маленький г')

Дирк будет примерно через 15 минут, чтобы уточнить;)

6 голосов
/ 09 января 2011

В 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 и т. д.

4 голосов
/ 09 ноября 2011

К вашему сведению: есть функция args (), которая извлекает аргументы функций R, не путать с вектором аргументов с именем args

0 голосов
/ 13 февраля 2015

Я просто собрал красивую структуру данных и цепочку обработки для генерации такого поведения переключения, библиотеки не нужны. Я уверен, что это будет реализовано много раз, и наткнулся на эту ветку в поисках примеров - думал, что я скину.

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

Пример вывода:

<strong>$</strong> Rscript <a href="https://github.com/lmmx/ScholarDaemon/blob/master/check_mail.Rscript" rel="nofollow">check_mail.Rscript</a> --help
--debug Print  variables rather than executing function XYZ...

-h  --help  Display flag definitions
0 голосов
/ 20 мая 2014

Если вам нужно указать опции с флагами (например, -h, --help, --number = 42 и т. Д.), Вы можете использовать пакет optparse R (вдохновленный Python): http://cran.r -project.org / веб / пакеты / optparse / виньетки / optparse.pdf .

По крайней мере, так я понимаю ваш вопрос, потому что я нашел этот пост, когда искал эквивалент bash getopt, или perl Getopt, или python argparse и optparse.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...