如何从R脚本读取命令行参数?

时间:2022-07-25 00:15:08

I've got a R script for which I'd like to be able to supply several command-line parameters (rather than hardcode parameter values in the code itself). The script runs on Windows.

我有一个R脚本,我希望能够提供几个命令行参数(而不是代码本身的硬编码参数值)。脚本在Windows上运行。

I can't find info on how to read parameters supplied on the command-line into my R script. I'd be surprised if it can't be done, so maybe I'm just not using the best keywords in my Google search...

在我的R脚本中,我无法找到如何读取命令行上提供的参数的信息。如果不能这样做,我很惊讶,也许我只是没有在谷歌搜索中使用最好的关键词……

Any pointers or recommendations?

指针或建议吗?

10 个解决方案

#1


193  

Dirk's answer here is everything you need. Here's a minimal reproducible example.

德克的回答是你需要的一切。这里有一个最小的可复制的例子。

I made two files: exmpl.bat and exmpl.R.

我做了两个文件:exmpl。蝙蝠和exmpl.R。

  • exmpl.bat:

    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
    

    Alternatively, using Rterm.exe:

    另外,使用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:

    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)
    

Save both files in the same directory and start exmpl.bat. In the result you'll get:

将两个文件保存在同一个目录中并启动exmpl.bat。结果你会得到:

  • example.png with some plot
  • 的例子。png和一些情节
  • exmpl.batch with all that was done
  • exmpl。完成了所有的工作。

You could also add an environment variable %R_Script%:

您还可以添加一个环境变量%R_Script%:

"C:\Program Files\R-3.0.2\bin\RScript.exe"

and use it in your batch scripts as %R_Script% <filename.r> <arguments>

在批处理脚本中使用它作为%R_Script% <参数> 。r>

Differences between RScript and Rterm:

RScript与Rterm的区别:

  • Rscript has simpler syntax
  • Rscript有简单的语法
  • Rscript automatically chooses architecture on x64 (see R Installation and Administration, 2.6 Sub-architectures for details)
  • Rscript自动选择x64上的架构(详见R安装和管理,2.6个子架构)
  • Rscript needs options(echo=TRUE) in the .R file if you want to write the commands to the output file
  • 如果您想要将命令写入输出文件,那么在.R文件中需要选项(echo=TRUE)。

#2


115  

A few points:

几个点:

  1. Command-line parameters are accessible via commandArgs(), so see help(commandArgs) for an overview.

    命令行参数可以通过commandArgs()访问,所以请参阅帮助(commandArgs)作为概述。

  2. You can use Rscript.exe on all platforms, including Windows. It will support commandArgs(). littler could be ported to Windows but lives right now only on OS X and Linux.

    您可以使用Rscript。exe在所有平台上,包括Windows。它将支持commandArgs()。littler可以移植到Windows上,但是现在只能在OS X和Linux上使用。

  3. There are two add-on packages on CRAN -- getopt and optparse -- which were both written for command-line parsing.

    在CRAN - getopt和optparse中有两个附加包,它们都是为命令行解析而编写的。

Edit in Nov 2015: New alternatives have appeared and I wholeheartedly recommend doctopt.

2015年11月编辑:出现了新的替代方案,我全力推荐doctopt。

#3


80  

Add this to the top of your script:

把这个添加到脚本的顶部:

args<-commandArgs(TRUE)

Then you can refer to the arguments passed as args[1], args[2] etc.

然后可以引用作为args[1]、args[2]等传递的参数。

Then run

然后运行

Rscript myscript.R arg1 arg2 arg3

If your args are strings with spaces in them, enclose within double quotes.

如果您的args是带有空格的字符串,请使用双引号括起来。

#4


12  

Try library(getopt) ... if you want things to be nicer. For example:

试着库(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();
}

#5


8  

you need littler (pronounced 'little r')

你需要littler(发音为“littler”)

Dirk will be by in about 15 minutes to elaborate ;)

德克将在15分钟内精心制作;

#6


6  

Since optparse has been mentioned a couple of times in the answers, and it provides a comprehensive kit for command line processing, here's a short simplified example of how you can use it, assuming the input file exists:

由于optparse在答案中已经提到了几次,并且它提供了一个用于命令行处理的综合工具包,这里有一个简短的示例,说明如何使用它,假设输入文件存在:

script.R:

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))
}

Given an arbitrary file blah.txt with 23 lines.

给定一个任意的文件。txt和23行。

On the command line:

在命令行:

Rscript script.R -h outputs

Rscript脚本。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 outputs [1] "69"

Rscript脚本。R - n。三种输出[1]“69”

Rscript script.R -n -f 5 blah.txt outputs [1] "115"

Rscript脚本。R -n -f 5。三种输出[1]“115”

#7


4  

In bash, you can construct a command line like the following:

在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
$

You can see that the variable $z is substituted by bash shell with "10" and this value is picked up by commandArgs and fed into args[2], and the range command x=1:10 executed by R successfully, etc etc.

