Passer les arguments de ligne de commande au lot CMD

j'ai utilisé R CMD BATCH my_script.R depuis un terminal pour exécuter un script R . J'en suis maintenant au point où j'aimerais présenter un argument au commandement, mais j'ai quelques difficultés à le faire fonctionner. Si je fais R CMD BATCH my_script.R blabla alors blabla devient le fichier de sortie, plutôt que d'être interprété comme un argument disponible pour le script R exécuté.

j'ai essayé Rscript my_script.R blabla qui semble transmettre blabla correctement comme argument, mais je n'obtiens pas le fichier de sortie my_script.Rout que j'obtiens avec R CMD BATCH (je veux le fichier .Rout ). Bien que je puisse rediriger la sortie d'un appel à Rscript vers un nom de fichier de mon choix, Je ne recevrais pas les commandes d'entrée R incluses dans le fichier comme R CMD BATCH le fait dans le fichier .Rout .

donc, idéalement, je suis après un moyen de passer des arguments à un script R exécuté via la méthode R CMD BATCH , bien que je serais heureux avec un approche utilisant Rscript s'il existe un moyen de le faire produire un fichier .Rout comparable.

84
demandé sur Bryce Thomas 2013-01-05 04:26:56

6 réponses

Mon impression est que R CMD BATCH est un peu une relique. Dans tous les cas, l'exécutable Rscript plus récent (disponible sur toutes les plateformes), avec commandArgs() rend le traitement des arguments en ligne de commande assez facile.

à titre d'exemple, voici un petit script -- l'appeler "myScript.R" :

## myScript.R
args <- commandArgs(trailingOnly = TRUE)
rnorm(n=as.numeric(args[1]), mean=as.numeric(args[2]))

et voici à quoi ressemble le fait de l'invoquer depuis la ligne de commande

> Rscript myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

Edit:

ce n'est pas que je le recommande, mais ... en utilisant une combinaison de source() et sink() , vous pourriez obtenir Rscript pour produire un fichier .Rout comme celui produit par R CMD BATCH . Une façon serait de créer un petit script R -- appeler it RscriptEcho.R -- que vous appelez directement avec Rscript. Il pourrait ressembler à ceci:

## RscriptEcho.R
args <- commandArgs(TRUE)
srcFile <- args[1]
outFile <- paste0(make.names(date()), ".Rout")
args <- args[-1]

sink(outFile, split = TRUE)
source(srcFile, echo = TRUE)

pour exécuter votre script actuel, vous feriez alors:

Rscript RscriptEcho.R myScript.R 5 100
[1]  98.46435 100.04626  99.44937  98.52910 100.78853

qui exécutera myScript.R avec les arguments fournis et coulera intercalé entrées, sorties, et messages à un unique nommé .Rout .

Edit 2:

Vous pouvez exécuter rscript verbosely et placer la sortie verbose dans un fichier.

Rscript --verbose myScript.R 5 100 > myScript.Rout
90
répondu Josh O'Brien 2018-03-06 13:39:40

après avoir essayé les options décrites ici, j'ai trouvé ce post de forestier dans R-blogueurs . Je pense que c'est une option propre à envisager.

j'ai mis son code ici:

ligne De commande

$ R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)' test.R test.out &

Test.R

##First read in the arguments listed at the command line
args=(commandArgs(TRUE))

##args is now a list of character vectors
## First check to see if arguments are passed.
## Then cycle through each element of the list and evaluate the expressions.
if(length(args)==0){
    print("No arguments supplied.")
    ##supply default values
    a = 1
    b = c(1,1,1)
}else{
    for(i in 1:length(args)){
      eval(parse(text=args[[i]]))
    }
}

print(a*2)
print(b*3)

en essai.out

> print(a*2)
[1] 2
> print(b*3)
[1]  6 15 18

Merci à forestier !

21
répondu Alex A. 2013-11-26 12:41:42

dans votre script R, appelé test.R :

