Rスクリプトからコマンドラインパラメーターを読み取るにはどうすればよいですか?


281

(コード自体のパラメーター値をハードコードするのではなく)コマンドラインパラメーターをいくつか提供できるようにするRスクリプトがあります。スクリプトはWindowsで実行されます。

コマンドラインで指定したパラメーターをRスクリプトに読み込む方法に関する情報が見つかりません。それができないのならびっくりするので、たぶん私は自分のグーグル検索で最高のキーワードを使っていません...

ポインタや推奨事項はありますか?


rscript実行可能ファイルの場所を設定する必要がある

回答:


209

ここでダークの答えはあなたが必要とするすべてです。これは最小限の再現可能な例です。

との2つのファイルを作成exmpl.batしましたexmpl.R

  • exmpl.bat

    set R_Script="C:\Program Files\R-3.0.2\bin\RScript.exe"
    %R_Script% exmpl.R 2010-01-28 example 100 > exmpl.batch 2>&1

    または、次を使用しRterm.exeます:

    set R_TERM="C:\Program Files\R-3.0.2\bin\i386\Rterm.exe"
    %R_TERM% --no-restore --no-save --args 2010-01-28 example 100 < exmpl.R > exmpl.batch 2>&1
  • exmpl.R

    options(echo=TRUE) # if you want see commands in output file
    args <- commandArgs(trailingOnly = TRUE)
    print(args)
    # trailingOnly=TRUE means that only your arguments are returned, check:
    # print(commandArgs(trailingOnly=FALSE))
    
    start_date <- as.Date(args[1])
    name <- args[2]
    n <- as.integer(args[3])
    rm(args)
    
    # Some computations:
    x <- rnorm(n)
    png(paste(name,".png",sep=""))
    plot(start_date+(1L:n), x)
    dev.off()
    
    summary(x)

両方のファイルを同じディレクトリに保存して、を起動しexmpl.batます。結果は次のようになります。

  • example.png いくつかのプロットで
  • exmpl.batch すべてが行われた

環境変数を追加することもできます%R_Script%

"C:\Program Files\R-3.0.2\bin\RScript.exe"

バッチスクリプトで次のように使用します %R_Script% <filename.r> <arguments>

違いRScriptRterm


127

いくつかのポイント:

  1. コマンドラインパラメータにはからアクセスできるため、概要についてcommandArgs()help(commandArgs)を参照してください。

  2. Rscript.exeWindowsを含むすべてのプラットフォームで使用できます。サポートしcommandArgs()ます。littlerはWindowsに移植できますが、現在はOS XとLinuxでのみ動作します。

  3. CRANにはgetoptoptparseの 2つのアドオンパッケージがあり、どちらもコマンドライン解析用に作成されました。

2015年11月に編集: 新しい代替案が登場しました。私はdocopt心からお勧めします



92

これをスクリプトの先頭に追加します。

args<-commandArgs(TRUE)

次にargs[1]、として渡された引数を参照できますargs[2]

次に実行します

Rscript myscript.R arg1 arg2 arg3

引数がスペースを含む文字列である場合は、二重引用符で囲みます。


7
これは、args <-commandArgs(TRUE)を使用した場合にのみ機能しました(大文字のAに注意してください)。
アンディウェスト

arg1の前に--argsが必要ですか?
philcolbourn 2017年

@philcolbournいいえ
Chris_Rands 2018

15

より良いものにしたい場合は、library(getopt)を試してください... 例えば:

spec <- matrix(c(
        'in'     , 'i', 1, "character", "file from fastq-stats -x (required)",
        'gc'     , 'g', 1, "character", "input gc content file (optional)",
        'out'    , 'o', 1, "character", "output filename (optional)",
        'help'   , 'h', 0, "logical",   "this help"
),ncol=5,byrow=T)

opt = getopt(spec);

if (!is.null(opt$help) || is.null(opt$in)) {
    cat(paste(getopt(spec, usage=T),"\n"));
    q();
}

11

あなたは少し必要です(「リトルr」と発音します)

ダークは、約15分で詳しく説明します。;)


11

以来optparse答えに数回言及し、そしてそれは、コマンドライン処理のための包括的なキットを提供してきた、ここでは、入力ファイルが存在すると仮定すると、あなたがそれを使用する方法の短い簡単な例です:

script.R:

library(optparse)

option_list <- list(
  make_option(c("-n", "--count_lines"), action="store_true", default=FALSE,
    help="Count the line numbers [default]"),
  make_option(c("-f", "--factor"), type="integer", default=3,
    help="Multiply output by this number [default %default]")
)

parser <- OptionParser(usage="%prog [options] file", option_list=option_list)

args <- parse_args(parser, positional_arguments = 1)
opt <- args$options
file <- args$args