您可以看到,变量$z被bash shell替换为“10”,这个值由commandArgs接收并输入到args[2]中,而range命令x=1:10被R成功执行,等等。

#8


3  

FYI: there is a function args(), which retrieves the arguments of R functions, not to be confused with a vector of arguments named args

FYI:有一个函数args(),它检索R函数的参数,而不是与名为args的参数向量混淆。

#9


0  

If you need to specify options with flags, (like -h, --help, --number=42, etc) you can use the R package optparse (inspired from Python): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf.

如果您需要指定带有标志的选项,(比如-h, -help, -number=42,等等),您可以使用R包optparse(从Python中得到的):http://cran.r project.org/web/packages/optparse/vignettes/optparse.pdf。

At least this how I understand your question, because I found this post when looking for an equivalent of the bash getopt, or perl Getopt, or python argparse and optparse.

至少这是我理解您的问题的方式,因为我在查找与bash getopt、perl getopt或python argparse和optparse等价的时候找到了这个帖子。

#10


0  

I just put together a nice data structure and chain of processing to generate this switching behaviour, no libraries needed. I'm sure it will have been implemented numerous times over, and came across this thread looking for examples - thought I'd chip in.

我只是建立了一个良好的数据结构和处理链来生成这种切换行为,不需要任何库。我确信它将会被无数次地实现,并跨越这条线寻找一些例子——我认为我将会参与其中。

I didn't even particularly need flags (the only flag here is a debug mode, creating a variable which I check for as a condition of starting a downstream function if (!exists(debug.mode)) {...} else {print(variables)}). The flag checking lapply statements below produce the same as:

我甚至没有特别需要标记(这里唯一的标志是调试模式,创建一个变量,我检查它作为启动下游函数的条件)(如果存在(debug.mode)){…} {打印(变量)})。下面的标志检查lapply语句生成如下:

if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args) 

where args is the variable read in from command line arguments (a character vector, equivalent to c('--debug','--help') when you supply these on for instance)

args是由命令行参数读入的变量(一个字符向量,相当于c('- debug','- help')当您提供这些参数时)

It's reusable for any other flag and you avoid all the repetition, and no libraries so no dependencies:

它可用于任何其他标志,避免了所有的重复,没有库,所以没有依赖性:

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))

Note that in flag.details here the commands are stored as strings, then evaluated with eval(parse(text = '...')). Optparse is obviously desirable for any serious script, but minimal-functionality code is good too sometimes.

注意,在flag.details中,命令存储为字符串,然后使用eval(parse(text = '…))进行评估。对于任何严肃的脚本来说,Optparse显然是可取的,但是很少的功能代码有时也是好的。

Sample output:

样例输出:

$ Rscript check_mail.Rscript --help
--debug Print  variables rather than executing function XYZ...

-h  --help  Display flag definitions

#1


193  

Dirk's answer here is everything you need. Here's a minimal reproducible example.

德克的回答是你需要的一切。这里有一个最小的可复制的例子。

I made two files: exmpl.bat and exmpl.R.

我做了两个文件:exmpl。蝙蝠和exmpl.R。

  • exmpl.bat:

    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
    

    Alternatively, using Rterm.exe:

    另外,使用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:

    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)
    

Save both files in the same directory and start exmpl.bat. In the result you'll get:

将两个文件保存在同一个目录中并启动exmpl.bat。结果你会得到:

  • example.png with some plot
  • 的例子。png和一些情节
  • exmpl.batch with all that was done
  • exmpl。完成了所有的工作。

You could also add an environment variable %R_Script%:

您还可以添加一个环境变量%R_Script%:

"C:\Program Files\R-3.0.2\bin\RScript.exe"

and use it in your batch scripts as %R_Script% <filename.r> <arguments>

在批处理脚本中使用它作为%R_Script% <参数> 。r>

Differences between RScript and Rterm:

RScript与Rterm的区别:

  • Rscript has simpler syntax
  • Rscript有简单的语法
  • Rscript automatically chooses architecture on x64 (see R Installation and Administration, 2.6 Sub-architectures for details)
  • Rscript自动选择x64上的架构(详见R安装和管理,2.6个子架构)
  • Rscript needs options(echo=TRUE) in the .R file if you want to write the commands to the output file
  • 如果您想要将命令写入输出文件,那么在.R文件中需要选项(echo=TRUE)。

#2


115  

A few points:

几个点:

  1. Command-line parameters are accessible via commandArgs(), so see help(commandArgs) for an overview.

    命令行参数可以通过commandArgs()访问,所以请参阅帮助(commandArgs)作为概述。

  2. You can use Rscript.exe on all platforms, including Windows. It will support commandArgs(). littler could be ported to Windows but lives right now only on OS X and Linux.

    您可以使用Rscript。exe在所有平台上,包括Windows。它将支持commandArgs()。littler可以移植到Windows上,但是现在只能在OS X和Linux上使用。

  3. There are two add-on packages on CRAN -- getopt and optparse -- which were both written for command-line parsing.

    在CRAN - getopt和optparse中有两个附加包,它们都是为命令行解析而编写的。

Edit in Nov 2015: New alternatives have appeared and I wholeheartedly recommend doctopt.

2015年11月编辑:出现了新的替代方案,我全力推荐doctopt。

#3


80  

Add this to the top of your script:

把这个添加到脚本的顶部:

args<-commandArgs(TRUE)

Then you can refer to the arguments passed as args[1], args[2] etc.

然后可以引用作为args[1]、args[2]等传递的参数。

Then run

然后运行

Rscript myscript.R arg1 arg2 arg3

If your args are strings with spaces in them, enclose within double quotes.

如果您的args是带有空格的字符串,请使用双引号括起来。

#4


12  

Try library(getopt) ... if you want things to be nicer. For example:

试着库(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();
}

#5


8  

you need littler (pronounced 'little r')

你需要littler(发音为“littler”)

Dirk will be by in about 15 minutes to elaborate ;)

