2010-01-27 4 views
257

Ich habe ein R-Skript, für das ich mehrere Befehlszeilenparameter bereitstellen könnte (anstelle von Hardcode-Parameterwerten im Code selbst). Das Skript läuft unter Windows.Wie kann ich Befehlszeilenparameter von einem R-Skript lesen?

Ich kann keine Informationen darüber finden, wie Parameter in der Befehlszeile in mein R-Skript eingelesen werden. Ich wäre überrascht, wenn es nicht möglich ist, also verwende ich vielleicht nicht die besten Keywords in meiner Google-Suche ...

Irgendwelche Hinweise oder Empfehlungen?

+0

müssen Sie den Speicherort von rscript ausführbar –

Antwort

189

Dirk's answer here ist alles, was Sie brauchen. Hier ist ein minimal reproduzierbares Beispiel.

Ich habe zwei Dateien erstellt: exmpl.bat und 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 
    

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

Speichern Sie beide Dateien im selben Verzeichnis und starten Sie exmpl.bat.Im Ergebnis erhalten Sie:

  • example.png mit einigen Grundstück
  • exmpl.batch mit allem, was

Sie getan wurde auch eine Umgebungsvariable %R_Script% könnte hinzufügen:

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

und Verwenden Sie es in Ihren Batch-Skripts als %R_Script% <filename.r> <arguments>

Unterschiede zwischen RScript und Rterm:

8

Sie littler müssen ('kleine r' ausgesprochen)

Dirk wird in etwa 15 Minuten von auszuarbeiten;)

+23

Ich war sieben Minuten zu spät. Es muss ein schlechter Verkehr auf den Intertubes stattgefunden haben. –

+2

entweder das oder du wirst alt. ;) –

+2

Ich habe seine Frage eindeutig nicht gut gelesen. -1 für mich die Windows-Anforderung –

114

Einige Punkte:

  1. Befehlszeilenparameter sind zugänglich über commandArgs(), so siehe help(commandArgs) für eine Übersicht.

  2. Sie können Rscript.exe auf allen Plattformen einschließlich Windows verwenden. Es unterstützt commandArgs(). littler könnte nach Windows portiert werden, aber lebt nur noch auf OS X und Linux.

  3. Es gibt zwei Add-on-Pakete auf CRAN - getopt und optparse - die beide für das Kommandozeilen-Parsing geschrieben wurden.

Bearbeiten im November 2015: Neue Alternativen erschienen und ich von ganzem Herzen empfehlendoctopt.

+8

+1 für den Zeiger auf das 'optparse'-Paket nicht sehen. – reprogrammer

+2

und es gibt [argparse] (http://cran.r-project.org/web/packages/argparse/index.html) – gkcn

79

Fügen Sie dies an den Anfang Ihres Skripts:

args<-commandArgs(TRUE) 

Dann können Sie den als args[1] gebenen Argumente beziehen, args[2] usw.

Dann

Rscript myscript.R arg1 arg2 arg3 

laufen Wenn Ihr args Strings mit Leerzeichen in ihnen sind, schließen in doppelten Anführungszeichen.

+7

Das funktionierte nur, wenn ich args <-commandArgs (TRUE) verwendete (beachten Sie den Großbuchstaben A) . –

+0

brauchst du --args vor arg1? – philcolbourn

+0

@philcolbourn No –

4

In bash können Sie eine Befehlszeile wie das Konstrukt folgendes:

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

Sie können sehen, dass die Variable $z von Bash-Shell mit „10“ ersetzt wird und dieser Wert gepflückt wird von commandArgs und fed in args[2], und der Bereich von R Befehl x=1:10 erfolgreich ausgeführt, etc etc.

3

FYI: args es eine Funktion() ist, die die Argumente von R Funktionen abruft, die mit einem Vektor der Argumente genannt args nicht zu verwechseln

+1

Dies ist fast sicher nicht der Fall. Nur Funktionen können Funktionen maskieren. Das Erstellen einer Variablen mit demselben Namen wie eine Funktion maskiert die Funktion nicht. Beziehen Sie sich auf diese Frage und Antworten: http://stackoverflow.com/q/6135868/602276 – Andrie

+0

Wahr, es maskiert es nicht. Im Allgemeinen versuche ich zu vermeiden, Funktionen und Variablen mit Namen zu benennen, die bereits in R existieren. – Tim

12

Probieren Sie Bibliothek (getopt) ... wenn Sie wollen, dass die Dinge schöner sind. Zum Beispiel:

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(); 
} 
0

Wenn Sie Optionen mit Flags angeben müssen, (wie -h, --help, --number = 42, usw.) können Sie den R-Paket optparse verwenden können (von Python inspiriert): http://cran.r-project.org/web/packages/optparse/vignettes/optparse.pdf.

Zumindest das, wie ich Ihre Frage verstehe, denn ich fand diesen Beitrag bei der Suche nach einem Äquivalent der Bash getopt, oder perl getopt, oder python argparse und optparse.

0

ich gerade zusammen eine schöne Datenstruktur und die Kette der Verarbeitung dieses Schaltverhalten zu erzeugen, benötigt keine Bibliotheken. Ich bin mir sicher, dass es viele Male umgesetzt worden sein wird, und stieß auf diesen Thread auf der Suche nach Beispielen - dachte, ich würde einspringen.

Ich brauchte nicht einmal besonders Flags (das einzige Flag hier ist ein Debug-Modus, Erstellen einer Variablen, die ich als Bedingung für den Start einer Downstream-Funktion if (!exists(debug.mode)) {...} else {print(variables)}) überprüfen. Die Flag Überprüfung lapply Aussagen unten produzieren das gleiche wie:

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

wo args ist die Variable in von Befehlszeilenargumenten lesen

Es ist wieder verwendbar für andere flag (eine Zeichenvektor entspricht c('--debug','--help') wenn man diese auf etwa liefern), und Sie vermeiden alle Wiederholungs , und keine Bibliotheken, so dass keine Abhängigkeiten:

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

Beachten Sie, dass in flag.details hier die Befehle als Strings gespeichert, dann mit eval(parse(text = '...')) ausgewertet. OptParse ist offensichtlich für jedes seriöse Skript wünschenswert, aber auch Code mit minimaler Funktionalität ist manchmal gut.

Beispielausgabe:

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

-h --help Display flag definitions
6

Seit optparse hat ein paar Mal in den Antworten erwähnt, und es bietet eine umfassende Kit für die Verarbeitung Kommandozeile, hier ist ein kurzes vereinfachtes Beispiel dafür, wie Sie es verwenden können, die Eingabedatei unter der Annahme besteht:

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

Gegeben eine Datei blah.txt mit 23 Zeilen.

in der Befehlszeile:

Rscript script.R -hAusgänge

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.txtAusgänge[1] "69"

Rscript script.R -n -f 5 blah.txtAusgänge[1] "115"

Verwandte Themen