2 min read

Call R from C#

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.

comments powered by Disqus