Quelle est la meilleure façon d'utiliser les scripts R sur la ligne de commande (terminal)?

115

Il est très pratique d'avoir des scripts R pour faire des graphiques simples à partir de la ligne de commande. Cependant, exécuter R à partir de scripts bash n'est pas du tout pratique. L'idéal pourrait être quelque chose comme

#!/path/to/R
...

ou

#!/usr/bin/env R
...

mais je n'ai pas réussi à faire fonctionner l'un ou l'autre de ces éléments.

Une autre option consiste à conserver les scripts uniquement dans R, par exemple script.R, et à les invoquer avec R --file=script.Rou similaire. Cependant, parfois, un script s'appuiera sur des commutateurs de ligne de commande obscurs à quel point une partie du code existe en dehors du script. Exemple: en glissant des choses dans R à partir de bash via un profil .R local, les commutateurs souhaités sont alors tout ce que cela --vanillaimplique sauf --no-init-file.

Une autre option est un script bash pour stocker les indicateurs R et être exécutable sans douleur, qui appelle ensuite le script R. Le problème est que cela signifie qu'un seul programme vient d'être divisé en deux fichiers qui doivent maintenant être synchronisés, transférés ensemble sur de nouvelles machines, etc.

L'option que je méprise le moins actuellement consiste à intégrer le R dans un script bash:

#!/bin/bash
... # usage message to catch bad input without invoking R
... # any bash pre-processing of input
... # etc
R --random-flags <<RSCRIPT
# R code goes here
RSCRIPT

Tout est dans un seul fichier. Il est exécutable et gère facilement les arguments. Le problème est que combiner bash et R comme ça élimine à peu près la possibilité que n'importe quel IDE n'échoue pas sur l'un ou l'autre, et me fait vraiment mal au cœur.

Y a-t-il une meilleure façon de me manquer?

blahdiblah
la source

Réponses:

132

Contenu de script.r:

#!/usr/bin/env Rscript

args = commandArgs(trailingOnly = TRUE)
message(sprintf("Hello %s", args[1L]))

La première ligne est la ligne shebang . Il est recommandé d'utiliser /usr/bin/env Rscriptau lieu de coder en dur le chemin d'accès à votre installation R. Sinon, vous risquez de casser votre script sur d'autres ordinateurs.

Ensuite, rendez-le exécutable (sur la ligne de commande):

chmod +x script.r

Appel depuis la ligne de commande:

./script.r world
# Hello world
Konrad Rudolph
la source
1
Oui, je pense que c'est la manière «officielle» de le faire.
Frank
5
Et courir à Rscript --helppartir de la ligne de commande listera de nombreuses options utiles qui peuvent être ajoutées au shebang, telles que --vanilla.
flodel
8
Mentionnons également la commandArgsfonction et les packages getoptet optparsepour analyser la ligne de commande. Pour que les arguments et les options puissent également être transmis à vos scripts lors de l'exécution à partir de la ligne de commande.
flodel
1
Notez que cela ne fonctionne que si #!/usr/bin/Rscript(ce qui n'est pas la pratique standard pour les scripts R).
gented
16

Essayez plus petit . littlerfournit une capacité de hachage (c'est-à-dire un script commençant par #! / some / path) pour GNU R, ainsi qu'une utilisation simple de la ligne de commande et du piping.

Jouni K. Seppänen
la source
10

La réponse de Miguel Sanchez est ce qu'elle devrait être. L'autre façon d'exécuter Rscript pourrait être la commande 'env' pour exécuter RScript à l'échelle du système.

#!/usr/bin/env Rscript
The_Cute_Hedgehog
la source
1
Pas "à l'échelle du système", mais envvous permettrait plutôt d'exécuter le premier Rscripttrouvé dans le vôtre $PATH, permettant ainsi à quelqu'un d'exécuter réellement autre chose qu'un système par défaut Rscript(qui ne peut pas être installé /usr/whatever). Je recommanderais d'utiliser envfor Rand Rscriptstuff, car ceux-ci en particulier peuvent ne pas être installés dans des endroits standard. (Les bashscripts ordinaires peuvent cependant toujours être utilisés en toute sécurité #!/bin/bash.)
michael
@michael Non, vous vous trompez concernant Bash, et c'est un conseil dangereux. La seule chose qui peut être codée en dur en toute sécurité est /bin/sh. Tout le reste doit utiliser la envrecherche. En particulier, le plus souvent, Bash est obsolète sur les clusters de calcul et les utilisateurs ont leurs propres installations personnalisées (généralement dans ~/.local/bin, ou partagées dans quelque chose comme un /softwaremontage NFS). De même, sur macOS, /bin/bashest toujours obsolète en raison de problèmes de licence, et un Bash à jour est plus couramment situé à /usr/local/bin/bash(je me rends compte que votre commentaire a 3 ans mais c'est assez important.)
Konrad Rudolph
Non, désolé, ce n'est tout simplement pas vrai. Vous avez cependant une forte opinion sur la question, je ne vais donc pas en débattre. Si l'utilisation /bin/shn'est, en aucun cas, également "dangereuse", alors vous devez admettre que l'on pourrait en dire autant /bin/bash. L'utilisation envest plus imprévisible, en raison de PATHparamètres fiables / incohérents pour différents utilisateurs, mais chaque utilisateur R peut en fait vouloir ce comportement, contrairement aux bashscripts. Enfin, pour CI / cloud invoquant des scripts bash plus récents, appelez-les simplement en utilisant /path/to/my/bash myscriptou définissez explicitement le chemin et appelez-les en utilisant env script. EOT
michael
9

#!/path/to/Rne fonctionnera pas car R est lui-même un script, donc execvemalheureux.

j'utilise R --slave -f script


la source
4
Fyi aux lecteurs occasionnels: beaucoup de ces réponses sont antérieures Rscript(et littler), au cas où vous vous poseriez la question.
michael
@michael Aucune des réponses ici n'est antérieure à Rscript, qui a été publié en 2007 avec R 2.5.0.
Konrad Rudolph
4

Cela marche,

#!/usr/bin/Rscript

mais je ne sais pas ce qui se passe si vous avez plus d'une version de R installée sur votre machine.

Si tu le fais comme ça

#!/usr/bin/env Rscript

il dit à l'interpréteur d'utiliser simplement ce que R apparaît en premier sur votre chemin.

hernamesbarbara
la source
2

Si le programme que vous utilisez pour exécuter votre script a besoin de paramètres, vous pouvez les mettre à la fin du #! ligne:

#!/usr/bin/R --random --switches --f

Ne connaissant pas R, je ne peux pas tester correctement, mais cela semble fonctionner:

axa@artemis:~$ cat r.test
#!/usr/bin/R -q -f
error
axa@artemis:~$ ./r.test
> #!/usr/bin/R -q -f
> error
Error: object "error" not found
Execution halted
axa@artemis:~$
Andrew Aylett
la source
2

Juste une note à ajouter à ce post. Les versions ultérieures de Rsemblent avoir Rscriptquelque peu enterré . Pour R 3.1.2-1 sur OSX téléchargé en janvier 2015, j'ai trouvé Rscriptdans

/sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

Donc, au lieu de quelque chose comme #! /sw/bin/Rscript, j'avais besoin d'utiliser ce qui suit en haut de mon script.

#! /sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

Cela locate Rscriptpourrait vous être utile.

John
la source
Cette réponse est potentiellement utile, car on ne sait pas à quelle plate-forme (* nix ou Mac OS) le PO se réfère. Avec un peu de retravail (cherchez à formater le code et supprimez le début d'excuse), ce serait un bon ajout aux réponses ici.
BenBarnes
2
C'est une autre raison d'utiliser #!/usr/bin/env Rscriptau lieu d'un chemin d'accès codé en dur dans les Rscripts (et d'ajouter ce long chemin à votre $PATH)
Michael
0

Vous voudrez peut-être utiliser le module rpy2 de python. Cependant, la «bonne» façon de procéder est d'utiliser R CMD BATCH. Vous pouvez le modifier pour écrire dans STDOUT, mais la valeur par défaut est d'écrire dans un fichier .Rout. Voir l'exemple ci-dessous:

[ramanujan:~]$cat foo.R
print(rnorm(10))
[ramanujan:~]$R CMD BATCH foo.R
[ramanujan:~]$cat foo.Rout

R version 2.7.2 (2008-08-25)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

[Previously saved workspace restored]


 ~/.Rprofile loaded.
Welcome at  Fri Apr 17 13:33:17 2009
> print(rnorm(10))
 [1]  1.5891276  1.1219071 -0.6110963  0.1579430 -0.3104579  1.0072677 -0.1303165  0.6998849  1.9918643 -1.2390156
>

Goodbye at  Fri Apr 17 13:33:17 2009
> proc.time()
   user  system elapsed
  0.614   0.050   0.721

Remarque: vous voudrez essayer les options --vanilla et d'autres pour supprimer toutes les erreurs de démarrage.

ramanujan
la source
0

Essayez smallR pour écrire des scripts R rapides dans la ligne de commande:

http://code.google.com/p/simple-r/

( rcommande dans le répertoire)

Le traçage à partir de la ligne de commande en utilisant smallR ressemblerait à ceci:

r -p file.txt
À M
la source
2
Plutôt que cela (qui semble mort), littlerserait certainement préféré (puisqu'il est toujours vivant); ou, utilisez simplement Rscript(qui est sorti après littlersa création.)
michael
-1

Ce qui suit fonctionne pour moi en utilisant MSYS bash sur Windows - je n'ai pas R sur ma machine Linux, je ne peux donc pas l'essayer là-bas. Vous avez besoin de deux fichiers - le premier appelé runr exécute R avec un paramètre de fichier

# this is runr
# following is path to R on my Windows machine
# plus any R params you need
c:/r/bin/r --file=$1

Vous devez rendre cet exécutable avec chmod + x runr .

Puis dans votre fichier script:

#!runr
# some R commands
x = 1
x

Noter la #! La ligne runr peut avoir besoin d'inclure le chemin complet de runr, selon la façon dont vous utilisez la commande, la façon dont votre variable PATH est définie, etc.

Pas joli, mais ça a l'air de marcher!


la source
1
Qu'en est-il des différents scripts R nécessitant des paramètres différents? Qu'en est-il du passage d'arguments aux scripts R à partir de la ligne de commande?
blahdiblah