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


102

私が使用しているR CMD BATCH my_script.R実行するために端末からRスクリプトを。現在、コマンドに引数を渡したいところですが、機能させるためにいくつかの問題があります。私が行う場合はR CMD BATCH my_script.R blabla、その後blabla、むしろRスクリプトが実行されるのに利用できる引数として解釈されるより、出力ファイルになります。

引数として正しくRscript my_script.R blabla渡されるように見えるものを試しましたblablaが、取得したmy_script.Rout出力ファイルを取得できませんR CMD BATCH.Routファイルが必要です)。私はコールの出力をリダイレクトすることもできますがRscript、私が選んだのファイル名に、私はある意味では、ファイルに含まR入力コマンド取得されることはないR CMD BATCHでない.Routファイルを。

したがって、理想的には、R CMD BATCHメソッドを介して実行されるRスクリプトに引数を渡すRscript方法を探してい.Routますが、比較可能なファイルを作成する方法がある場合は、それを使用したアプローチで満足します。

回答:


113

私の印象はそれ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。呼び出す-一つの方法は、小さな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、指定された引数で実行され、インターリーブされた入力、出力、およびメッセージを一意の名前でシンクします.Rout

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

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

4
R CMD BATCH遺跡でもある印象を受けます。ただし.Rout、スクリプト出力だけでなく、.Rその出力を生成したスクリプトファイルから入力コマンド/コメントをインターリーブするファイルも生成するのが好きです。
ブライストーマス

1
私はあなたを聞く。それは(私はまだそうだと思います!)の良い面でしたR CMD BATCH
Josh O'Brien

5
しかし、私はあなたがより良いよりも行うことができると思うR CMD BATCHknitr例えば、Rscript -e "knitr::stitch(commandArgs(TRUE)[1])" my_script.R(あなたは置き換えることができstitchstitch_rhtmlstitch_rmd、あなたがインストールする必要がありますknitrからGitHubの私はちょうどでバグを発見したので、stitch...)
Yihui謝

7
0.02を追加するだけで、ターミナルからのリダイレクトも簡単に使用できます。例はRscript myfile.R > path/to/mylog.Rout、標準出力(画面)に出力される代わりに、ファイルの出力がファイルに保存されます.Rout
James Pringle

3
@JamesPringleに追加するために、出力を画面(リアルタイムで監視するため)とファイル(後で見るため)の両方に印刷することがよくあります。私はそうしますRscript myfile.R | tee mylog.Rout
ハイゼンベルク

26

ここで説明されているオプションを試した、Foresterのこの投稿をr-bloggersで見つけました。検討するのはクリーンなオプションだと思います。

私は彼のコードをここに入れました:

コマンドラインから

$ 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

フォレスターに感謝!


引数が文字型の場合、一重引用符や二重引用符を使用する必要がないことに注意してください。例:R CMD BATCH '--args a = FolderName' test.R test.out&
d2a2d

フォレスターの投稿で述べたように、--argsが鍵です。それはまたで動作R --no-save --no-restore --args a=1 < test.Rし、R --no-save --no-restore < test.R --args a=1
デイブ

コマンドラインから--argsに引数を渡す方法はありますか?したがって、コマンドラインでforループを実行し、それを--args行で送信するとします。
user2809432

9

あなたの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 

8

あなたは前に引数を置き、引数で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.

2
この方法で行うと、スクリプトの使用args <- commandArgs(FALSE)後に引数を出力すると、次のように、自分のものではないものを含め、すべての引数が使用されてしまいます。--restore--save私が使用している場合などcommandArgs(TRUE)、私はすべての引数を取得していません。私自身の追加の引数だけを取得する方法はありますか? --args有望に見えますが、動作させることができませんでした...
ブライストーマス

引数は最後から数える必要があります(たとえば、サイズ2、サイズ1、サイズ)-あなたの引数は常に最後になります。
ynka 2014年

4

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"

0

を使用してコマンドライン引数を処理する別の方法を次に示しR CMD BATCHます。私のアプローチは、ここで以前の答えに基づいていますでのでは、コマンドラインで引数を指定し、Rスクリプトでそれらの一部またはすべてにデフォルト値を指定できます。

これが私がtest.Rという名前の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)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.