Come posso leggere i parametri della riga di comando da uno script R?


281

Ho uno script R per il quale mi piacerebbe essere in grado di fornire diversi parametri della riga di comando (piuttosto che valori di parametro hardcode nel codice stesso). Lo script funziona su Windows.

Non riesco a trovare informazioni su come leggere i parametri forniti dalla riga di comando nel mio script R. Sarei sorpreso se non fosse possibile, quindi forse non sto usando le migliori parole chiave nella mia ricerca su Google ...

Qualche puntatore o raccomandazione?


devi impostare la posizione dell'eseguibile rscript

Risposte:


209

La risposta di Dirk qui è tutto ciò di cui hai bisogno. Ecco un esempio riproducibile minimo.

Ho creato due file: exmpl.bate 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

    In alternativa, usando 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)

Salvare entrambi i file nella stessa directory e avviare exmpl.bat. Nel risultato otterrai:

  • example.png con qualche trama
  • exmpl.batch con tutto ciò che è stato fatto

È inoltre possibile aggiungere una variabile di ambiente %R_Script%:

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

e utilizzarlo negli script batch come %R_Script% <filename.r> <arguments>

Differenze tra RScripte Rterm:


127

Alcuni punti:

  1. I parametri della riga di comando sono accessibili tramite commandArgs(), quindi vedere help(commandArgs)per una panoramica.

  2. È possibile utilizzare Rscript.exesu tutte le piattaforme, incluso Windows. Supporterà commandArgs(). littler potrebbe essere portato su Windows, ma attualmente vive solo su OS X e Linux.

  3. Esistono due pacchetti aggiuntivi su CRAN - getopt e optparse - entrambi scritti per l'analisi da riga di comando.

Modifica nel novembre 2015: nuove alternative sono apparsi e io con tutto il cuore raccomandare docopt .


2
e c'è argparse
gkcn il

92

Aggiungi questo nella parte superiore del tuo script:

args<-commandArgs(TRUE)

Quindi è possibile fare riferimento agli argomenti passati come args[1], args[2]ecc.

Quindi corri

Rscript myscript.R arg1 arg2 arg3

Se i tuoi arg sono stringhe con spazi, racchiudili tra virgolette doppie.


7
Questo ha funzionato solo quando ho usato args <-commandArgs (TRUE) (notare la A maiuscola).
Andy West,

ti serve --args prima di arg1?
philcolbourn,

@philcolbourn No
Chris_Rands

15

Prova la libreria (getopt) ... se vuoi che le cose siano più belle. Per esempio:

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

Dato che optparseè stato citato un paio di volte nelle risposte e fornisce un kit completo per l'elaborazione da riga di comando, ecco un breve esempio semplificato di come puoi usarlo, supponendo che il file di input esista:

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

Dato un file arbitrario blah.txtcon 23 righe.

Sulla riga di comando:

Rscript script.R -h uscite

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

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


7

In bash, puoi costruire una riga di comando come la seguente:

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

Puoi vedere che la variabile $zè sostituita dalla shell bash con "10" e questo valore viene raccolto commandArgse inserito in args[2], e il comando range x=1:10eseguito da R con successo, ecc. Ecc.


4

Cordiali saluti: esiste una funzione args (), che recupera gli argomenti delle funzioni R, da non confondere con un vettore di argomenti chiamato args


1
Questo non è quasi certamente il caso. Solo le funzioni possono mascherare le funzioni. La creazione di una variabile con lo stesso nome di una funzione non maschera la funzione. Fare riferimento a questa domanda e risposte: stackoverflow.com/q/6135868/602276
Andrie

È vero, non lo maschera. In generale, cerco di evitare le funzioni di denominazione e le variabili con nomi già esistenti in R.
Tim


1

Ho appena creato una bella struttura di dati e una catena di elaborazione per generare questo comportamento di commutazione, senza bisogno di librerie. Sono sicuro che sarà stato implementato numerose volte e ho trovato questo thread in cerca di esempi - ho pensato di fare un chip.

In particolare non avevo nemmeno bisogno di flag (l'unico flag qui è una modalità di debug, che crea una variabile che controllo come condizione per l'avvio di una funzione downstream if (!exists(debug.mode)) {...} else {print(variables)}). Le lapplyistruzioni di controllo flag di seguito producono lo stesso di:

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

dove argsè la variabile letta dagli argomenti della riga di comando (un vettore di caratteri, equivalente a c('--debug','--help')quando li fornisci ad esempio)

È riutilizzabile per qualsiasi altra bandiera e si evita tutta la ripetizione e nessuna libreria quindi nessuna dipendenza:

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

Si noti che flag.detailsqui i comandi vengono memorizzati come stringhe, quindi valutati con eval(parse(text = '...')). Optparse è ovviamente desiderabile per qualsiasi script serio, ma a volte il codice con funzionalità minime è buono.

Uscita campione:

$ Rscript check_mail.Rscript --help
--debug Stampa le variabili anziché eseguire la funzione XYZ ...

-h --help Visualizza le definizioni dei flag
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.