德克将在15分钟内精心制作;

#6


6  

Since optparse has been mentioned a couple of times in the answers, and it provides a comprehensive kit for command line processing, here's a short simplified example of how you can use it, assuming the input file exists:

由于optparse在答案中已经提到了几次,并且它提供了一个用于命令行处理的综合工具包,这里有一个简短的示例,说明如何使用它,假设输入文件存在:

script.R:

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))
}

Given an arbitrary file blah.txt with 23 lines.

给定一个任意的文件。txt和23行。

On the command line:

在命令行:

Rscript script.R -h outputs

Rscript脚本。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 outputs [1] "69"

Rscript脚本。R - n。三种输出[1]“69”

Rscript script.R -n -f 5 blah.txt outputs [1] "115"

Rscript脚本。R -n -f 5。三种输出[1]“115”

#7


4  

In bash, you can construct a command line like the following:

在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
$

You can see that the variable $z is substituted by bash shell with "10" and this value is picked up by commandArgs and fed into args[2], and the range command x=1:10 executed by R successfully, etc etc.

您可以看到,变量$z被bash shell替换为“10”,这个值由commandArgs接收并输入到args[2]中,而range命令x=1:10被R成功执行,等等。

#8


3  

FYI: there is a function args(), which retrieves the arguments of R functions, not to be confused with a vector of arguments named args

FYI:有一个函数args(),它检索R函数的参数,而不是与名为args的参数向量混淆。

#9


0  

If you need to specify options with flags, (like -h, --help, --number=42, etc) you can use the R package optparse (inspired from Python): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf.

如果您需要指定带有标志的选项,(比如-h, -help, -number=42,等等),您可以使用R包optparse(从Python中得到的):http://cran.r project.org/web/packages/optparse/vignettes/optparse.pdf。

At least this how I understand your question, because I found this post when looking for an equivalent of the bash getopt, or perl Getopt, or python argparse and optparse.

至少这是我理解您的问题的方式,因为我在查找与bash getopt、perl getopt或python argparse和optparse等价的时候找到了这个帖子。

#10


0  

I just put together a nice data structure and chain of processing to generate this switching behaviour, no libraries needed. I'm sure it will have been implemented numerous times over, and came across this thread looking for examples - thought I'd chip in.

我只是建立了一个良好的数据结构和处理链来生成这种切换行为,不需要任何库。我确信它将会被无数次地实现,并跨越这条线寻找一些例子——我认为我将会参与其中。

I didn't even particularly need flags (the only flag here is a debug mode, creating a variable which I check for as a condition of starting a downstream function if (!exists(debug.mode)) {...} else {print(variables)}). The flag checking lapply statements below produce the same as:

我甚至没有特别需要标记(这里唯一的标志是调试模式,创建一个变量,我检查它作为启动下游函数的条件)(如果存在(debug.mode)){…} {打印(变量)})。下面的标志检查lapply语句生成如下:

if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args) 

where args is the variable read in from command line arguments (a character vector, equivalent to c('--debug','--help') when you supply these on for instance)

args是由命令行参数读入的变量(一个字符向量,相当于c('- debug','- help')当您提供这些参数时)

It's reusable for any other flag and you avoid all the repetition, and no libraries so no dependencies:

它可用于任何其他标志,避免了所有的重复,没有库,所以没有依赖性:

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))

Note that in flag.details here the commands are stored as strings, then evaluated with eval(parse(text = '...')). Optparse is obviously desirable for any serious script, but minimal-functionality code is good too sometimes.

注意,在flag.details中,命令存储为字符串,然后使用eval(parse(text = '…))进行评估。对于任何严肃的脚本来说,Optparse显然是可取的,但是很少的功能代码有时也是好的。

Sample output:

样例输出:

$ Rscript check_mail.Rscript --help
--debug Print  variables rather than executing function XYZ...

-h  --help  Display flag definitions