ฉันจะอ่านพารามิเตอร์บรรทัดคำสั่งจากสคริปต์ R ได้อย่างไร


281

ฉันมีสคริปต์ R ซึ่งฉันสามารถจัดหาพารามิเตอร์บรรทัดคำสั่งได้หลายตัว (แทนที่จะเป็นค่าพารามิเตอร์ hardcode ในโค้ดเอง) สคริปต์ทำงานบน Windows

ฉันไม่สามารถหาข้อมูลเกี่ยวกับวิธีการอ่านพารามิเตอร์ที่ให้มาในบรรทัดคำสั่งลงในสคริปต์ R ของฉัน ฉันจะแปลกใจถ้ามันไม่สามารถทำได้ดังนั้นบางทีฉันอาจไม่ได้ใช้คำหลักที่ดีที่สุดในการค้นหาของ Google ...

พอยน์เตอร์หรือคำแนะนำใด ๆ


คุณต้องตั้งค่าตำแหน่งของไฟล์ปฏิบัติการ

คำตอบ:


209

คำตอบของเดิร์คคือทุกสิ่งที่คุณต้องการ นี่คือตัวอย่างที่ทำซ้ำได้น้อยที่สุด

ผมทำสองไฟล์: และexmpl.batexmpl.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>

ความแตกต่างระหว่างRScriptและRterm:


127

คะแนนน้อย:

  1. พารามิเตอร์บรรทัดคำสั่งสามารถเข้าถึงได้ผ่านทางcommandArgs()ดังนั้นดูhelp(commandArgs)ภาพรวม

  2. คุณสามารถใช้Rscript.exeบนแพลตฟอร์มทั้งหมดรวมถึง Windows commandArgs()มันจะให้การสนับสนุน littlerสามารถย้ายไปยัง Windows ได้ แต่ตอนนี้ใช้งานได้เฉพาะบน OS X และ Linux

  3. มีแพ็กเกจเสริมสองรายการใน CRAN - getoptและoptparse - ซึ่งเขียนขึ้นสำหรับการแยกวิเคราะห์บรรทัดคำสั่ง

แก้ไขในเดือนพฤศจิกายน 2558: มีทางเลือกใหม่ ๆ ปรากฏขึ้นและฉันขอแนะนำอย่างสุดใจ docopt


2
และมีการโต้แย้ง
gkcn

92

เพิ่มสิ่งนี้ไปที่ด้านบนของสคริปต์ของคุณ:

args<-commandArgs(TRUE)

จากนั้นคุณสามารถดูการขัดแย้งผ่านการเป็นargs[1],args[2]ฯลฯ

จากนั้นเรียกใช้

Rscript myscript.R arg1 arg2 arg3

หาก args ของคุณเป็นสตริงที่มีช่องว่างในนั้นให้ใส่เครื่องหมายคำพูดคู่


7
สิ่งนี้ใช้ได้เฉพาะเมื่อฉันใช้ args <-commandArgs (TRUE) (หมายเหตุตัวพิมพ์ใหญ่ A)
Andy West

คุณต้องการ --args ก่อน arg1 หรือไม่
philcolbourn

@philcolbourn ไม่มี
Chris_Rands

15

ลองใช้ไลบรารี่ (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

คุณต้องการlittler (ออกเสียงจระเข้น้อย ')

เดิร์คจะใช้เวลาประมาณ 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.txtด้วย 23 บรรทัด

บนบรรทัดคำสั่ง:

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ถูกแทนที่ด้วย bash shell ด้วย "10" และค่านี้จะถูกเลือกโดยcommandArgsและป้อนเข้าargs[2]และคำสั่ง range ที่x=1:10ดำเนินการโดย R สำเร็จ ฯลฯ ฯลฯ


4

FYI: มีฟังก์ชั่น args () ซึ่งดึงข้อโต้แย้งของฟังก์ชัน R เพื่อไม่ให้สับสนกับเวกเตอร์ของอาร์กิวเมนต์ที่ชื่อ args


1
นี่ไม่ใช่กรณีอย่างแน่นอน ฟังก์ชั่นเท่านั้นที่สามารถปกปิดฟังก์ชั่น การสร้างตัวแปรที่มีชื่อเดียวกันกับฟังก์ชั่นไม่ปิดบังฟังก์ชัน อ้างถึงคำถามและคำตอบนี้: stackoverflow.com/q/6135868/602276
Andrie

จริงมันไม่ปิดบัง โดยทั่วไปแล้วฉันพยายามหลีกเลี่ยงการตั้งชื่อฟังก์ชั่นและตัวแปรที่มีชื่อที่มีอยู่แล้วในอาร์
ทิม

1

หากคุณจำเป็นต้องระบุตัวเลือกที่มีธง (เช่น -h, --help, --number = 42, ฯลฯ ) คุณสามารถใช้แพคเกจ optparse R (แรงบันดาลใจจากงูใหญ่): http://cran.r-project.org /web/packages/optparse/vignettes/optparse.pdf/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 - ช่วยเหลือ
--debug ตัวแปรการพิมพ์มากกว่าการดำเนินการฟังก์ชั่น XYZ ...

-h - ช่วยแสดงนิยามธง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.