Bagaimana saya bisa membaca parameter baris perintah dari skrip R?

Saya memiliki skrip R yang saya ingin dapat menyediakan beberapa parameter baris perintah (daripada nilai parameter hardcode dalam kode itu sendiri). Skrip berjalan di Windows.

Saya tidak dapat menemukan info tentang cara membaca parameter yang disediakan pada baris perintah ke dalam skrip R saya. Saya akan terkejut jika hal itu tidak dapat dilakukan, jadi mungkin saya hanya tidak menggunakan kata kunci terbaik dalam pencarian Google saya...

Ada petunjuk atau rekomendasi?


person monch1962    schedule 27.01.2010    source sumber
comment
Anda perlu mengatur lokasi rscript yang dapat dieksekusi   -  person    schedule 02.08.2017


Jawaban (10)


Jawaban Dirk di sini adalah semua yang Anda butuhkan. Berikut adalah contoh minimal yang dapat direproduksi.

Saya membuat dua file: exmpl.bat dan 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
    

    Alternatifnya, menggunakan 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)
    

Simpan kedua file di direktori yang sama dan mulai exmpl.bat. Hasilnya Anda akan mendapatkan:

  • example.png dengan beberapa plot
  • exmpl.batch dengan semua yang telah dilakukan

Anda juga dapat menambahkan variabel lingkungan %R_Script%:

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

dan gunakan dalam skrip batch Anda sebagai %R_Script% <filename.r> <arguments>

Perbedaan antara RScript dan Rterm:

  • Rscript memiliki sintaks yang lebih sederhana
  • Rscript secara otomatis memilih arsitektur pada x64 (lihat Instalasi R dan Administrasi, 2.6 Sub-arsitektur untuk detailnya)
  • Rscript membutuhkan options(echo=TRUE) di file .R jika Anda ingin menulis perintah ke file output
person Marek    schedule 28.01.2010

Beberapa poin:

  1. Parameter baris perintah dapat diakses melalui commandArgs(), jadi lihat help(commandArgs) untuk gambaran umum.

  2. Anda dapat menggunakan Rscript.exe di semua platform, termasuk Windows. Ini akan mendukung commandArgs(). sedikit dapat di-porting ke Windows tetapi saat ini hanya tersedia di OS X dan Linux.

  3. Ada dua paket tambahan di CRAN -- getopt dan optparse -- keduanya ditulis untuk penguraian baris perintah.

Edit pada November 2015: Alternatif baru telah muncul dan saya dengan sepenuh hati merekomendasikan mendokumentasikan.

person Dirk Eddelbuettel    schedule 28.01.2010
comment
dan ada argparse - person gkcn; 13.08.2013

Tambahkan ini ke bagian atas skrip Anda:

args<-commandArgs(TRUE)

Kemudian Anda bisa merujuk pada argumen yang disampaikan sebagai args[1], args[2] dll.

Lalu lari

Rscript myscript.R arg1 arg2 arg3

Jika argumen Anda adalah string dengan spasi di dalamnya, sertakan dalam tanda kutip ganda.

person Hrishi Mittal    schedule 28.01.2010
comment
Ini hanya berfungsi ketika saya menggunakan argsā€¹-commandArgs(TRUE) (perhatikan huruf besar A). - person Andy West; 27.04.2012
comment
apakah Anda memerlukan --args sebelum arg1? - person philcolbourn; 24.05.2017
comment
@philcolbourn Tidak - person Chris_Rands; 19.02.2018

Coba perpustakaan(getopt) ... jika Anda ingin segalanya menjadi lebih baik. Misalnya:

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();
}
person Erik Aronesty    schedule 27.12.2012

Karena optparse telah disebutkan beberapa kali dalam jawaban, dan ini menyediakan kit komprehensif untuk pemrosesan baris perintah, berikut adalah contoh singkat yang disederhanakan tentang bagaimana Anda dapat menggunakannya, dengan asumsi file input ada:

skrip.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))
}

Diberikan file arbitrer blah.txt dengan 23 baris.

Di baris perintah:

Rscript script.R -h keluaran

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 keluaran [1] "69"

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

person Megatron    schedule 15.10.2015

Anda memerlukan littler (diucapkan 'little r')

Dirk akan tiba sekitar 15 menit untuk menjelaskan lebih lanjut;)

person JD Long    schedule 28.01.2010

Di bash, Anda dapat membuat baris perintah seperti berikut:

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

Anda dapat melihat bahwa variabel $z diganti dengan bash shell dengan "10" dan nilai ini diambil oleh commandArgs dan dimasukkan ke dalam args[2], dan perintah rentang x=1:10 berhasil dijalankan oleh R, dll.

person TTW    schedule 09.01.2011

FYI: ada fungsi args(), yang mengambil argumen fungsi R, jangan bingung dengan vektor argumen bernama args

person Tim    schedule 09.11.2011
comment
Hal ini hampir pasti tidak terjadi. Hanya fungsi yang dapat menutupi fungsi. Membuat variabel dengan nama yang sama dengan suatu fungsi tidak menutupi fungsi tersebut. Lihat pertanyaan dan jawaban ini: stackoverflow.com/q/6135868/602276 - person Andrie; 09.11.2011
comment
Benar, itu tidak menutupinya. Secara umum, saya mencoba menghindari penamaan fungsi dan variabel dengan nama yang sudah ada di R. - person Tim; 10.11.2011

Jika Anda perlu menentukan opsi dengan tanda, (seperti -h, --help, --number=42, dll), Anda dapat menggunakan paket R optparse (terinspirasi dari Python): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf.

Setidaknya beginilah cara saya memahami pertanyaan Anda, karena saya menemukan posting ini ketika mencari yang setara dengan bash getopt, atau perl Getopt, atau python argparse dan optparse.

person TheBinturonGggh    schedule 20.05.2014

Saya baru saja menyusun struktur data dan rantai pemrosesan yang bagus untuk menghasilkan perilaku peralihan ini, tidak diperlukan perpustakaan. Saya yakin ini akan diterapkan berkali-kali, dan menemukan thread ini untuk mencari contoh - saya pikir saya akan ikut serta.

Saya bahkan tidak terlalu membutuhkan flag (satu-satunya flag di sini adalah mode debug, membuat variabel yang saya periksa sebagai syarat untuk memulai fungsi hilir if (!exists(debug.mode)) {...} else {print(variables)}). Pernyataan flag yang memeriksa lapply di bawah menghasilkan hal yang sama seperti:

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

di mana args adalah variabel yang dibaca dari argumen baris perintah (vektor karakter, setara dengan c('--debug','--help') ketika Anda menyediakannya misalnya)

Ini dapat digunakan kembali untuk flag lain dan Anda menghindari semua pengulangan, dan tidak ada perpustakaan sehingga tidak ada ketergantungan:

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

Perhatikan bahwa di flag.details di sini perintah disimpan sebagai string, kemudian dievaluasi dengan eval(parse(text = '...')). Optparse jelas diinginkan untuk skrip serius apa pun, tetapi kode dengan fungsionalitas minimal terkadang juga bagus.

Contoh keluaran:

$ Rscript check_mail.Rscript --help
--debug Print  variables rather than executing function XYZ...

-h  --help  Display flag definitions
person Louis Maddox    schedule 13.02.2015