[英]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
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
= 2
且b
= 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
= 2
, b
= 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.