将命令行parameter passing给R CMD BATCH
我一直在使用R CMD BATCH my_script.R
从一个terminal执行一个R
脚本。 我现在正想让这个命令传递一个参数,但是在解决这个问题的时候遇到了一些问题。 如果我执行R CMD BATCH my_script.R blabla
则blabla
将成为输出文件,而不是被解释为正在执行的R脚本可用的参数。
我已经试过Rscript my_script.R blabla
似乎正确地作为parameter passing,但是然后我没有得到R CMD BATCH
(我想.Rout
文件)的my_script.Rout
输出文件。 虽然我可以redirect到Rscript
调用的输出到我select的文件名,但我不会以R CMD BATCH
在.Rout
文件中的方式获取文件中包含的Rinput命令。
因此,理想情况下,我想通过R CMD BATCH
方法将parameter passing给正在执行的R脚本,尽pipe如果有办法使它产生一个可比较的.Rout
文件,对于使用Rscript
的方法会感到满意。
我的印象是, R CMD BATCH
有点遗憾。 在任何情况下,最新的Rscript
可执行文件(在所有平台上都可用)和commandArgs()
使得处理命令行参数非常容易。
作为一个例子,这里有一个小脚本 – 称之为"myScript.R"
:
## myScript.R args <- commandArgs(trailingOnly = TRUE) rnorm(n=as.numeric(args[1]), mean=as.numeric(args[2]))
这里是从命令行调用它的样子
> Rscript myScript.R 5 100 [1] 98.46435 100.04626 99.44937 98.52910 100.78853
编辑:
不是我推荐它,但是…使用source()
和sink()
,可以让Rscript
生成一个.Rout
文件,就像R CMD BATCH
生成的文件一样。 一种方法是创build一个小R脚本 – 称之为RscriptEcho.R
– 你直接用Rscript调用。 它可能看起来像这样:
## RscriptEcho.R args <- commandArgs(TRUE) srcFile <- args[1] outFile <- paste0(make.names(date()), ".Rout") args <- args[-1] sink(outFile, split = TRUE) source(srcFile, echo = TRUE)
要执行您的实际脚本,您将然后执行:
Rscript RscriptEcho.R myScript.R 5 100 [1] 98.46435 100.04626 99.44937 98.52910 100.78853
它将使用提供的参数执行myScript.R
,并将交织input,输出和消息.Rout
到一个唯一命名的.Rout
。
在尝试了这里介绍的选项之后,我在r-bloggers中发现了Forester的这篇文章 。 我认为这是一个干净的select考虑。
我把他的代码放在这里:
从命令行
$ R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)' test.R test.out &
Test.R
##First read in the arguments listed at the command line args=(commandArgs(TRUE)) ##args is now a list of character vectors ## First check to see if arguments are passed. ## Then cycle through each element of the list and evaluate the expressions. if(length(args)==0){ print("No arguments supplied.") ##supply default values a = 1 b = c(1,1,1) }else{ for(i in 1:length(args)){ eval(parse(text=args[[i]])) } } print(a*2) print(b*3)
在test.out中
> print(a*2) [1] 2 > print(b*3) [1] 6 15 18
感谢Forester !
你需要把参数放在my_script.R
之前,然后使用参数,例如
R CMD BATCH -blabla my_script.R
在这种情况下, commandArgs()
将接收-blabla
作为string。 查看帮助了解详细信息:
$ R CMD BATCH --help Usage: R CMD BATCH [options] infile [outfile] Run R non-interactively with input from infile and place output (stdout and stderr) to another file. If not given, the name of the output file is the one of the input file, with a possible '.R' extension stripped, and '.Rout' appended. Options: -h, --help print short help message and exit -v, --version print version info and exit --no-timing do not report the timings -- end processing of options Further arguments starting with a '-' are considered as options as long as '--' was not encountered, and are passed on to the R process, which by default is started with '--restore --save --no-readline'. See also help('BATCH') inside R.
在您的R脚本中,名为test.R
:
args <- commandArgs(trailingOnly = F) myargument <- args[length(args)] myargument <- sub("-","",myargument) print(myargument) q(save="no")
从命令行运行:
R CMD BATCH -4 test.R
您的输出文件test.Rout将显示参数4
已成功传递给R:
cat test.Rout > args <- commandArgs(trailingOnly = F) > myargument <- args[length(args)] > myargument <- sub("-","",myargument) > print(myargument) [1] "4" > q(save="no") > proc.time() user system elapsed 0.222 0.022 0.236
我添加一个答案,因为我认为一行解决scheme总是好的! 在myRscript.R
文件的顶部,添加以下行:
eval(parse(text=paste(commandArgs(trailingOnly = TRUE), collapse=";")))
然后提交你的脚本,如:
R CMD BATCH [options] '--args arguments you want to supply' myRscript.R &
例如:
R CMD BATCH --vanilla '--args N=1 l=list(a=2, b="test") name="aname"' myscript.R &
然后:
> ls() [1] "N" "l" "name"
这是使用R CMD BATCH
处理命令行参数的另一种方法。 我的方法build立在这里的早期答案上 ,可以让你在命令行中指定参数,并在你的R脚本中给出一些或全部的默认值。
这是一个R文件,我叫test.R :
defaults <- list(a=1, b=c(1,1,1)) ## default values of any arguments we might pass ## parse each command arg, loading it into global environment for (arg in commandArgs(TRUE)) eval(parse(text=arg)) ## if any variable named in defaults doesn't exist, then create it ## with value from defaults for (nm in names(defaults)) assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]))[[1]]) print(a) print(b)
在命令行,如果我input
R CMD BATCH --no-save --no-restore '--args a=2 b=c(2,5,6)' test.R
那么在R内,我们将有a
= 2
和b
= c(2,5,6)
。 但我可以说,省略b
,并加上另一个论点c
:
R CMD BATCH --no-save --no-restore '--args a=2 c="hello"' test.R
然后在R中,我们将有a
= 2
, b
= c(1,1,1)
(默认)和c
= "hello"
。
最后,为了方便起见,只要我们注意环境,我们可以把R代码封装在一个函数中:
## defaults should be either NULL or a named list parseCommandArgs <- function(defaults=NULL, envir=globalenv()) { for (arg in commandArgs(TRUE)) eval(parse(text=arg), envir=envir) for (nm in names(defaults)) assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]), envir=envir)[[1]], pos=envir) } ## example usage: parseCommandArgs(list(a=1, b=c(1,1,1)))