💾 Archived View for blitter.com › apl-books › APLX50 › APLX-manual › www.microapl.com › apl_help › c… captured on 2023-01-29 at 14:38:03.
⬅️ Previous capture (2022-07-17)
-=-=-=-=-=-=-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Interfacing to R</TITLE> <META NAME="DESCRIPTION" CONTENT="APL language help page: Interfacing to R"> <META NAME="KEYWORDS" CONTENT="R,statistics,significance tests,apl,aplx,apl help"> <!-- %%COMMON_HEAD%% --> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <LINK rel="stylesheet" type="text/css" href="http://www.microapl.com/styles_apl_help.css"> <!-- %%END%%--> </HEAD> <body> <table> <tr> <td width="800" valign="top" colspan="2"> <center>Topic: <A HREF="ch.htm">APLX Help</A> : <A HREF="ch_070.htm">Interfacing to other languages</A> : <A HREF="ch_070_060.htm">Interfacing to R</A> </center> <center> [<A HREF="ch_070_060.htm">Next</A> | <A HREF="ch_070_040.htm">Previous</A> | <A HREF="ch.htm">Contents</A> | <A HREF="help_index.htm">Index</A> | <A HREF="http://www.microapl.co.uk/apl/index.html">APL Home</A> ]</center> <br></td> </tr> <tr> <td width="120"> <a href="http://www.microapl.co.uk/apl/index.html"><img height="68" border="0" width="119" src="MicroAPL_logo.gif" alt="www.microapl.co.uk"></a> </td> <td align="left" valign="bottom"> <h1>Interfacing to the R statistical language</h1> </td> </tr> <tr> <td width="800" valign="top" colspan="2"> <hr> <H2>What is R?</H2> <p>R is an open-source language and set of packages aimed principally at statistical analysis. It includes a huge library of pre-written statistical and mathematical routines, which can be accessed immediately and very conveniently from APLX. It also includes mathematically-oriented graphing facilities.</p> <p>R is available from <A HREF="http://www.r-project.org/">http://www.r-project.org</A>, which describes R as follows:</p> <blockquote> <i><p>R is a language and environment for statistical computing and graphics. It is a GNU project which is similar to the S language and environment which was developed at Bell Laboratories (formerly AT&T, now Lucent Technologies) by John Chambers and colleagues. R can be considered as a different implementation of S. There are some important differences, but much code written for S runs unaltered under R.</p> <p>R provides a wide variety of statistical (linear and nonlinear modelling, classical statistical tests, time-series analysis, classification, clustering, ...) and graphical techniques, and is highly extensible. The S language is often the vehicle of choice for research in statistical methodology, and R provides an Open Source route to participation in that activity.</p> <p>R is available as Free Software under the terms of the Free Software Foundation's GNU General Public License in source code form. It compiles and runs on a wide variety of UNIX platforms and similar systems (including FreeBSD and Linux), Windows and MacOS.</p></i> </blockquote> <H2>Installing R</H2> <p>R can be downloaded either in source code form, or as a pre-compiled binary for most popular platforms, from a number of wesbites (see <A HREF="http://www.r-project.org/">http://www.r-project.org</A>). In each case you need the R shared library (called <tt>libR.so</tt> in Linux, <tt>R.dll</tt> under Windows, and <tt>libR.dylib</tt> under MacOS); this is usually available in the pre-compiled binaries. If installing from source, be sure to specify the option <tt>--enable-R-shlib</tt> when running the configure script.</p> <H3>Installing under Windows</H3> <p>This is most easily done using the installer provided with the pre-built binaries. The only additional step which you might need to take is to add the R binary directory to your search path, so that APLX can find the DLL <tt>R.dll</tt>.</p> <H3>Installing under Linux and MacOS</H3> <p>Follow the instructions provided with the R download. You also need to set up environment variables for R; this is usually done in the R script.</p> <H2>Calling R from APLX</H2> <p>Most of the interface between APLX and R is done using a single external class, named <tt>'r'</tt>, which represents the R session that you are running. (Note that this is different from most of the other external class interfaces, where objects of many different classes can be created separately from APLX). You create a single instance of this class using <A HREF="ch_020_070_505.htm"><code>⎕NEW</code></A>. R functions (either built-in or loaded from packages) then appear as methods of this object, and R variables as properties of the object.</p> <p>For example:</p> <pre> ⍝ Open the R interface and try a few simple things r←'r' ⎕new 'r' r.sqrt 2 1.414213562 r.sqrt (⊂⍳5) 1 1.414213562 1.732050808 2 2.236067977 r.sqrt ¯1 [r:NAN] ⍝ Returns a special R object NAN r.mean (⊂⍳10) 5.5 </pre> <p>When calling R functions, the APLX right argument is always a vector where each element corresponds to one argument of the R function. The calls to the <tt>sqrt</tt> and <tt>mean</tt> functions above illustrate this; to pass an array as the argument, it needs to be enclosed.</p> <H2>Creating variables in the R environment</H2> <p>Assigning to a symbol as though it were a property of the R session class creates a variable in the R world:</p> <pre> r.x←2 3⍴⍳6 ⍝ x is an R variable r.x 1 2 3 4 5 6 r.x.⎕ref [r:matrix] </pre> <H2>Evaluating R expressions</H2> <p>Because R is an interpreted language, it is possible to use the System Function <A HREF="ch_020_070_293.htm"><code>⎕EVAL</code></A> to run lines of R code, for setting up variables in the R environment, for defining R functions, and so on.</p> <pre> 'r' ⎕eval '4:9' 4 5 6 7 8 9 </pre> <p>However, a more convenient syntax is provided (for the 'r' class only) in which <code>⎕EVAL</code> is a monadic system <i>method</i>. </p> <p>The right argument is a text vector containing any expression which is a valid line of R code. The result is the explicit result (if any) of evaluating the expression in the external environment. For example:</p> <pre> r←'r' ⎕new 'r' r.x←2 3⍴⍳6 ⍝ x is an R variable r.x 1 2 3 4 5 6 r.⎕eval 'x[2,]' 4 5 6 r.⎕eval 'mean(x[2,])' 5 </pre> <p>Note that the last line could be executed using the alternative syntax where <code>⎕EVAL</code> is a system <i>function</i>:</p> <pre> 'r' ⎕eval 'mean(x[2,])' 5 </pre> <H2>Example: 3-D plot</H2> <p>In this short but complete example (based on an article by Skomorokhov and Kutinsky from Quote Quad 123 No 4), we create some data in the R environment, define an R function, and run the R outer product to create some test data. We then call the R <tt>persp</tt> function to create a 3-D plot:</p> <pre> r←'r' ⎕new 'r' x←r.⎕eval 'seq(-10,10,length=50)' y←x ⍝ Define an R function and return a reference to it: fn←r.⎕eval 'foo<-function(x,y){r<-sqrt(x^2+y^2);10*sin(r)/r}' fn [r:function] r.z←r.outer(x y fn) r.x←x r.y←y ⊣r.⎕eval 'persp(x,y,z,theta=30,phi=30,expand=0.5,xlab="X",ylab="Y",zlab="Z")' </pre> <p>This causes R to open a window and display a 3-d perspective chart:</p> <center><img src="Rplot.jpg" width="538" height="556" border="0"> </center> <H2>Listing R variables and functions</H2> <p>The <code>⎕NL</code> system method can be used to get the names of R variables and/or functions. The function list includes built-in functions and functions from all the loaded R packages, so may be several thousand items long:</p> <pre> ⍝ List R variables: vars←r.⎕nl 2 ⍴vars 129 21 ⍝ List R functions: fns←r.⎕nl 3 ⍴fns 2058 34 ⍝ There are lots of them! </pre> <p><code>⎕DESC</code> can be used to get the full R function list together with details of the parameters (Caution: the result is very large):</p> <pre> fns2←r.⎕desc 3 fns2[1445+⍳5;] pwilcox (q, m, n, lower.tail = TRUE, log.p = FALSE) q (save = "default", status = 0, runLast = TRUE) qbeta (p, shape1, shape2, ncp = 0, lower.tail = TRUE, log.p = FALSE) qbinom (p, size, prob, lower.tail = TRUE, log.p = FALSE) qbirthday (prob = 0.5, classes = 365, coincident = 2) </pre> <H2>R naming conventions</H2> <p>R function names can have characters such as a <tt><</tt> and <tt>-</tt> in them, which are not legal as symbol names in APLX. To call these in APLX as direct method calls, you need to escape the illegal character with a <tt>{body}lt;/tt> character. (This is not of course necessary when using <code>⎕EVAL</code>, where the string is passed as-is to R).</p> <p>For example, to call <tt>attr<-</tt> from APLX, you would call <tt>r.attr{body}amp;lt;$-</tt>.</p> <H2>Conversion of R data types to APL data</H2> <p>Simple numeric arrays and arrays of strings passed from APLX to R are converted directly to the R equivalent array, and are converted back automatically ('unboxed') when referenced or returned from an R function call, unless you use <code>⎕REF</code> to force an object reference to be returned:</p> <pre> r.y←2.2 3.3 4.4 r.y 2.2 3.3 4.4 r.y.⎕ref [r:numeric] (r.y.⎕ref).⎕ds ⍝ Use R to format the R array [1] 2.2 3.3 4.4 r.⎕eval 'mean(y)' 3.3</pre> <H2>Complex, NA and NAN data types</H2> <p>The APLX R interface defines three special object classes for NA ('Not Available'), NaN ('Not A Number') and complex-number data, which R routines may return, or which you may want to pass as arguments into R functions.</p> <p>For example, the following R expression returns a complex number: <pre> c←r.⎕eval '3+4i' c [r:complex] c.format 3+4i </pre> <p>Instances of these object classes can be created by using <code>⎕NEW</code>:</p> <pre> NA←'r' ⎕new 'NA' NA [r:NA] NAN←'r' ⎕new 'NAN' r.z←55.6 77.4 NAN 81 NA r.z 55.6 77.4 [r:NAN] 81 [r:NA] r.sqrt (⊂r.z) 7.456540753 8.797726979 [r:NAN] 9 [r:NA] </pre> <p>The <tt>complex</tt> class allows you to create either a single complex number, by using a constructor with two numbers for real/imaginary parts:</p> <pre> c←'r' ⎕new 'complex' 2 3 c [r:complex] c.format 2+3i </pre> <p> or to build an R complex array by passing an array of length-2 vectors of the real and imaginary parts of each complex number:</p> <pre> m←'r' ⎕new 'complex' (3 2⍴(1 2) (3 4) (5 6) (7 8) (9 10) (11 12)) m [r:matrix] m.format 1+ 2i 3+ 4i 5+ 6i 7+ 8i 9+10i 11+12i </pre> <p>You can access or specify the real and imaginary parts directly using the pseudo-properties <tt>real</tt> and <tt>imag</tt> of the <tt>complex</tt> object:</p> <pre> m.real 1 3 5 7 9 11 m.imag←3 2⍴.1×⍳6 m.format 1+0.1i 3+0.2i 5+0.3i 7+0.4i 9+0.5i 11+0.6i m.imag 0.1 0.2 0.3 0.4 0.5 0.6 </pre> <p>NAs and NaNs are also supported in Complex arrays:</p> <pre> v←'r' ⎕new 'complex' ((3.2 3.4) NA (1.1 8.2)) v.format 3.2+3.4i NA 1.1+8.2i v.real 3.2 [r:NA] 1.1 v.imag 3.4 [r:NA] 8.2 (r.sqrt v).format 1.983563+0.857043i NA 2.164885+1.893865i </pre> <H2>Advanced R data types</H2> <p>Other R types, such as factors and lists, are left 'boxed up' as references to the underlying R object (unless you use <code>⎕VAL</code> to force an unbox, if this is possible):</p> <pre> lst←r.⎕eval 'list(name="Fred",age=99) lst [r:list] lst.⎕val Fred 99 ⎕display lst.⎕val </pre> <p>An object which is still boxed up can be passed as an argument to an R function:</p> <pre> r.length lst 2 r.names lst name age </pre> <p>As a convenience you can also write this last example as:</p> <pre> lst.length 2 lst.names name age </pre> <p>This works because APLX treats the expression</p> <pre> obj.function arg1,arg2,... </pre> <p>...as equivalent to:</p> <pre> r.function obj,arg1,arg2,... </pre> <H2>Examining an object with <code>⎕DS</code></H2> <p>The system method <code>⎕DS</code> can be used to examine an R object. It's equivalent to calling the <tt>print</tt> method when working in an interactive R session. <pre> lst←r.⎕eval 'list(name="Fred",age=99) lst [r:list] lst.⎕ds $name [1] "Fred" $age [1] 99 </pre> <H2>Functions on the left side of an R assignment</H2> <p>In R, a function name can sometimes be given on the left side of an R assignment as the fourth line of the following example written in the R language shows:</p> <pre> > lst<-list(name="Fred",age=99) > names(lst) [1] "name" "age" > names(lst)<-c("firstname", "age") > names(lst) [1] "firstname" "age" </pre> <p>What actually happens 'under the hood' is that R treats an assignment like:</p> <pre> function(obj) <- value</pre> <p>...as being a call to a function called "function<-" with the function result assigned to the object, i.e.</p> <pre> obj <- "function<-" (obj, value)</pre> <p>If you wanted to call this function in APLX you could do so, using the $ character to escape the function name:</p> <pre> lst←lst.names{body}amp;lt;$- (⊂'firstname' 'age') lst.names firstname age </pre> <p>However, APLX also supports a much more convenience syntax:</p> <pre> lst.names←'firstname' 'age' </pre> <H2>Indexing lists by name</H2> <p>In the R language a list can be indexed either by number or by name, e.g.</p> <pre> > lst[[2]] $age [1] 99 > lst$age [1] 99 </pre> <p>This is achieved by special R indexing functions called [[ and $ which can also be called from APLX (once again using a $ to escape the function name):</p> <pre> lst.$[$[ 2 99 lst.$ 'age' 99 </pre> <p>It is also possible to change the value of a list item, which you would do in R by writing "<tt>lst$age<-95</tt>". Under the hood, R is using a function called <tt>{body}amp;lt;-</tt> which we can call from APLX:</p> <pre> lst←lst.${body}amp;lt;$- 'age' 95 </pre> <H2>Attributes</H2> <p>R objects can have <i>attributes</i> attached to them. By convention, any reference to <code>∆XXX</code> is interpreted as an implicit call to <tt>attr(obj, XXX)</tt>:</p> <pre> ⍝ Get a copy of the R 'Iris' variable, a sample 'data.frame' iris←r.iris iris [r:frame] (iris.attributes).names names row.names class iris.∆names Sepal.Length Sepal.Width Petal.Length Petal.Width Species </pre> <p>You can also change the value of attributes or add your own. Any assignment to <code>∆XXX</code> is interpreted as an implicit call to <tt>attr<-(obj, XXX)</tt>: <pre> f.∆mycustomatt ← 'Some attribute' f.∆mycustomatt Some attribute ⍝ Longer-winded way of doing the same thing, but creating a new object: f2←r.attr{body}amp;lt;$- f 'mycustomattr' 'Some other attribute' r.attr f2 'mycustomattr' Some other attribute</pre> <p>Here is an example of creating an R data.frame object from some APL data:</p> <pre> data←?3 5⍴100 ⍝ Random APL data for demo data 95 6 77 78 83 13 2 69 87 63 74 73 100 89 24 frame←r.data.frame (⊂data) frame.attributes.⎕ds $names [1] "X1" "X2" "X3" "X4" "X5" $row.names [1] 1 2 3 $class [1] "data.frame" frame.∆names←'Fish' 'Chips' 'Ham' 'Eggs' 'Tea' frame.⎕ds Fish Chips Ham Eggs Tea 1 95 6 77 78 83 2 13 2 69 87 63 3 74 73 100 89 24 frame.summary.⎕ds Fish Chips Ham Eggs Tea Min. :13.00 Min. : 2.0 Min. : 69.0 Min. :78.00 Min. :24.00 1st Qu.:43.50 1st Qu.: 4.0 1st Qu.: 73.0 1st Qu.:82.50 1st Qu.:43.50 Median :74.00 Median : 6.0 Median : 77.0 Median :87.00 Median :63.00 Mean :60.67 Mean :27.0 Mean : 82.0 Mean :84.67 Mean :56.67 3rd Qu.:84.50 3rd Qu.:39.5 3rd Qu.: 88.5 3rd Qu.:88.00 3rd Qu.:73.00 Max. :95.00 Max. :73.0 Max. :100.0 Max. :89.00 Max. :83.00 frame.plot </pre> <H2>Using the R interface from multiple APL tasks</H2> <p>Because it is not safe to call the R interpreter from multiple threads, you cannot use the R interface from more than one APL task at a time. If you try to do so, you will get an error message and a FILE LOCKED error:</p> <pre> r←'r' ⎕new 'r' This interface cannot be used by more than one APL task at a time FILE LOCKED r←'r' ⎕new 'r' ^ </pre> <p>The lock will be cleared when the APL task which has been accessing R executes a <tt>)CLEAR</tt>, <tt>)LOAD</tt>, or <tt>)OFF</tt>.</p> <hr> </td> </tr> <tr> <td width="800" valign="top" colspan="2"> <center>Topic: <A HREF="ch.htm">APLX Help</A> : <A HREF="ch_070.htm">Interfacing to other languages</A> : <A HREF="ch_070_060.htm">Interfacing to R</A> </center> <center> [<A HREF="ch_070_060.htm">Next</A> | <A HREF="ch_070_040.htm">Previous</A> | <A HREF="ch.htm">Contents</A> | <A HREF="help_index.htm">Index</A> | <A HREF="http://www.microapl.co.uk/apl/index.html">APL Home</A> ]</center> <br></td> </tr> </table> <!-- %%COMMON_BODY_TAIL%% --> <p class="copyright">Copyright © 1996-2010 MicroAPL Ltd</p> <!-- %%END%% --> </body> </html>