RDotNet and F#: Example from the Code Project
September 3, 2013 1 Comment
I added the R type provider via NuGet and it showed up in my references tab:
When I go to reference the library in code:
But if I fully-qualify the reference, it works:
Very Strange, but then I get yummy intellisense
I then wanted to add in the RDotNet assembly:
Filly qualified does not work
but if you add the “@” symbol, it does…
I then added the test case that is on codeplex(https://rdotnet.codeplex.com/).
After figuring out that your can only have 1 instance of the engine going at any point in time and the FSI holds a reference (my issue logged here), I wrote this very much procedural code:
- #r @"C:\TFS\Tff.RDotNetExample_Solution\packages\R.NET.1.5.3\lib\net40\RDotNet.dll"
- #r @"C:\TFS\Tff.RDotNetExample_Solution\packages\R.NET.1.5.3\lib\net40\RDotNet.NativeLibrary.dll"
- open System.IO
- open RDotNet
- let environmentPath = System.Environment.GetEnvironmentVariable("PATH")
- let binaryPath = @"C:\Program Files\R\R-3.0.1\bin\x64"
- System.Environment.SetEnvironmentVariable("PATH",environmentPath+System.IO.Path.PathSeparator.ToString()+binaryPath)
- let engine = RDotNet.REngine.CreateInstance("RDotNet")
- engine.Initialize()
- let group1 = engine.CreateNumericVector([30.02;29.99;30.11;29.97;30.01;29.99]);
- engine.SetSymbol("group1", group1)
- let expression = "group2 <- c(29.89,29.93,29.72,29.98,30.02,29.98)"
- let group2 = engine.Evaluate(expression).AsNumeric()
- let calcExpression = "t.test(group1, group2)"
- let testResult = engine.Evaluate(calcExpression).AsList()
- printfn "P-Value = %A" (testResult.Item("p.value").AsNumeric())
With the results coming out:
Hi James
I hope you are having fun playing with R and F#. I am the main author of the RProvider.
Your examples are using RDotNet directly. The good thing about the RProvider is that you get syntactic sugar for calling R functions, so you should for your t.test example you should be able to do the following (you don’t need to do the explicit initialization either if you use the RProvider):
let group1 = [30.02;29.99;30.11;29.97;30.01;29.99]
let group2 = [29.89,29.93,29.72,29.98,30.02,29.98]
let testResult = R.t_test(group1, group2)
You can see that it’s much simpler and cleaner, and you get intellisense for functions (though not their types, since R is dynamically typed). Also, the RProvider implicitly coerces things like lists or arrays into R vectors as needed.
You may also notice that the dot in t.test has been transformed into an underscore. This is because dot is not a valid character in identifiers.
Accessing results of functions is still harder than it should be, but the author of RDotNet and I are improving that somewhat.
Hope that helps!
Howard