我如何从R脚本读取命令行参数?
我有一个R脚本,我希望能够提供几个命令行参数(而不是代码本身的硬编码参数值)。 该脚本在Windows上运行。
我无法find有关如何将命令行上提供的参数读入我的R脚本的信息。 如果无法完成,我会感到惊讶,所以也许我只是没有在我的Googlesearch中使用最好的关键字…
任何指针或build议?
德克的答案是你需要的一切。 这是一个最小的可重复的例子。
我做了两个文件: 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
你也可以添加一个环境variables%R_Script%
:
"C:\Program Files\R-3.0.2\bin\RScript.exe"
并在批处理脚本中使用它作为%R_Script% <filename.r> <arguments>
RScript
和Rterm
-
Rscript
有更简单的语法 -
Rscript
在x64上自动select体系结构(请参阅R安装和pipe理,2.6子体系结构以了解详细信息) - 如果要将命令写入输出文件,
Rscript
需要.R文件中的options(echo=TRUE)
几点:
-
命令行参数可以通过
commandArgs()
来访问,所以请参阅help(commandArgs)
来获得概述。 -
您可以在所有平台(包括Windows)上使用
Rscript.exe
。 它将支持commandArgs()
。 littler可以移植到Windows上,但现在只能在OS X和Linux上运行。 -
CRAN上有两个附加软件包: getopt和optparse ,这两个软件包都是为命令行分析而编写的。
编辑在2015年11月:新的替代品已经出现,我全心全意推荐doctopt 。
将其添加到脚本的顶部:
args<-commandArgs(TRUE)
然后你可以引用参数args[1]
, args[2]
等
然后运行
Rscript myscript.R arg1 arg2 arg3
如果您的参数是包含空格的string,请使用双引号括起来。
尝试库(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(); }
你需要小动物 (发音为“小r”)
德克将在15分钟内详细阐述;)
在bash中,你可以像下面这样构build一个命令行:
$ 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 $
你可以看到variables$z
被bash shellreplace为“10”,并且这个值被commandArgs
拾取并且被input到args[2]
以及由R成功执行的范围命令x=1:10
等等。
由于optparse
在答案中已经提到了几次,它提供了一个用于命令行处理的综合工具包,下面是一个简单的例子,假设input文件存在,你可以如何使用它:
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)) }
给定一个23行的任意文件blah.txt
。
在命令行上:
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"
仅供参考:有一个函数args(),它检索R函数的参数,不要与名为args的参数向量混淆
如果你需要用标志来指定选项(比如-h,–help,–number = 42等),你可以使用R包optparse(灵感来自Python): http : //cran.r-project.org /web/packages/optparse/vignettes/optparse.pdf 。
至less这个我怎么理解你的问题,因为我发现这个职位时,寻找一个相当于bash getopt,perl Getopt或python argparse和optparse。
我只是放在一个很好的数据结构和处理链来产生这种切换行为,不需要库。 我相信它已经被实现了很多次,并且遇到了这个线程寻找的例子 – 认为我会插入。
我甚至没有特别需要标志(这里唯一的标志是debugging模式, if (!exists(debug.mode)) {...} else {print(variables)})
创build一个variables,我将检查它作为启动下游函数的一个条件if (!exists(debug.mode)) {...} else {print(variables)})
。 检查lapply
语句的标志如下所示:
if ("--debug" %in% args) debug.mode <- T if ("-h" %in% args || "--help" %in% args)
其中args
是从命令行参数中读入的variables(一个字符向量,当你提供这些参数时,相当于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
,这些命令被存储为string,然后用eval(parse(text = '...'))
进行评估。 对于任何严肃的脚本,Optparse显然是可取的,但是最小function的代码有时也是很好的。
示例输出:
$ Rscript check_mail.Rscript - 帮助 --debug打印variables而不是执行函数XYZ ... -h --help显示标志定义