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


281

我有一个R脚本,我想为其提供几个命令行参数(而不是代码本身中的硬编码参数值)。该脚本在Windows上运行。

我找不到有关如何将命令行中提供的参数读入R脚本的信息。如果无法完成,我会感到惊讶,所以也许我只是没有在Google搜索中使用最佳关键字...

有任何指示或建议吗?


您需要设置rscript可执行文件的位置

Answers:


209

德克的答案就是您需要的一切。这是一个最小的可复制示例。

我制作了两个文件:exmpl.batexmpl.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


127

几点:

  1. 命令行参数可通过访问commandArgs(),因此请参见help(commandArgs)参考资料。

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

  3. 有两个附加的CRAN包- getopt的optparse -这是既为命令行解析写入。

编辑于2015年11月: 出现了新的替代方法,我全力推荐docopt


2
还有argparse
gkcn

92

将其添加到脚本顶部:

args<-commandArgs(TRUE)

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

然后跑

Rscript myscript.R arg1 arg2 arg3

如果您的args是其中包含空格的字符串,请用双引号引起来。


7
这仅在我使用args <-commandArgs(TRUE)时有效(请注意大写的A)。
安迪·韦斯特

在arg1之前需要--args吗?
philcolbourn

@philcolbourn No
Chris_Rands

15

如果您希望事情变得更好,请尝试library(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

既然optparse在答案中已经提到过两次,并且它提供了用于命令行处理的综合工具包,下面是一个简短的示例,说明了如何使用它(假设输入文件存在):

脚本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.txt23行的任意文件。

在命令行上:

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"


7

在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 shell替换为“ 10”,并且该值被拾取commandArgs并馈入args[2],并且x=1:10R成功执行了range命令,等等。


4

仅供参考:有一个函数args(),它检索R函数的参数,不要与名为args的参数向量混淆


1
几乎可以肯定不是这种情况。只有功能可以屏蔽功能。创建与函数同名的变量不会屏蔽该函数。请参阅以下问题和答案:stackoverflow.com/q/6135868/602276
Andrie

没错,它不会掩盖它。就在一般情况下,我尽量避免命名函数和变量名与已经存在的R.
蒂姆·


1

我只是整理了一个不错的数据结构和处理链来生成这种切换行为,不需要任何库。我确信它将被实施多次,并且偶然发现了这个线程以查找示例-认为我会参与进来。

我什至没有特别需要标记(这里唯一的标记是调试模式,创建一个变量,我将其作为启动下游功能的条件进行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显示标志定义
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.