web-dev-qa-db-ja.com

コマンドライン引数をR CMD BATCHに渡す

端末からR CMD BATCH my_script.Rを使用してRスクリプトを実行しています。私は今、コマンドに引数を渡したいと思っていますが、機能させるためにいくつかの問題があります。 R CMD BATCH my_script.R blablaを実行すると、blablaが、実行中のRスクリプトで使用可能な引数として解釈されるのではなく、出力ファイルになります。

blablaを引数として正しく渡すように見えるRscript my_script.R blablaを試しましたが、my_script.Routで取得したR CMD BATCH出力ファイルを取得しません(.Routファイルが必要です)。 Rscriptへの呼び出しの出力を選択したファイル名にリダイレクトできましたが、R CMD BATCH.Routファイルで行うような方法で、R入力コマンドをファイルに含めることはできません。

したがって、理想的には、R CMD BATCHメソッドを介して実行されているRスクリプトに引数を渡す方法を求めていますが、同等の.Routファイルを生成する方法があればRscriptを使用するアプローチに満足します。

91
Bryce Thomas

私の印象では、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ファイルを生成できます。 1つの方法は、小さなRスクリプトを作成することです-itRscriptEcho.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を実行し、インターリーブされた入力、出力、およびメッセージを一意の名前の.Routにシンクします。

Edit2:
Rscriptを詳細に実行し、詳細な出力をファイルに配置できます。

Rscript --verbose myScript.R 5 100 > myScript.Rout
98
Josh O'Brien

ここで説明したオプションを試した後、r-bloggersのForesterから この投稿 を見つけました。私はそれを考慮するためのきれいなオプションだと思います。

私は彼のコードをここに置きます:

コマンドラインから

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

in test.out

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

Forester

25
Alex A.

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 
9
user1563570

my_script.Rの前に引数を置き、引数に-を使用する必要があります。

R CMD BATCH -blabla my_script.R

この場合、commandArgs()-blablaを文字列として受け取ります。詳細については、ヘルプを参照してください。

$ 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.
8
Yihui Xie

1行のソリューションは常に良いと思うので、答えを追加します。 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"
3
ClementWalter

R CMD BATCHを使用して、コマンドライン引数を処理する別の方法を次に示します。 以前の回答 に基づいた私のアプローチでは、コマンドラインで引数を指定し、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)

コマンドラインで、次のように入力すると

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

次に、R内にa = 2b = c(2,5,6)があります。しかし、たとえば、bを省略し、別の引数cを追加できます。

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

Rでは、a = 2b = 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)))
0
Dagremu