web-dev-qa-db-fra.com

Comment puis-je lire les paramètres de ligne de commande à partir d'un script R?

J'ai un script R pour lequel j'aimerais pouvoir fournir plusieurs paramètres de ligne de commande (plutôt que des valeurs de paramètres codées dans le code lui-même). Le script s'exécute sous Windows.

Je ne trouve pas d'informations sur la façon de lire les paramètres fournis sur la ligne de commande dans mon script R. Je serais surpris que cela ne puisse pas être fait, alors peut-être que je n'utilise tout simplement pas les meilleurs mots-clés dans ma recherche sur Google ...

Des pointeurs ou des recommandations?

272
monch1962

La réponse de Dirk ici , c'est tout ce dont vous avez besoin. Voici un exemple reproductible minimal.

J'ai créé deux fichiers: exmpl.bat et 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
    

    Vous pouvez également utiliser 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)
    

Enregistrez les deux fichiers dans le même répertoire et démarrez exmpl.bat. Au résultat, vous obtiendrez:

  • example.png avec un complot
  • exmpl.batch avec tout ce qui a été fait

Vous pouvez également ajouter une variable d'environnement %R_Script%:

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

et utilisez-le dans vos scripts batch en tant que %R_Script% <filename.r> <arguments>

Différences entre RScript et Rterm:

  • Rscript a une syntaxe plus simple
  • Rscript choisit automatiquement l'architecture sur x64 (voir R Installation et administration, 2.6 Sous-architectures pour plus de détails)
  • Rscript a besoin de options(echo=TRUE) dans le fichier .R si vous souhaitez écrire les commandes dans le fichier de sortie.
205
Marek

Quelques points:

  1. Les paramètres de ligne de commande sont accessibles via commandArgs(). Pour plus d'informations, reportez-vous à help(commandArgs).

  2. Vous pouvez utiliser Rscript.exe sur toutes les plateformes, y compris Windows. Il supportera commandArgs(). littler pourrait être porté sur Windows mais ne vit actuellement que sur OS X et Linux.

  3. Il existe deux packages add-on sur CRAN - getopt et optparse - qui ont tous deux été écrits pour l'analyse en ligne de commande.

Éditer en novembre 2015: De nouvelles alternatives sont apparues et je sans réserve recommande - docopt .

123
Dirk Eddelbuettel

Ajoutez ceci en haut de votre script:

args<-commandArgs(TRUE)

Ensuite, vous pouvez vous référer aux arguments passés en tant que args[1], args[2] etc.

Puis courir

Rscript myscript.R arg1 arg2 arg3

Si vos arguments sont des chaînes contenant des espaces, mettez-les entre guillemets.

90
Hrishi Mittal

Essayez la bibliothèque (getopt) ... si vous voulez que les choses soient plus agréables. Par exemple:

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();
}
15
Erik Aronesty

Comme optparse a été mentionné à plusieurs reprises dans les réponses et qu'il fournit un kit complet pour le traitement en ligne de commande, voici un court exemple simplifié de la façon dont vous pouvez l'utiliser, en supposant que le fichier d'entrée existe:

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

Étant donné un fichier arbitraire blah.txt avec 23 lignes.

Sur la ligne de commande:

Rscript script.R -h renvoie

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 génère [1] "69"

Rscript script.R -n -f 5 blah.txt génère [1] "115"

11
Megatron

vous avez besoin de littler (prononcez 'petit r')

Dirk sera dans environ 15 minutes pour élaborer;)

10
JD Long

Dans bash, vous pouvez construire une ligne de commande comme suit:

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

Vous pouvez voir que la variable $z est remplacée par bash Shell par "10" et que cette valeur est reprise par commandArgs et introduite dans args[2], et la commande de plage x=1:10 exécuté par R avec succès, etc. etc.

6
TTW

Pour votre information: il existe une fonction args (), qui récupère les arguments des fonctions R, à ne pas confondre avec un vecteur d'arguments nommé args

4
Tim

Je viens de mettre en place une structure de données Nice et une chaîne de traitement pour générer ce comportement de commutation, aucune bibliothèque nécessaire. Je suis sûr qu'il aura été implémenté de nombreuses fois et que je suis tombé sur ce fil à la recherche d'exemples - pensais que je pourrais participer.

Je n'avais même pas particulièrement besoin de drapeaux (le seul drapeau ici est un mode de débogage, créant une variable que je vérifie comme condition pour démarrer une fonction en aval if (!exists(debug.mode)) {...} else {print(variables)}). Le drapeau vérifiant lapply les instructions ci-dessous produisent le même que:

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

args est la variable lue à partir des arguments de la ligne de commande (un vecteur de caractère équivalent à c('--debug','--help') lorsque vous les indiquez, par exemple).

Il est réutilisable pour tout autre drapeau et vous évitez toute répétition, et aucune bibliothèque, donc aucune dépendance:

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

Notez que dans flag.details ici, les commandes sont stockées sous forme de chaînes, puis évaluées avec eval(parse(text = '...')). Optparse est évidemment souhaitable pour tout script sérieux, mais le code à fonctionnalité minimale est bon aussi parfois.

Exemple de sortie:

 $  Rscript  check_mail.Rscript  --help 
 - Déboguer des variables d’impression plutôt que d’exécuter la fonction XYZ .. . 
 
 - h --help Afficher les définitions des drapeaux
0
Louis Maddox

Si vous devez spécifier des options avec des indicateurs (tels que -h, --help, --number = 42, etc.), vous pouvez utiliser le package R optparse (inspiré de Python): http: //cran.r -project.org/web/packages/optparse/vignettes/optparse.pdf .

Au moins, voici comment je comprends votre question, car j’ai trouvé cet article en cherchant un équivalent de bash getopt, ou Perl Getopt, ou python argparse et optparse.

0
TheBinturonGggh