J'utilise R CMD BATCH my_script.R
depuis un terminal pour exécuter un script R
. Je suis maintenant sur le point de passer un argument à la commande, mais j'ai du mal à 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 en cours d'exécution.
J'ai essayé Rscript my_script.R blabla
qui semble transmettre correctement l'argument blabla
, mais je ne reçois pas le fichier de sortie my_script.Rout
que je reçois avec R CMD BATCH
(je veux le fichier .Rout
). Bien que je puisse rediriger la sortie d'un appel vers Rscript
vers un nom de fichier de mon choix, je ne recevrais pas les commandes d'entrée R incluses dans le fichier de la même manière que R CMD BATCH
dans le fichier .Rout
.
Donc, idéalement, je recherche un moyen de passer des arguments à un script R exécuté via la méthode R CMD BATCH
, mais serait heureux d’une approche utilisant Rscript
s’il est possible de le faire produire un fichier .Rout
comparable.
Mon impression est que R CMD BATCH
est un peu un relict. Dans tous les cas, l'exécutable Rscript
plus récent (disponible sur toutes les plates-formes), associé à commandArgs()
, facilite le traitement des arguments de ligne de commande.
Par exemple, voici un petit script - appelez-le "myScript.R"
:
## myScript.R
args <- commandArgs(trailingOnly = TRUE)
rnorm(n=as.numeric(args[1]), mean=as.numeric(args[2]))
Et voici à quoi ressemble l'invocation depuis la ligne de commande
> Rscript myScript.R 5 100
[1] 98.46435 100.04626 99.44937 98.52910 100.78853
Modifier:
Non pas que je le recommande, mais ... en combinant les fonctions source()
et sink()
, vous pouvez obtenir Rscript
pour générer un fichier .Rout
similaire à celui produit par R CMD BATCH
. Une solution serait de créer un petit script R - appelez le RscriptEcho.R
- que vous appelez directement avec Rscript. Cela 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 absorbera les entrées, les sorties et les messages entrelacés dans un .Rout
unique.
Edit2:
Vous pouvez exécuter Rscript verbalement et placer la sortie détaillée dans un fichier.
Rscript --verbose myScript.R 5 100 > myScript.Rout
Après avoir essayé les options décrites ici, j’ai trouvé ce message de Forester dans r-bloggers. Je pense que c'est une option propre à considérer.
Je mets son code ici:
Depuis la 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)
Dans test.out
> print(a*2)
[1] 2
> print(b*3)
[1] 6 15 18
Merci à Forester !
Dans votre script R, appelé test.R
:
args <- commandArgs(trailingOnly = F)
myargument <- args[length(args)]
myargument <- sub("-","",myargument)
print(myargument)
q(save="no")
A partir de la ligne de commande, lancez:
R CMD BATCH -4 test.R
Votre fichier de sortie, test.Rout, montrera 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
Vous devez placer les arguments avant my_script.R
et utiliser -
sur les arguments, par exemple.
R CMD BATCH -blabla my_script.R
commandArgs()
recevra -blabla
sous forme de 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.
J'ajoute une réponse car 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=";")))
Puis 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 &
Ensuite:
> ls()
[1] "N" "l" "name"
Voici un autre moyen de traiter les arguments de ligne de commande, en utilisant R CMD BATCH
. Mon approche, qui repose sur une réponse antérieure ici , vous permet de spécifier des arguments sur la ligne de commande et, dans votre script R, de donner à tout ou partie de leurs 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)
Sur 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, par exemple, omettre b
et ajouter un autre argument c
:
R CMD BATCH --no-save --no-restore '--args a=2 c="hello"' test.R
Ensuite, dans R, nous aurons a
= 2
, b
= c(1,1,1)
(valeur par défaut) et c
= "hello"
.
Enfin, pour plus de commodité, nous pouvons inclure le code R dans une fonction, à condition de respecter 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)))