¿Cuál es la mejor manera de usar scripts R en la línea de comando (terminal)?

115

Es muy conveniente tener scripts en R para realizar trazados simples desde la línea de comandos. Sin embargo, ejecutar R desde scripts bash no es nada conveniente. El ideal podría ser algo como

#!/path/to/R
...

o

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

pero no he podido hacer que ninguno de esos funcione.

Otra opción es mantener los scripts puramente en R, por ejemplo script.R, e invocarlos con R --file=script.Ro similar. Sin embargo, ocasionalmente un script se basará en cambios de línea de comando oscuros en cuyo punto parte del código existe fuera del script. Ejemplo: infiltrar cosas en R desde bash a través de un .Rprofile local, los interruptores deseados son entonces todo --vanillaimplica excepto --no-init-file.

Otra opción es un script bash para almacenar los indicadores R y ser ejecutable sin dolor, que luego llama al script R. El problema es que esto significa que un solo programa acaba de dividirse en dos archivos que ahora deben mantenerse sincronizados, transferidos a nuevas máquinas juntos, etc.

La opción que menos desprecio actualmente es incrustar la R en 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

Todo está en un solo archivo. Es ejecutable y maneja argumentos fácilmente. El problema es que combinar bash y R de esta manera elimina prácticamente la posibilidad de que cualquier IDE no falle en uno u otro, y hace que mi corazón duela mucho.

¿Hay alguna forma mejor que me esté perdiendo?

blahdiblah
fuente

Respuestas:

132

Contenido de script.r:

#!/usr/bin/env Rscript

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

La primera línea es la línea shebang . Es una buena práctica usar en /usr/bin/env Rscriptlugar de codificar la ruta a su instalación de R. De lo contrario, corre el riesgo de que su script se rompa en otras computadoras.

A continuación, hágalo ejecutable (en la línea de comando):

chmod +x script.r

Invocación desde la línea de comando:

./script.r world
# Hello world
Konrad Rudolph
fuente
1
Sí, creo que esta es la forma "oficial" de hacerlo.
Frank
5
Y al ejecutar Rscript --helpdesde la línea de comando, se enumerarán muchas opciones útiles que se pueden agregar al shebang, como --vanilla.
flodel
8
También mencionemos la commandArgsfunción y los paquetes getopty optparsepara analizar la línea de comandos. Para que los argumentos y las opciones también se puedan pasar a sus scripts cuando se ejecutan desde la línea de comandos.
flodel
1
Tenga en cuenta que esto solo funciona si #!/usr/bin/Rscript(que no es la práctica estándar para los scripts de R).
gented
16

