Как я могу прочитать параметры командной строки из сценария R?

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

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

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


person monch1962    schedule 27.01.2010    source источник
comment
вам нужно указать местоположение исполняемого файла rscript   -  person    schedule 02.08.2017


Ответы (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:

person Marek    schedule 28.01.2010

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

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

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

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

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

person Dirk Eddelbuettel    schedule 28.01.2010
comment
и есть argparse - person gkcn; 13.08.2013

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

args<-commandArgs(TRUE)

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

Тогда беги

Rscript myscript.R arg1 arg2 arg3

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

person Hrishi Mittal    schedule 28.01.2010
comment
Это сработало только тогда, когда я использовал args ‹-commandArgs (TRUE) (обратите внимание на верхний регистр A). - person Andy West; 27.04.2012
comment
вам нужно --args перед arg1? - person philcolbourn; 24.05.2017
comment
@philcolbourn Нет - person Chris_Rands; 19.02.2018

Попробуйте библиотеку (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();
}
person Erik Aronesty    schedule 27.12.2012

Поскольку 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"

person Megatron    schedule 15.10.2015

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

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

person JD Long    schedule 28.01.2010

В 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, и т. Д. И т. Д.

person TTW    schedule 09.01.2011

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

person Tim    schedule 09.11.2011
comment
Это почти наверняка не так. Только функции могут маскировать функции. Создание переменной с тем же именем, что и функция, не маскирует функцию. Обратитесь к этому вопросу и ответам: stackoverflow.com/q/6135868/602276 - person Andrie; 09.11.2011
comment
Правда, не маскирует. В общем, я стараюсь избегать именования функций и переменных с именами, которые уже существуют в R. - person Tim; 10.11.2011

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

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

person TheBinturonGggh    schedule 20.05.2014

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

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

-h  --help  Display flag definitions
person Louis Maddox    schedule 13.02.2015