tags:

views:

3739

answers:

6

It's very convenient to have R scripts for doing simple plots from the command line. However, running R from bash scripts is not convenient at all. The ideal might be something like

#!/path/to/R
...

or

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

but I haven't been able to make either of those work.

Another option is keeping the scripts purely in R, e.g. script.R, and invoking it with R --file=script.R or similar. However, occasionally a script will rely on obscure command line switches at which point part of the code exists outside the script. Example: sneaking things into R from bash via a local .Rprofile, the desired switches are then everything --vanilla implies except --no-init-file.

Another option is a bash script to store the R flags and be painlessly executable, which then calls the R script. The problem is that this means a single program just got split into two files which now have to be keep in sync, transferred to new machines together, etc.

The option I currently despise least is embedding the R in a bash script:

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

Everything's in a single file. It's executable and easily handles arguments. The problem is that combining bash and R like this pretty much eliminates the possibility of any IDE not failing on one or the other, and makes my heart hurt real bad.

Is there some better way I'm missing?

A: 

The following works for me using MSYS bash on Windows - I don't have R on my Linux box so can't try it there. You need two files - the first one called runr executes R with a file parameter

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

You need to make this executable with chmod +x runr.

Then in your script file:

#!runr
# some R commands
x = 1
x

Note the #! runr line may need to include the full path to runr, depending on how you are using the command, how your PATH variable is set etc.

Not pretty, but it does seem to work!

anon
What about different R scripts needing different parameters? What about passing arguments to the R scripts from the command line?
+4  A: 

Try littler.

Jouni K. Seppänen
A: 

If the program you're using to execute your script needs parameters, you can put them at the end of the #! line:

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

Not knowing R, I can't test properly, but this seems to work:

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
A: 

You might want to use python's rpy2 module. However, the "right" way to do this is with R CMD BATCH. You can modify this to write to STDOUT, but the default is to write to a .Rout file. See example below:

[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

Note: you'll want to try out the --vanilla and other options to remove all the startup cruft.

ramanujan
A: 

#!/path/to/R won't work because R is itself a script, so execve is unhappy.

I use R --slave -f script

+8  A: 

This is how it works:

#!/usr/bin/Rscript

cat("Hallo\n")`

Yes, I think this is the "official" way to do it.