if(opt$count_lines) {
  print(paste(length(readLines(file)) * opt$factor))
}

blah.txt23行の任意のファイルが与えられます。

コマンドラインで:

Rscript script.R -h 出力

Usage: script.R [options] file


Options:
        -n, --count_lines
                Count the line numbers [default]

        -f FACTOR, --factor=FACTOR
                Multiply output by this number [default 3]

        -h, --help
                Show this help message and exit

Rscript script.R -n blah.txt 出力 [1] "69"

Rscript script.R -n -f 5 blah.txt 出力 [1] "115"


7

bashでは、次のようなコマンドラインを作成できます。

$ z=10
$ echo $z
10
$ Rscript -e "args<-commandArgs(TRUE);x=args[1]:args[2];x;mean(x);sd(x)" 1 $z
 [1]  1  2  3  4  5  6  7  8  9 10
[1] 5.5
[1] 3.027650
$

変数$zが「10」のbashシェルによって置き換えられ、この値がによって取得されcommandArgsてに供給されargs[2]x=1:10Rによってrangeコマンドが正常に実行されたことがわかります。


4

参考:R関数の引数を取得する関数args()があります。argsという名前の引数のベクトルと混同しないでください。


1
これはほぼ間違いなくそうではありません。関数だけが関数をマスクできます。関数と同じ名前の変数を作成しても、関数はマスクされません。この質問と回答を参照してください:stackoverflow.com/q/6135868/602276
Andrie

確かに、それはそれをマスクしません。ただ、一般的に、私はすでにRに存在する名前を持つ関数や変数の命名回避しよう
ティム

1

フラグ付きのオプションを指定する必要がある場合(-h、-help、-number = 42など)、Rパッケージのoptparse(Pythonからインスピレーションを得たもの)を使用できます。http//cran.r-project.org /web/packages/optparse/vignettes/optparse.pdf

少なくともこれは私があなたの質問を理解する方法です。なぜなら、bash getopt、またはperl Getopt、またはpython argparseおよびoptparseに相当するものを探しているときにこの投稿を見つけたからです。


1

ライブラリを必要とせずに、この切り替え動作を生成するために、優れたデータ構造と一連の処理を組み合わせただけです。私はそれが何度も実装されていると確信しており、例を探してこのスレッドに出くわしました-私はチップインすると思いました。

特にフラグは必要ありませんでした(ここでの唯一のフラグはデバッグモードであり、下流の関数を開始する条件としてチェックする変数を作成しますif (!exists(debug.mode)) {...} else {print(variables)})lapply以下のフラグチェックステートメントは以下と同じ結果になります:

if ("--debug" %in% args) debug.mode <- T
if ("-h" %in% args || "--help" %in% args) 

ここargsで、コマンドライン引数から読み込まれた変数(文字ベクトル、c('--debug','--help')たとえばこれらを指定した場合と同じ)

それは他のフラグで再利用可能であり、すべての繰り返しを避け、ライブラリもないので依存関係もありません。

args <- commandArgs(TRUE)

flag.details <- list(
"debug" = list(
  def = "Print variables rather than executing function XYZ...",
  flag = "--debug",
  output = "debug.mode <- T"),
"help" = list(
  def = "Display flag definitions",
  flag = c("-h","--help"),
  output = "cat(help.prompt)") )

flag.conditions <- lapply(flag.details, function(x) {
  paste0(paste0('"',x$flag,'"'), sep = " %in% args", collapse = " || ")
})
flag.truth.table <- unlist(lapply(flag.conditions, function(x) {
  if (eval(parse(text = x))) {
    return(T)
  } else return(F)
}))

help.prompts <- lapply(names(flag.truth.table), function(x){
# joins 2-space-separatated flags with a tab-space to the flag description
  paste0(c(paste0(flag.details[x][[1]][['flag']], collapse="  "),
  flag.details[x][[1]][['def']]), collapse="\t")
} )

help.prompt <- paste(c(unlist(help.prompts),''),collapse="\n\n")

# The following lines handle the flags, running the corresponding 'output' entry in flag.details for any supplied
flag.output <- unlist(lapply(names(flag.truth.table), function(x){
  if (flag.truth.table[x]) return(flag.details[x][[1]][['output']])
}))
eval(parse(text = flag.output))

flag.detailsここでは、コマンドは文字列として保存され、で評価されることに注意してくださいeval(parse(text = '...'))。深刻なスクリプトにはOptparseが望ましいのは明らかですが、最小限の機能のコードが良い場合もあります。

出力例:

$ Rscript check_mail.Rscript --help
--debug関数XYZを実行するのではなく、変数を出力します...

-h --helpフラグ定義を表示します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.