简体   繁体   English

将命令行参数传递给R CMD BATCH

[英]Passing command line arguments to R CMD BATCH

I have been using R CMD BATCH my_script.R from a terminal to execute an R script. 我一直在使用来自终端的R CMD BATCH my_script.R来执行R脚本。 I am now at the point where I would like to pass an argument to the command, but am having some issues getting it working. 我现在正处于我想向命令传递一个参数的地步,但是我遇到了一些让它工作的问题。 If I do R CMD BATCH my_script.R blabla then blabla becomes the output file, rather than being interpreted as an argument available to the R script being executed. 如果我做R CMD BATCH my_script.R blabla然后blabla成为输出文件,而不是被解释为正在执行的R脚本可用的参数。

I have tried Rscript my_script.R blabla which seems to pass on blabla correctly as an argument, but then I don't get the my_script.Rout output file that I get with R CMD BATCH (I want the .Rout file). 我已经尝试过Rscript my_script.R blabla ,它似乎正确地将blabla作为参数传递,但是后来我没有得到我用R CMD BATCH得到的my_script.Rout输出文件(我想要.Rout文件)。 While I could redirect the output of a call to Rscript to a file name of my choosing, I would not be getting the R input commands included in the file in the way R CMD BATCH does in the .Rout file. 虽然我可以Rscript的调用输出重定向到我选择的文件名,但我不会按照R CMD BATCH.Rout文件中的方式获取文件中包含的R输入命令。

So, ideally, I'm after a way to pass arguments to an R script being executed via the R CMD BATCH method, though would be happy with an approach using Rscript if there is a way to make it produce a comparable .Rout file. 因此,理想情况下,我正在尝试将参数传递给通过R CMD BATCH方法执行的R脚本,但如果有办法使其生成类似的.Rout文件,则会对使用Rscript的方法感到满意。

My impression is that R CMD BATCH is a bit of a relict. 我的印象是R CMD BATCH有点像残骸。 In any case, the more recent Rscript executable (available on all platforms), together with commandArgs() makes processing command line arguments pretty easy. 在任何情况下,更新的Rscript可执行文件(在所有平台上都可用)与commandArgs()一起使得处理命令行参数非常容易。

As an example, here is a little script -- call it "myScript.R" : 举个例子,这是一个小脚本 - 称之为"myScript.R"

## myScript.R
args <- commandArgs(trailingOnly = TRUE)
rnorm(n=as.numeric(args[1]), mean=as.numeric(args[2]))

And here is what invoking it from the command line looks like 这是从命令行调用它的样子

> Rscript myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

Edit: 编辑:

Not that I'd recommend it, but ... using a combination of source() and sink() , you could get Rscript to produce an .Rout file like that produced by R CMD BATCH . 不是我推荐它,但是......使用source()sink() ,你可以得到Rscript来生成一个.Rout R CMD BATCH生成的.Rout文件。 One way would be to create a little R script -- call it RscriptEcho.R -- which you call directly with Rscript. 一种方法是创建一个小R脚本 - 称之为RscriptEcho.R - 您可以直接使用Rscript调用 It might look like this: 它可能看起来像这样:

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

To execute your actual script, you would then do: 要执行您的实际脚本,您将执行以下操作:

Rscript RscriptEcho.R myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

which will execute myScript.R with the supplied arguments and sink interleaved input, output, and messages to a uniquely named .Rout . 它将使用提供的参数执行myScript.R ,并将交错的输入,输出和消息.Rout到唯一命名的.Rout

Edit2: EDIT2:
You can run Rscript verbosely and place the verbose output in a file. 您可以详细运行Rscript并将详细输出放在文件中。

Rscript --verbose myScript.R 5 100 > myScript.Rout

After trying the options described here, I found this post from Forester in r-bloggers . 在尝试了这里描述的选项之后,我在r-bloggers中找到了来自Forester的这篇文章 I think it is a clean option to consider. 我认为这是一个干净的选择。

I put his code here: 我把他的代码放在这里:

From command line 从命令行

$ R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)' test.R test.out &

Test.R 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)

In test.out 在test.out中

> print(a*2)
[1] 2
> print(b*3)
[1]  6 15 18

Thanks to Forester ! 感谢Forester

In your R script, called test.R : 在你的R脚本中,名为test.R

args <- commandArgs(trailingOnly = F)
myargument <- args[length(args)]
myargument <- sub("-","",myargument)
print(myargument)
q(save="no")

From the command line run: 从命令行运行:

R CMD BATCH -4 test.R

Your output file, test.Rout, will show that the argument 4 has been successfully passed to 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 

You need to put arguments before my_script.R and use - on the arguments, eg 你需要在my_script.R之前放置参数并在参数上使用-例如

R CMD BATCH -blabla my_script.R

commandArgs() will receive -blabla as a character string in this case. 在这种情况下, commandArgs()将接收-blabla作为字符串。 See the help for details: 有关详细信息,请参阅帮助

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

I add an answer because I think a one line solution is always good! 我添加了一个答案,因为我认为一线解决方案总是好的! Atop of your myRscript.R file, add the following line: myRscript.R文件的顶部,添加以下行:

eval(parse(text=paste(commandArgs(trailingOnly = TRUE), collapse=";")))

Then submit your script with something like: 然后提交您的脚本,例如:

R CMD BATCH [options] '--args arguments you want to supply' myRscript.R &

For example: 例如:

R CMD BATCH --vanilla '--args N=1 l=list(a=2, b="test") name="aname"' myscript.R &

Then: 然后:

> ls()
[1] "N"    "l"    "name"

Here's another way to process command line args, using R CMD BATCH . 这是使用R CMD BATCH处理命令行参数的另一种方法。 My approach, which builds on an earlier answer here , lets you specify arguments at the command line and, in your R script, give some or all of them default values. 我的方法基于此处的早期答案 ,允许您在命令行中指定参数,并在R脚本中提供其中的部分或全部默认值。

Here's an R file, which I name test.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)

At the command line, if I type 在命令行,如果我键入

R CMD BATCH --no-save --no-restore '--args a=2 b=c(2,5,6)' test.R

then within R we'll have a = 2 and b = c(2,5,6) . 然后在R内我们将得到a = 2b = c(2,5,6) But I could, say, omit b , and add in another argument c : 但我可以说,省略b ,并添加另一个参数c

R CMD BATCH --no-save --no-restore '--args a=2 c="hello"' test.R

Then in R we'll have a = 2 , b = c(1,1,1) (the default), and c = "hello" . 然后在R中我们将得到a = 2b = c(1,1,1) (默认值),并且c = "hello"

Finally, for convenience we can wrap the R code in a function, as long as we're careful about the environment: 最后,为方便起见,我们可以将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)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM