Was ist der beste Weg, um R-Skripte in der Befehlszeile (Terminal) zu verwenden?

114

Es ist sehr praktisch, R-Skripte für einfache Diagramme über die Befehlszeile zu haben. Das Ausführen von R über Bash-Skripte ist jedoch überhaupt nicht bequem. Das Ideal könnte so etwas sein

#!/path/to/R
...

oder

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

aber ich war nicht in der Lage, eine dieser Arbeiten zu machen.

Eine andere Möglichkeit besteht darin, die Skripte z. B. in R zu script.Rbelassen und sie mit R --file=script.Roder ähnlichem aufzurufen . Gelegentlich stützt sich ein Skript jedoch auf undurchsichtige Befehlszeilenoptionen, an denen ein Teil des Codes außerhalb des Skripts vorhanden ist. Beispiel: Wenn Sie Dinge von Bash über ein lokales .R-Profil in R schleichen, sind die gewünschten Schalter dann alles --vanillaaußer --no-init-file.

Eine andere Option ist ein Bash-Skript, um die R-Flags zu speichern und schmerzlos ausführbar zu sein, das dann das R-Skript aufruft. Das Problem ist, dass dies bedeutet, dass ein einzelnes Programm gerade in zwei Dateien aufgeteilt wurde, die jetzt synchron gehalten, zusammen auf neue Computer übertragen werden müssen usw.

Die Option, die ich derzeit am wenigsten verachte, ist das Einbetten des R in ein Bash-Skript:

#!/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

Alles ist in einer einzigen Datei. Es ist ausführbar und kann problemlos mit Argumenten umgehen. Das Problem ist, dass das Kombinieren von Bash und R auf diese Weise die Möglichkeit, dass eine IDE auf der einen oder anderen Seite nicht ausfällt, so gut wie ausschließt und mein Herz sehr weh tut.

Gibt es einen besseren Weg, den ich vermisse?

blahdiblah
quelle

Antworten:

131

Inhalt von script.r:

#!/usr/bin/env Rscript

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

Die erste Zeile ist die Shebang-Zeile . Es wird /usr/bin/env Rscriptempfohlen, den Pfad zu Ihrer R-Installation zu verwenden, anstatt ihn fest zu codieren. Andernfalls besteht die Gefahr, dass Ihr Skript auf anderen Computern beschädigt wird.

Machen Sie es als nächstes ausführbar (in der Befehlszeile):

chmod +x script.r

Aufruf über die Kommandozeile:

./script.r world
# Hello world
Konrad Rudolph
quelle
1
Ja, ich denke, dies ist der "offizielle" Weg, dies zu tun.
Frank
5
Wenn Sie Rscript --helpüber die Befehlszeile ausgeführt werden, werden viele nützliche Optionen aufgelistet, die dem Shebang hinzugefügt werden können, z --vanilla.
Flodel
8
Erwähnen wir auch die commandArgsFunktion und die Pakete getoptund optparsezum Parsen der Befehlszeile. Damit können Argumente und Optionen auch über die Befehlszeile an Ihre Skripte übergeben werden.
Flodel
1
Beachten Sie, dass dies nur funktioniert, wenn #!/usr/bin/Rscript(was nicht die Standardpraxis für R-Skripte ist).
Gented
16

Versuchen Sie es kleiner . littlerBietet Hash-Bang-Funktionen (dh ein Skript, das mit #! / some / path beginnt) für GNU R sowie eine einfache Befehlszeilen- und Piping-Verwendung.

Jouni K. Seppänen
quelle
10

Die Antwort von Miguel Sanchez ist so, wie sie sein sollte. Die andere Möglichkeit, Rscript auszuführen, könnte der Befehl 'env' sein, um das systemweite RScript auszuführen.

#!/usr/bin/env Rscript
The_Cute_Hedgehog
quelle
1
Nicht "systemweit", sondern envwürde es Ihnen ermöglichen, den ersten Rscriptgefundenen in Ihrem eigenen auszuführen $PATH, sodass Sie tatsächlich etwas anderes als einen systemweiten / Standard ausführen Rscriptkönnen (der möglicherweise nicht installiert ist /usr/whatever). Ich würde empfehlen, envfor Rund so zu verwenden Rscript, da diese möglicherweise nicht an Standardorten installiert werden. (Gewöhnliche bashSkripte können jedoch normalerweise immer sicher verwendet werden #!/bin/bash.)
Michael
@ Michael Nein, du liegst falsch in Bezug auf Bash, und das ist ein gefährlicher Rat. Das einzige, was sicher fest codiert werden kann, ist /bin/sh. Alles andere muss envLookup verwenden. Insbesondere ist Bash in Computerclustern häufig veraltet und Benutzer haben ihre eigenen benutzerdefinierten Installationen (üblicherweise in ~/.local/bineinem /softwareNFS-Mount oder in einem solchen gemeinsam genutzt). Ebenso auf macOS, /bin/bashwird immer aus Lizenzgründen veraltet, und ein auf dem Laufenden Bash wird häufiger gelegen an /usr/local/bin/bash(Ich weiß , Ihr Kommentar ist 3 Jahre alt , aber das ist ziemlich wichtig.)
Konrad Rudolph
Nein, sorry, das stimmt einfach nicht. Sie haben jedoch eine starke Meinung zu diesem Thema, daher werde ich das Thema nicht diskutieren. Wenn die Verwendung /bin/shunter keinen Umständen auch "gefährlich" ist, müssen Sie zugeben, dass dies auch der Fall ist /bin/bash. Die Verwendung envist aufgrund zuverlässiger / inkonsistenter PATHEinstellungen für verschiedene Benutzer unvorhersehbarer, aber jeder R-Benutzer möchte dieses Verhalten möglicherweise tatsächlich, während bashSkripte dies nicht tun. Wenn CI / Cloud neuere Bash-Skripte aufruft, rufen Sie sie einfach mit auf /path/to/my/bash myscriptoder legen Sie den Pfad explizit fest und rufen Sie sie mit auf env script. EOT
Michael
9

#!/path/to/Rfunktioniert nicht, weil R selbst ein Skript ist, also execveunglücklich ist.

ich benutze R --slave -f script


quelle
4
Zu Ihrer Information an Gelegenheitsleser: Viele dieser Antworten datieren vor Rscript(und littler), falls Sie sich fragen.
Michael
@michael Keine der Antworten hier ist älter als Rscript, das 2007 mit R 2.5.0 veröffentlicht wurde.
Konrad Rudolph
4

Das funktioniert,

#!/usr/bin/Rscript

Ich weiß jedoch nicht, was passiert, wenn auf Ihrem Computer mehr als eine Version von R installiert ist.

Wenn du es so machst

#!/usr/bin/env Rscript

Es weist den Interpreter an, nur das zu verwenden, was zuerst auf Ihrem Pfad angezeigt wird.

hernamesbarbara
quelle
2

Wenn das Programm, mit dem Sie Ihr Skript ausführen, Parameter benötigt, können Sie diese am Ende des # einfügen! Linie:

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

Da ich R nicht kenne, kann ich nicht richtig testen, aber das scheint zu funktionieren:

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
quelle
2

Nur eine Anmerkung zu diesem Beitrag. Spätere Versionen von Rscheinen Rscriptetwas begraben zu haben . Für R 3.1.2-1 unter OSX heruntergeladen Jan 2015 fand ich Rscriptin

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

Anstelle von so etwas #! /sw/bin/Rscriptmusste ich also oben in meinem Skript Folgendes verwenden.

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

Das locate Rscriptkönnte für Sie hilfreich sein.

John
quelle
Diese Antwort ist möglicherweise hilfreich, da unklar ist, auf welche Plattform (* nix oder Mac OS) sich das OP bezieht. Mit ein wenig Überarbeitung (versuchen Sie, den Code zu formatieren und den entschuldigenden Anfang zu entfernen) wäre dies eine gute Ergänzung zu den Antworten hier.
BenBarnes
2
Dies ist ein weiterer Grund, #!/usr/bin/env Rscriptanstelle eines fest codierten Pfads in RSkripten zu verwenden (und diesen langen Pfad zu Ihrem hinzuzufügen $PATH)
Michael
0

Möglicherweise möchten Sie das rpy2-Modul von Python verwenden. Der "richtige" Weg, dies zu tun, ist jedoch mit R CMD BATCH. Sie können dies ändern, um in STDOUT zu schreiben. Standardmäßig wird jedoch in eine .Rout-Datei geschrieben. Siehe Beispiel unten:

[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

Hinweis: Sie sollten --vanilla und andere Optionen ausprobieren, um alle Start-Cruft zu entfernen.

Ramanujan
quelle
0

Versuchen Sie smallR, um schnelle R-Skripte in die Befehlszeile zu schreiben:

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

( rBefehl im Verzeichnis)

Das Plotten über die Befehlszeile mit smallR würde folgendermaßen aussehen:

r -p file.txt
Tom
quelle
2
Anstatt dies (was tot zu sein scheint), littlerwäre es sicherlich vorzuziehen (da es noch lebt); oder verwenden Sie einfach Rscript(was tatsächlich herauskam, nachdem littleres erstellt wurde.)
michael
-1

Das Folgende funktioniert für mich mit MSYS Bash unter Windows - ich habe kein R auf meiner Linux-Box, kann es dort also nicht ausprobieren. Sie benötigen zwei Dateien - die erste mit dem Namen runr führt R mit einem Dateiparameter aus

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

Sie müssen dies mit chmod + x runr ausführbar machen .

Dann in Ihrer Skriptdatei:

#!runr
# some R commands
x = 1
x

Beachten Sie das #! Die runr-Zeile muss möglicherweise den vollständigen Pfad zu runr enthalten, je nachdem, wie Sie den Befehl verwenden, wie Ihre PATH-Variable festgelegt ist usw.

Nicht schön, aber es scheint zu funktionieren!


quelle
1
Was ist mit verschiedenen R-Skripten, die unterschiedliche Parameter benötigen? Was ist mit der Übergabe von Argumenten an die R-Skripte über die Befehlszeile?
Blahdiblah