R has various packages to call other languages, like Rccp, rJava or sparklyr. Those tools significantly expand R’s capabilities, because the user doesn’t need to learn a lot of different stuff. Everything is nicely integrated into R.
However, sometimes the problem is different - there’s an existing system written in some language, and R can be used to expand its possibilities. So in that scenario R must be called.
In that post, I’ll describe how R can be integrated with C# program using Microsoft.R.Host.Client.API
.
Create R session inside C#.
The first problem is to create R session inside C#. Firstly, some imports must be added (note that Microsoft.R.Host.Client.API should be imported from NuGet - https://www.nuget.org/packages/Microsoft.R.Host.Client.API/) :
// Imports needed for R
using System.Threading;
using System.IO;
using System.Threading.Tasks;
using Microsoft.R.Host.Client;
Then the following code starts the R session:
// Init R session
IRHostSession session = RHostSession.Create("Test");
Task sessionStartTask = session.StartHostAsync(new RHostSessionCallback());
sessionStartTask.Wait();
// Simple output from console
Console.WriteLine("Arbitrary R code:");
var result = session.ExecuteAndOutputAsync("Sys.info()");
result.Wait();
Console.WriteLine(result.Result.Output);
Pass data.frame from C# to R.
The next useful thing is to create R’s data.frame
in C# and pass it to R’s session. It can be achieved using the session.CreateDataFrameAsync("data", df)
, where “data” is a name of data.frame created in R and df is a C# DataFrame object.
The following code presents how to create DataFrame:
List<string> colNames = new List<string>(new string[] { "c1", "c2" });
List<string> rowNames = new List<string>(new string[] { "1", "2", "3", "10" });
var xx = new object[] { new object[] { 1, 3, 43, 54 }, new object[] { "a", "c", "a", "d" } };
var list = new List<IReadOnlyCollection<object>>();
foreach (object o in xx)
{
list.Add(o as object[]);
}
DataFrame df = new DataFrame(rowNames, colNames, list.AsReadOnly());
var dtc = session.CreateDataFrameAsync("data", df);
dtc.Wait();
Then you can collect some data from R as a list using:
result = session.ExecuteAndOutputAsync("print(data)");
result.Wait();
Console.WriteLine("\nR data frame:");
Console.WriteLine(result.Result.Output);
var resultList = session.GetListAsync("list(mean(data$c1), 111)");
Console.WriteLine("\nList elements returned from R to C#:");
Console.WriteLine(Convert.ToDouble(resultList.Result[0]) * 100);
Console.WriteLine(resultList.Result[1]);
Conclusions.
Microsoft.R.Host.Client.API
is quite easy to use and might be your first shot when you need to integrate R with C# application. For more examples, you can visit https://github.com/MikhailArkhipov/RTVS-cs. You can also try https://github.com/jmp75/rdotnet, which is another project which allows using R in C#. However, I didn’t test it, so I can’t say anything about it.
Simple console app containing the C# code from this post is available here: https://github.com/zzawadz/r-from/tree/master/r-from-csharp.