[R] writing R shell scripts?

Mike Miller mbmiller at taxa.epi.umn.edu
Wed Nov 9 06:04:55 CET 2005


On Wed, 9 Nov 2005, Henrik Bengtsson wrote:

> What you really want to do might be solved by write.table(), e.g.
>
> x <- matrix(rnorm(25*2),c(25,2));
> write.table(file=stdout(), x, row.names=FALSE, col.names=FALSE);

Thanks.  That does what I want.

There is one remaining problem for my "echo" method.  While write.table 
seems to do the right thing for me, R seems to add an extra newline to the 
output when it closes.  You can see that this produces exactly one newline 
and nothing else:

# echo '' | R --slave --no-save | wc -c
       1

Is there any way to stop R from sending an extra newline?  It's funny 
because normal running of R doesn't seem to terminate by sending a newline 
to stdout.  Oops -- I just figured it out.  If I send "quit()", there is 
no extra newline!  Examples that send no extra newline:

echo 'quit()' | R --slave --no-save

echo "x <- matrix(rnorm(25*2),c(25,2)); write.table(file=stdout(), x, row.names=FALSE, col.names=FALSE); quit()" | R --slave --no-save

I suppose we can live with that as it is.  Is this an intentional feature?


> A note of concern: When writing batch scripts like this, be explicit and 
> use the print() statement.  A counter example to compare
>
> echo "1; 2" | R --slave --no-save
>
> and
>
> echo "print(1); print(2)" | R --slave --no-save

I guess you are saying that sometimes R will fail if I don't use print(). 
Can you give an example of how it can fail?


>> By the way, I find it useful to have a script in my path that does 
>> this:
>> 
>> #!/bin/sh
>> echo "$1" | /usr/local/bin/R --slave --no-save
>> 
>> Suppose that script was called "doR", then one could do things like 
>> this from the Linux/UNIX command line:
>> 
>> # doR 'sqrt(35.6)'
>> [1] 5.966574
>> 
>> # doR 'runif(1)'
>> [1] 0.8881654
>> 
>> Which I find to be handy for quick arithmetic and even for much more 
>> sophisticated things.  I'd like to get rid of the "[1]" though!
>
> If you want to be lazy and not use, say, doR 'cat(runif(1),"\n")' above, 
> maybe a simple Unix sed in your shell script can fix that?!


It looks like I can rewrite the script like this:

#!/bin/sh
echo "$1 ; write.table(file=stdout(), out, row.names=FALSE, col.names=FALSE); quit()" | /usr/local/bin/R --slave --no-save

Then I have to always include something like this...

out <- some_operation

...as part of my command.  Example:

# doR 'A <- matrix(rnorm(100*5),c(100,5)); out <- chol(cov(A))'
1.08824564637869 0.00749462665482204 -0.109577665309141 0.123824503621501 0.0420504647142321
0 0.969304154505745 0.0689085053799411 0.143273894584171 -0.0204348333174425
0 0 0.995383836907855 0.0860782051613422 0.056980680914183
0 0 0 0.94180592438191 0.0534651651371964
0 0 0 0 0.907266109886987

Now we've got it!!

The output above is nice and compact, and it doesn't have an extra 
newline, but if you want it to look nice on the screen, my friend Stephen 
Montgomery-Smith (Math, U Missouri) made me this nice little perl script 
for aligning numbers neatly and easily (but it doesn't work if there are 
letters in there (e.g., NA or 1.3e-6):

http://taxa.epi.umn.edu/misc/numalign

# ./doR 'A <- matrix(rnorm(100*5),c(100,5)); out <- chol(cov(A))' | numalign
0.903339952680364 -0.088773840144205 -0.223677935069773  -0.0736286093726908  0.0457396703130186
0                  1.08096548052082   0.0800540640587432 -0.0457840266135511 -0.0311210293661459
0                  0                  0.93834307353671    0.0665017259723313 -0.0825698771035788
0                  0                  0                   1.03303581434252    0.118372967026342
0                  0                  0                   0                   0.972768611955302

Thanks very much for all of the help!!!

Mike

-- 
Michael B. Miller, Ph.D.
Assistant Professor
Division of Epidemiology and Community Health
and Institute of Human Genetics
University of Minnesota
http://taxa.epi.umn.edu/~mbmiller/




More information about the R-help mailing list