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

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

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

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


person monch1962    schedule 27.01.2010    source แหล่งที่มา
comment
คุณต้องตั้งค่าตำแหน่งของ rscript ที่สามารถเรียกทำงานได้   -  person    schedule 02.08.2017


คำตอบ (10)


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

ฉันสร้างสองไฟล์: 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>

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

person Marek    schedule 28.01.2010

ไม่กี่จุด:

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

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

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

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

person Dirk Eddelbuettel    schedule 28.01.2010
comment
และมี argparse - person gkcn; 13.08.2013

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

args<-commandArgs(TRUE)

จากนั้นคุณสามารถอ้างถึงข้อโต้แย้งที่ส่งผ่านเป็น args[1], args[2] เป็นต้น

จากนั้นจึงวิ่ง

Rscript myscript.R arg1 arg2 arg3

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

person Hrishi Mittal    schedule 28.01.2010
comment
สิ่งนี้ใช้ได้เฉพาะเมื่อฉันใช้ args‹-commandArgs(TRUE) (สังเกตตัวพิมพ์ใหญ่ A) - person Andy West; 27.04.2012
comment
คุณต้องการ --args ก่อน arg1 หรือไม่ - person philcolbourn; 24.05.2017
comment
@philcolbourn ## - person Chris_Rands; 19.02.2018

ลองใช้ไลบรารี (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();
}
person Erik Aronesty    schedule 27.12.2012

เนื่องจาก 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"

person Megatron    schedule 15.10.2015

คุณต้อง คนตัวเล็ก (ออกเสียงว่า 'little r')

เดิร์กจะใช้เวลาประมาณ 15 นาทีเพื่ออธิบายรายละเอียด ;)

person JD Long    schedule 28.01.2010

ใน 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 สำเร็จ ฯลฯ

person TTW    schedule 09.01.2011

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

person Tim    schedule 09.11.2011
comment
นี่เกือบจะไม่เป็นเช่นนั้นอย่างแน่นอน เฉพาะฟังก์ชันเท่านั้นที่สามารถปกปิดฟังก์ชันได้ การสร้างตัวแปรที่มีชื่อเดียวกันกับฟังก์ชันจะไม่ปิดบังฟังก์ชัน อ้างถึงคำถามและคำตอบนี้: stackoverflow.com/q/6135868/602276 - person Andrie; 09.11.2011
comment
จริงอยู่ที่มันไม่ได้ปกปิดมัน โดยทั่วไป ฉันพยายามหลีกเลี่ยงการตั้งชื่อฟังก์ชันและตัวแปรด้วยชื่อที่มีอยู่แล้วใน R - person Tim; 10.11.2011

หากคุณต้องการระบุตัวเลือกด้วยแฟล็ก (เช่น -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

person TheBinturonGggh    schedule 20.05.2014

ฉันเพิ่งรวบรวมโครงสร้างข้อมูลที่ดีและห่วงโซ่การประมวลผลเพื่อสร้างพฤติกรรมการสลับนี้โดยไม่จำเป็นต้องใช้ไลบรารี ฉันแน่ใจว่ามันจะถูกนำไปใช้หลายครั้งแล้ว และเจอกระทู้นี้เพื่อค้นหาตัวอย่าง - คิดว่าฉันจะเข้าไปช่วย

ฉันไม่ต้องการแฟล็กเป็นพิเศษด้วยซ้ำ (แฟล็กเดียวที่นี่คือโหมดดีบั๊ก โดยสร้างตัวแปรที่ฉันตรวจสอบเป็นเงื่อนไขในการเริ่มต้นฟังก์ชันดาวน์สตรีม 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 Print  variables rather than executing function XYZ...

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