[R] commandArgs usage and --args invokation

ivo welch ivowel at gmail.com
Sun Apr 1 22:30:35 CEST 2007


hanks, dirk.  this looks a bit nicer than what I put together in the
last hour, which is a simple perl script that gives me the syntax I
most like:
  $ R batch.R arg1 arg2
personally, because this has no meaning in the current invoke
syntax, I think that R should understand this as the obvious
shortcut for "R CMD BATCH '--args arg1 arg2' batch.R".

upon completion, if there is an error, it also prints the last 20
lines of the output, thereby alerting me real well that something went
wrong.  in case someone else finds it useful, I am dropping it in here
(it's short enough not to be too much of a bother, I hope).

the remaining problem that I have not yet tackled is that if I want a
few invokations of the same script, each with different args, the .Rout
file name should reflect the args...this is not hard, I think


#!/usr/bin/perl -w
use strict;
################################################################
### Q: command line interface to R that allows the following
###    simplified syntax
###
###  $ Q [any R options] batch.R  arg1 arg2 arg3 ...
###      in R itself, use commandArgs() to pick them off
###
### unless the --restore option or the --save option is given,
### we wipe out the .RData file, and invoke with --no-restore
### and --no-save.  I don't like accidentally contaminated
### R data spaces.
###
### if invoked with a CMD or without a .R file, then it just
### invokes the original /usr/bin/R with the same commandline.
###
### Finally, upon exit, if R exits with an error code, then it
### prints the last 20 lines of the .Rout file.  If I knew how
### to reliably ring a bell in linux, I would do this, too.
###
###
### in my .Rprofile, I have
###
### ARGV= vector(mode="character", 0);
### if (!interactive()) {
###  all.args=commandArgs();
###  nowargs=F;
###  for (i in 1:length(all.args)) {
###    if (nowargs) ARGV= c(ARGV, all.args[i]);
###    if (all.args[i] == "--args") { nowargs=T;}
###  }
### }
###
### so I can now use the ARGV vector.  Note: this script has not been debugged
### or used for very long.
################################################################

if ($#ARGV<0) {
 (-e ".RData") and unlink(".RData");  # by default, forget the environment
 exit(system("/usr/bin/R --no-restore-data --no-save"));
}

my $originalline= join(" ", @ARGV);

($originalline !~ /[a-zA-Z0-9\_]\.R\b/) and exit(system("/usr/bin/R
$originalline"));  ## there is no .R file anywhere
($originalline =~ /\bCMD\b/) and exit(system("/usr/bin/R
$originalline"));  ## the user gives his own CMD file

### ok, pick off all arguments after the .R batch file

my $Rbatch; my $Rpgmopts="";
while (1) {
 $Rbatch = pop(@ARGV);
 ($Rbatch =~ /\.R$/) and last;
 $Rpgmopts= "$Rbatch $Rpgmopts";
}

## ok, we have the .R batch file in $Rbatch, and the options in $pgmopts;
(-e $Rbatch) or die "File $Rbatch does not exist\n";

my $RLNGOPTS= ($#ARGV>=0) ? join(" ", @ARGV) : "";

 ## wipe out .RData;  I don't use it;
my $nowipeout=0;
if ($RLNGOPTS =~ /--restore/) { $nowipeout=1; } else { $RLNGOPTS .= "
--no-restore"; }
if ($RLNGOPTS =~ /--save/) { $nowipeout=1; } else { $RLNGOPTS .= " --no-save"; }
if (!$nowipeout) { (-e ".RData") and unlink(".RData"); }

if ($Rpgmopts ne "") { $Rpgmopts="'--args $Rpgmopts'"; }

print STDERR "/usr/bin/R $RLNGOPTS CMD BATCH $Rpgmopts $Rbatch...";
my $rc=system("/usr/bin/R $RLNGOPTS CMD BATCH $Rpgmopts $Rbatch\n");

if (!$nowipeout) { (-e ".RData") and unlink(".RData"); }

################################################################
## now check the output;

my $Rbatchlog= "${Rbatch}out";

if ($rc) {
 my $t="\n\n".`tail -20 $Rbatchlog`."";
 warn "
****************************************************************
 /usr/bin/R $originalline: ERROR CODE $rc\n$t
****************************************************************
";
} else { print STDERR "ok\n"; }

exit $rc;



More information about the R-help mailing list