R <myRscript), or execute it from the interactive
prompt by using the source function
(> source("myRscript")). While this is handy,
it seemed to me that it would be nice to be able to write executable R
scripts capable of taking command-line parameters, as with sh, perl,
tcl/tk and other scripting languages; in short, to use the #!
convention with R.
When R starts, it will source the file named in environment variable
R_PROFILE before beginning interactive execution. If that file
defines a function named .First, that function will be executed. The
Bourne shell script presented below, named setR, takes advantage of
R_PROFILE and .First to provide a #! equivalent for R scripts. If the
first line of an R script contains
#! /bin/sh /usr/bin/setR (with the
appropriate paths, of course), and the R script is executed, it will be
passed by setR to the R interpreter. An array called argv will be
created and passed as well, containing any command-line arguments given
with the invocation of the executable R script.
Here's the code. This script is copyright © 2003 Gregory Louis, and is distributed without warranty under the GNU General Public License (GPL):
#! /bin/sh
# command-line args to pass to R
Rargs="--no-save -q"
if [ "x$1" = "xh" -o "x$1" = "x-h" ]; then
cat <<EOT
NAME
setR - wrapper to provide a hashbang equivalent for R scripts
SYNOPSIS
setR -h
or
#! /bin/sh /usr/bin/setR
DESCRIPTION
setR writes an R profile in $TMPDIR containing a function .First that
sources the calling script. If there are any command-line parameters
in the invocation of the calling script, these are assigned to
array argv before function .First's "source" command. If not, argv
will exist with length 0. R is then called with this profile and
command-line arguments $Rargs.
OPTIONS
-h The option -h displays help.
EOT
exit 0
fi
# get the name of the calling script; if ./something, replace . with $PWD
caller=$1; shift
test "x${caller#./}" != "x$caller" && caller=$PWD${caller#.}
# begin an R profile with standard options, and startup function .First
profn=$TMPDIR/R$$; test "x$TMPDIR" = "x" && profn=/tmp/R$$
cat > $profn <<-EOT
options(CRAN="http://cran.us.r-project.org", papersize="letter")
par(las=1, font.lab=2, pty="s", tcl=0.35, mgp=c(2.75,0.5,0), bty="l")
.First <- function() {
EOT
# NB: *** for R 2.0.0 and later, omit the par() call from the above!
# Due to "lazy loading," graphics calls don't work at this point.
# make a comma-separated list of command-line arguments, if any
echo -n " argv <<- c(" >> $profn
while [ "x$1" != "x" ]; do
echo -n "\"$1\"" >> $profn; shift
test "x$1" != "x" && echo -n ", " >> $profn
done
echo ")" >> $profn
# let the .First function end by feeding the calling script to R
cat >> $profn <<-EOT
source("$caller")
}
EOT
# run R and then delete the profile
R_PROFILE=$profn /usr/bin/R $Rargs
/bin/rm -f $profn