In my family we say, “If no one took a picture, it didn’t happen.” I’m getting to be that way somewhat with various software technologies. Some little voice inside me says, “If I can’t call it from C#, it can’t be a real technology.” That’s not true of course, but it helps explain my recent struggle to figure out how to call the analytic engine ‘R’ from C#. Of course I did have a business reason…
The R community is pretty vibrant, to a point. If you want help with analytic esoterica, there are tons of forums and news groups. But if you want to think about incorporating R into a commercial environment, the road is less traveled. (Sorry for the mixed metaphor.)
I did manage to get it to work. I started with this 2008 article The R Statistical Language and C#.NET: Foundations by Jeff Cromwell. That gave me the basic idea of how to connect. The stack I used includes:
· R 2.11.1 32-bit for Windows (Windows 7 in my case)
· The matching rscproxy package
· The R-(D)COM Interface
The current version of R is 2.12.0. I started there but had no luck getting my simple C# program to connect to R. I eventually found a posting that says the DCOM interface does not work with the 2.12.0 version of R. Once I backtracked and got 2.11.1 and the matching rscproxy package, I got the connection to work.
Here is the recipe:
1. Download R 2.11.1 here.
2. When you install R, make sure to check the box that saves the version number in the registry. You’ll see it in the second or third dialog of the install routine. It seems to be checked by default.
3. Download the 2.11 version of rscproxy here.
4. Unzip the rscproxy package somewhere you can find later. Within that folder you will find an ‘rscproxy’ folder. Copy that folder to your library folder under the R directory. For me, that is C:\Program Files (x86)\R\R-2.11.1\library. Adjust for your installation as appropriate.
5. Down load the DCOM Interface from here.
6. Install the DCOM Interface by running the exe you downloaded in step 5.
7. At this point I started R and used the library () command to be sure rscproxy was in the library. I further used library (rscproxy) to make sure I could load it. If your version of rscproxy is newer than your version of R, you will find out at this point.
8. The DCOM Interface installs a simple test routine at “C:\Program Files (x86)\R\(D)COM Server\samples\Simple\simple.exe” (on my machine.) You’ll find it in your start menu as well with the name “Server 01 – Basic Test”. If you run this, you will see a GUI with a ‘Start R’ button. If that works, you’re good to go. If it does not, make sure all the versions align. Remember, 2.12.0 does not seem to work at this point (11/18/2010). Make sure you can load the proxy from within R.
I’m sure there are other ways to do this; I’m interested in learning about other approaches, especially in terms of performance and robustness.
Once the test program worked, I wrote a simple C# console program based on the sample in the Cromwell article. The only thing I had to puzzle out, slightly, was adding the reference to the libraries. It’s here:
That gives you the key entry points to establish a connection, set and get R symbols and cause evaluation. In other words, this assembly has the implementation of IStatConnector. There are other libraries to invoke R’s graphics engine and other features. I have not tried these yet.
The one change I made in the Cromwell’s sample code is to use ‘var’ instead of ‘object’. C# circa 2008 did not include support for var, at least I don’t think it did.
This code works:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using StatConnectorCommonLib; using STATCONNECTORSRVLib; namespace R_TestClient { class Program { static void Main(string[] args) { try { StatConnector rConn = new StatConnector(); rConn.Init("R"); rConn.SetSymbol("n1", 20); rConn.Evaluate ("x1<-rnorm(n1)"); var o = rConn.GetSymbol ("x1"); foreach (double d in o) Console.WriteLine(d); rConn.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } |
I’m off to learn R and try more substantial processing. Let me know, via comments, if I have any of this wrong or if you found better ways to do the same things. Thanks!
My next steps:
· Try more complicated R processing.
· Understand how to connect to remote instances of R.
· Test scale (data size) and performance.