Using F# with R
On the F# list server over at Microsoft Research, there was a question posted by Lars Johnson about using F# with R. For whatever reason, I'm not able to post to that list server. I'm not very good with list servers, so I'll post up my usage here and hope that someone could post this back to the list server or notify Lars.
For those that don't know, R is an analytics tool with an emphasis on rich statistical toolboxes. It was first produced at the old AT&T Bell Labs and was later commercialized by Stat-Sci (later to become Insightful) as S-Plus. R remains free and in the public domain.
In the list server thread, Juergen Van Gael mentioned two approaches for possible integration - RSOAP and R(D)COM. This post is for usage of R with R(D)COM with F#. The RSOAP approach is a little more involved, so I chose the R(D)COM path here. As its name implies, R(D)COM is a wrapper for R for usage with COM and DCOM. It was written by Thomas Baier and Erich Neuwirth.
My environment for use of F# with R on a Windows platform:
1. Windows XP SP2
2. .NET 2.0 - 2.0.50727
3. Visual Studio 2005 with SP1 - 8.0.50727.762 (SP.050727-7600)
4. F# 1.9.2.9
5. R 2.6.0 - http://cran.us.r-project.org/
6. R(D)COM 2.50_pl1 - http://rcom.univie.ac.at/
Note that VS2005 is not necessary as this could be done with the .NET Framework and F#.
After the above installation, we need to make an R(D)COM .NET wrapper so that F# or any .NET application can see the R(D)COM server. For this, I opened a VS2005 command prompt (dos window with the VS2005 environment variables properly set up). In that window, perform the following two steps. After you complete these steps, the command window is no longer needed.
1. Change directory to the default installation for the R(D)COM binaries. "cd C:\Program Files\R\(D)COM Server\bin".
2. Create the .NET interop wrapper. "TlbImp STATCONNECTORSRV.exe /out:Interop.STATCONNECTORSRVLib.dll". Note that while this is a standard operation for .NET with COM, Robert Pickering's book "Foundations of F#" covers COM usage with F# (and other interoperability) in Chapter 13.
Next, open up a copy of fsi and interact with the following code.
//-----------------------------
#light
// attach a copy of the R(D)COM dll for statistics connections.
#r @"C:\Program Files\R\(D)COM Server\bin\Interop.STATCONNECTORSRVLib.dll"
// open the namespace
open Interop.STATCONNECTORSRVLib
// Create a connection instance
let SCCForR = new StatConnectorClass()
// Initialize that instance for usage with R
SCCForR.Init("R")
// Sample statements to modify the R environment.
// create an R variable named abc and assign it the value of 5
SCCForR.SetSymbol("abc", 5)
// Retrieve the value of the R variable named abc and assign that value to the F# value valueForabc
let valueForabc = SCCForR.GetSymbol("abc")
// Evaluate an expression in R and assign that value to an F# value aTestEvaluation
let aTestEvaluation = SCCForR.Evaluate("8 * sin(4)")
// Close the R connection
SCCForR.Close()
//-----------------------------
Note that the value for valueForabc should be 5. The value for aTestEvaluation should be -6.054419962. Also note that this sample does NOT clean up the COM object assigned to SCCForR. It only closes the connection to R.
This sample interop code was modified from the example given in the R(D)COM package. There are many other possibilities for R(D)COM, especially in the rich graphics libraries that R has to offer.