args <- commandArgs(trailingOnly = F)
myargument <- args[length(args)]
myargument <- sub("-","",myargument)
print(myargument)
q(save="no")

à partir de la ligne de commande:

R CMD BATCH -4 test.R

votre fichier de sortie, test.Rout, va montrer que l'argument 4 a été passé avec succès à R:

cat test.Rout

> args <- commandArgs(trailingOnly = F)
> myargument <- args[length(args)]
> myargument <- sub("-","",myargument)
> print(myargument)
[1] "4"
> q(save="no")
> proc.time()
user  system elapsed 
0.222   0.022   0.236 
9
répondu user1563570 2017-03-27 21:21:24

vous devez mettre les arguments avant my_script.R et utiliser - sur les arguments, par exemple

R CMD BATCH -blabla my_script.R

commandArgs() recevra -blabla comme chaîne de caractères dans ce cas. Voir l'aide pour plus de détails:

$ R CMD BATCH --help
Usage: R CMD BATCH [options] infile [outfile]

Run R non-interactively with input from infile and place output (stdout
and stderr) to another file.  If not given, the name of the output file
is the one of the input file, with a possible '.R' extension stripped,
and '.Rout' appended.

Options:
  -h, --help        print short help message and exit
  -v, --version     print version info and exit
  --no-timing           do not report the timings
  --            end processing of options

Further arguments starting with a '-' are considered as options as long
as '--' was not encountered, and are passed on to the R process, which
by default is started with '--restore --save --no-readline'.
See also help('BATCH') inside R.
8
répondu Yihui Xie 2013-01-05 00:42:05

j'ajoute une réponse parce que je pense qu'une solution d'une ligne est toujours bonne! Au sommet de votre fichier myRscript.R , ajoutez la ligne suivante:

eval(parse(text=paste(commandArgs(trailingOnly = TRUE), collapse=";")))

alors soumettez votre script avec quelque chose comme:

R CMD BATCH [options] '--args arguments you want to supply' myRscript.R &

par exemple:

R CMD BATCH --vanilla '--args N=1 l=list(a=2, b="test") name="aname"' myscript.R &

puis:

> ls()
[1] "N"    "l"    "name"
3
répondu clemlaflemme 2016-10-07 11:50:22

Voici une autre façon de traiter la ligne de commande args, en utilisant R CMD BATCH . Mon approche, qui s'appuie sur une réponse précédente ici , vous permet de spécifier des arguments à la ligne de commande et, dans votre script R, de donner certaines ou toutes les valeurs par défaut.

voici un fichier R, que je nomme test.R :

defaults <- list(a=1, b=c(1,1,1)) ## default values of any arguments we might pass

## parse each command arg, loading it into global environment
for (arg in commandArgs(TRUE))
  eval(parse(text=arg))

## if any variable named in defaults doesn't exist, then create it
## with value from defaults
for (nm in names(defaults))
  assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]))[[1]])

print(a)
print(b)

à la ligne de commande, si je tape

R CMD BATCH --no-save --no-restore '--args a=2 b=c(2,5,6)' test.R

alors dans R Nous aurons a = 2 et b = c(2,5,6) . Mais je pourrais, dire, omettre b , et ajouter dans un autre argument c :

R CMD BATCH --no-save --no-restore '--args a=2 c="hello"' test.R

alors en R Nous aurons a = 2 , b = c(1,1,1) (the default), et c = "hello" .

enfin, pour plus de commodité, nous pouvons envelopper le code R dans une fonction, aussi longtemps que nous faisons attention à l'environnement:

## defaults should be either NULL or a named list
parseCommandArgs <- function(defaults=NULL, envir=globalenv()) {
  for (arg in commandArgs(TRUE))
    eval(parse(text=arg), envir=envir)

  for (nm in names(defaults))
    assign(nm, mget(nm, ifnotfound=list(defaults[[nm]]), envir=envir)[[1]], pos=envir)
}

## example usage:
parseCommandArgs(list(a=1, b=c(1,1,1)))
0
répondu Dagremu 2017-05-23 11:46:22