Intente más pequeño . littlerproporciona la capacidad de hash-bang (es decir, un script que comienza con #! / some / path) para GNU R, así como un uso simple de la línea de comandos y la canalización.

Jouni K. Seppänen
fuente
10

La respuesta de Miguel Sánchez es como debe ser. La otra forma de ejecutar Rscript podría ser el comando 'env' para ejecutar el RScript en todo el sistema.

#!/usr/bin/env Rscript
The_Cute_Hedgehog
fuente
1
No "en todo el sistema", sino que envle permitiría ejecutar el primero que se Rscriptencuentre en el suyo $PATH, lo que le permitirá ejecutar algo que no sea ​​en todo el sistema / predeterminado Rscript(que puede no estar instalado /usr/whatever). Recomendaría usar envfor Rand Rscriptstuff, ya que estos en particular pueden no estar instalados en lugares estándar. (Ordinarias bashguiones sin embargo pueden utilizar con seguridad por lo general siempre #!/bin/bash.)
Michael
@michael No, te equivocas con respecto a Bash, y este es un consejo peligroso. Lo único que se puede codificar de forma segura es /bin/sh. Todo lo demás debe usar la envbúsqueda. En particular, la mayoría de las veces Bash está desactualizado en los clústeres de computación y los usuarios tienen sus propias instalaciones personalizadas (comúnmente en ~/.local/bino compartidas en algo como un /softwaremontaje NFS). Del mismo modo, en macOS, siempre/bin/bash está desactualizado debido a problemas de licencia, y un Bash actualizado se encuentra más comúnmente en (me doy cuenta de que su comentario tiene 3 años, pero esto es bastante importante)./usr/local/bin/bash
Konrad Rudolph,
No, lo siento, eso simplemente no es cierto. Sin embargo, tiene una opinión firme sobre el tema, así que no debatiré el tema. Si el uso no /bin/shes, en cualquier circunstancia, también "peligroso", entonces debe admitir que podría decirse lo mismo /bin/bash. El uso enves más impredecible, debido a PATHconfiguraciones confiables / inconsistentes para diferentes usuarios, pero cada usuario de R puede querer este comportamiento, mientras que los bashscripts no. Por último, para CI / nube que invoca scripts de bash más nuevos, simplemente invocalos usando /path/to/my/bash myscripto establece explícitamente la ruta e invocalos usando env script. EOT
Michael
9

#!/path/to/Rno funcionará porque R es en sí mismo un script, por lo que execvees infeliz.

yo suelo R --slave -f script


fuente
4
Fyi para lectores ocasionales: muchas de estas respuestas son anteriores a Rscript(y littler), en caso de que se lo pregunten.
Michael
@michael Ninguna de las respuestas aquí es anterior a Rscript, que se lanzó en 2007 con R 2.5.0.
Konrad Rudolph
4

Esto funciona,

#!/usr/bin/Rscript

pero no sé qué sucede si tiene más de 1 versión de R instalada en su máquina.

Si lo haces asi

#!/usr/bin/env Rscript

le dice al intérprete que use la R que aparezca primero en su camino.

su nombrebarbara
fuente
2

Si el programa que está utilizando para ejecutar su script necesita parámetros, ¡puede ponerlos al final de #! línea:

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

Sin saber R, no puedo probar correctamente, pero esto parece funcionar:

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

Solo una nota para agregar a esta publicación. Las versiones posteriores de Rparece haber enterrado Rscriptun poco. Para R 3.1.2-1 en OSX descargado en enero de 2015 encontré Rscripten

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

Entonces, en lugar de algo como #! /sw/bin/Rscript, necesitaba usar lo siguiente en la parte superior de mi script.

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

El locate Rscriptpodría ser útil para usted.

Juan
fuente
Esta respuesta es potencialmente útil, ya que no está claro a qué plataforma (* nix o Mac OS) se refiere el OP. Con un poco de reelaboración (busque formatear el código y elimine el principio de disculpa), esto sería una buena adición a las respuestas aquí.
BenBarnes
2
Esta es otra razón para usar en #!/usr/bin/env Rscriptlugar de una ruta codificada en los Rscripts (y agregar esa ruta larga a su $PATH)
michael
0

Es posible que desee utilizar el módulo rpy2 de python. Sin embargo, la forma "correcta" de hacer esto es con R CMD BATCH. Puede modificar esto para escribir en STDOUT, pero el valor predeterminado es escribir en un archivo .Rout. Vea el ejemplo a continuación:

[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

Nota: querrá probar --vanilla y otras opciones para eliminar todo el cruft de inicio.

ramanujan
fuente
0

Pruebe smallR para escribir scripts R rápidos en la línea de comando:

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

( rcomando en el directorio)

Trazar desde la línea de comando usando smallR se vería así:

r -p file.txt
Tom
fuente
2
En lugar de esto (que parece muerto), littlersin duda sería preferible (ya que todavía está vivo); o bien, sólo tiene que utilizar Rscript(que en realidad salió después littlerse creó.)
michael
-1

Lo siguiente me funciona al usar MSYS bash en Windows: no tengo R en mi caja de Linux, así que no puedo probarlo allí. Necesita dos archivos: el primero llamado runr ejecuta R con un parámetro de archivo

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

Necesitas hacer este ejecutable con chmod + x runr .

Luego, en su archivo de script:

#!runr
# some R commands
x = 1
x

Nota la #! Es posible que la línea runr deba incluir la ruta completa a runr, dependiendo de cómo esté usando el comando, cómo esté configurada su variable PATH, etc.

No es bonito, ¡pero parece funcionar!


fuente
1
¿Qué pasa con los diferentes scripts de R que necesitan diferentes parámetros? ¿Qué hay de pasar argumentos a los scripts R desde la línea de comandos?
blahdiblah