Tutorial
Tutorial
|
Show me round R!
The R window
Simple functions:
Because R is stack-based, standard arithmetic functions such as 1+2 have to be
rewritten to work. For instance, the example above (1+2) would be written in R
as 1 2 +.
Although this syntax is confusing at first, it reduces
complexity in parenthesised expressions such as (2+(3*4)) - ((8/5)*4) - which
equals 7.6 - by removing parentheses. The example above would be written in R as
2 3 4 * + 8 5 / 4 * -.
Explanation:
2 3 4 * +: 2, 3 and 4 are added to the stack. *
then multiplies 3 and 4, leaving the stack as 2 12. The + then adds
together 2 and 12, leaving 14 on the stack.
8 5 / 4 *: 8 and 5 are added to the stack, leaving it as
14 8 5. / then divides 8 by 5, returning 1.6. 4 is then
added to the stack (now containing 14 1.6 4), and *
multiplies 1.6 by 4, leaving 6.4 on the stack.
-: This - takes the stack, now containing 4 and
6.4, and takes 6.4 from 14. This leaves 7.6, which is left at the end of the
expression and returned.
Vector functions:
As a vector language, R has more options open to it. The same operators we met
in the last section (+, -, *, and /) can also be used on vectors. Try
typng this expression into the edit field:
(2 3 7)(1 0.4 -2)+
You should see (3 3.4 5) in the output window.
The \ (reduce) operator works in conjunction with the other arithmetic
operators for vector operations. For instance, try this:
(4 5 6)\+
You should see 15 (4+5+6). The \ operator works with
all the arithmetic operators, and also with ,, which is very
different and not covered here.
The other vector-specialised operators are #i, #v and #resize.
#i produces vectors of the format (1 2 3 ... n), and is run with
an expression like 5 #i, which gives (1 2 3 4 5).
#v is more complicated. Given n scalars of the same type
and a numeric scalar n, it produces a vector. Try this:
1 98.4 2 4 #v
The output window should show (0 1 98.4 2). Note the zero: because
we called it with n as a larger number than the length of the stack,
it pads with zeroes.
If instead we had run:
(1 98.4 2) 4 #resize (note the brackets, delimiting a vector)
... we would have got (1 98.4 2 1) the vector has been wrapped. (If you want to resize
a vector without wrapping, use #take: the vactor would then be padded with zeroes, so in this
example it would be (1 98.4 2 0).)
Arrays:
In a way, arrays are an extension of the vectors we have just been looking at. An array is bounded
by the square brackets ([ and ]), and can contain any data including other arrays, which can be as
nested as you like. Because arrays can contain mixed data, they are a useful wrapper. For example, they could be used
to maintain a personal records system, with an array structure such as:
[
['Joe Bloggs' 43 '17 March Avenue, Bloggsbury']
['Mark Johnson' 35 'Brown House, Highrigg']
]
... which only takes up one entry on the stack.
To extract data from an array, we have to use #apop. This takes an array and puts its contents
on the stack it effectively removes the outermost layer of square brackets from the construct.
For example, the code [2 3 4 ['hello' 23]] #apop (1 stack item) produces the result:
2 3 4 ['hello' 23] (4 stack items).
The same size functions (#size, #resize and #take) that we met
earlier for vectors also work on arrays: for #take, the array is padded with the
special value #null.
Defining functions:
There are two methods of defining functions in R: block definition and
the function editor. Firstly, lets define a function, using block structure,
that adds two to any number type into the edit field:
'AddTwo' {2 +} #def
... and press Enter.
This defines a new function, AddTwo, which consists of the R code
2 +. When run, it will add 2 to the stack, and
then run the + function. The net result will be that it will add 2 to the
number previously on the stack. Try it type:
4 AddTwo
... and the output window should show 6. (Note that R displays the line of
code you just typed in the output window. By double-clicking on a line, it will be
displayed in the input field, ready for editing or running.)
A useful maths function is average (mean). This time, lets use the
function editor. Type:
'average' #ed
... then type into the text area:
#d \+ #exch #size /
... and press Save.
When this function is called, the stack should contain a numeric vector to be
averaged. The calls to #d and \+ duplicate the vector, then add
up the vector at the top of the stack. (At this point the stack is (vec1)
sum.) #exch then exchanges the two items, #size
gives the length of the vector (leaving the stack as sum size), and
finally the / divides sum by size,
leaving the average.
(If you are confused, try adding #view into the code at certain
points to see what is on the stack at that point.)
Note that you could also have defined average by typing:
'average' {#d \+ #exch #size /} #def
... into the edit field. In fact, 'AddTwo' #ed will show you the
definition for AddTwo.)
To see which functions are defined in the current session, run the statement
#fns. The output window will show AddTwo average.
Defining Variables:
To define a variable, we use the R system function #set. To do this,
type into the input window:
'title' 'The R Tutorial' #set
... defining a variable title, which has the value 'The R Tutorial'.
Type #vars and the system will show title.
Graphics:
The R window again!
Before we start this section, lets have the graphics window displayed so we can
see what were doing. Enter #g.display, and a window with a cyan rectangle in it
should appear. This is the graphics display, and the cyan rectangle shows the area to draw on. As in PostScript, the co-ordinate system starts in the bottom left, and is measured in points
(1/72 inch at full scale, but 1 pixel on this window). The top right hand corner of the cyan rectangle
is at (324, 432). To show this, lets draw a line from bottom left to top right type:
0 0 324 432 #g.line
... and a line should appear on the graphics display.
Next, well draw a filled blue rectangle in the top left hand corner of the display. Type:
0 0 255 #g.setcolour 0 402 30 432 #g.frect
You should see a rectangle appear in the top corner.
Now lets draw a triangle near the bottom right. Triangles arent given a seperate
graphics call, so we have to use the polygon function, #g.pline (polyline). The call is
as follows:
(324 0 302 0 324 40 324 0) #g.pline
(Note that the co-ordinates must be a vector, otherwise #g.pline doesnt know how much to
take off the stack. This is also true of #g.fpline and #g.ptick.)
Finally, lets add some text in a medium grey. Use this code:
0.5 #g.setgrey 1 24 0 #g.setfont 15 15 'Hello World!' #g.text
The call to #g.setgrey sets the colour to the medium grey.
The call to #g.setfont needs explanation. It takes three arguments, the font face, type size
and the style. The face is an index into the vector (Times, Helvetica or Arial, Courier, Dialog, Symbol).
The style is one of Plain(0), Italic(1), Bold(2) or BoldItalic(3).
PostScript style:
In this subsection we will try to reproduce the display we just created, but using the PostScript style
of graphics. First, clear the display and reset the colour to black:
#ps.reset 0 #ps.setgrey (Note the #ps prefix).
The major difference between the two graphics types is that the PostScript one requires the use of the
#ps.moveto operator, and the #ps.stroke and #ps.fill operators are needed to
render graphics onto the page. For instance, to draw the line above, we need:
0 0 #ps.moveto 324 432 #ps.lineto
Note that nothing will appear until you type:
#ps.stroke
... at which point the familiar line will appear.
For the rectangle, we have to draw it ourselves, as the PostScript emulation doesnt provide us
with a rectangle function. So we must type:
0 0 255 #ps.setrgbcolour 0 402 #ps.moveto 0 30 #ps.rlineto 30 0 #ps.rlineto 0 -30 #ps.rlineto #ps.fill
... phew! That was a bit long! However, it introduces us to two things: #ps.rlineto, which draws a line
relative to the current point, and the fact that #ps.fill implicitly closes the current subpath
before filling it.
Next up is the triangle, this time drawn using repeated calls to #ps.rlineto. Here is the code:
324 0 #ps.moveto -40 0 #ps.rlineto 40 40 #ps.rlineto #ps.closepath #ps.stroke
Here we see that the path is explicity closed using #ps.closepath before using #ps.stroke.
Otherwise, this is very similar to the rectangle example above.
Finally we have the text. This is a very similar call to the one using standard graphics:
0.5 #ps.setgrey 1 24 0 #ps.setfont 15 15 #ps.moveto 'Hello World!' #ps.show
This moves the current point to (15, 15) before displaying the text. For an explanation of #ps.setfont, see
the explanation of #g.setfont above.
Changing the co-ordinate system:
The co-ordinate syatem can be scaled, rotated and moved using the functions #g.scale (or #ps.scale),
#g.rotate (or #ps.rotate and #g.translate (or #ps.translate). All subsequent graphics functions,
including later transformations, will use the modified co-ordinate system until a call to #g.resetctm (or #ps.resetctm),
which resets only the co-ordinate system, or #g.reset (or #ps.reset), which clears the display aswell.
This section is designed to have shown you a basic understanding of both types of R graphics. For further details,
please look at the Graphics Reference.
Scripts
The applet version of R cannot run scripts; scripts are files and the Java "sandbox" prevents an applet from getting access to your files (very sensibly). However, as a script is just a series of R commands you can paste the commands you want into an R function and run it.
To use scripts properly, you must download R.
Page and site © Richard Smith 2001
Please send any comments to richard@redcorona.com - thank you.
|