How to Run R Script from C# Program in a Session


   To run the R script in the C# program by calling the Rscript.exe in every execution is time-consuming, and it makes the application slow. We implemented this method in my previous post. To avoid such unnecessary calls, we can create a session and load all necessary libraries once and use it until the end of the application.
   This post is about how to run the R script in C# by creating an R session. To implement an R session in a C# application, we use Microsoft.R.Host.Client.API package. The package provides an interface between the C# and R using Visual Studio R Tools runtime.

   First, we create a Console application in Visual Studio 2017 and install Microsoft.R.Host.Client.API package with a NuGet Manager.



Next, we add Microsoft.R.Host.Client library into our source code.

using Microsoft.R.Host.Client;

Next, we create the rSession object with the IRHostSession class and initiate it.

private static IRHostSession rSession;
// create session
rSession = RHostSession.Create("RwrapperSession");
// start session
var sessionStartTask = rSession.StartHostAsync(new RHostSessionCallback());
sessionStartTask.Wait();

Once the session is initiated, it can be used to execute the R commands until the application is closed. To run R command, we use ExecuteAndOutputAsync() method of the rSession object.

var rcommand = "library(dplyr)";
var result = rSession.ExecuteAndOutputAsync(rcommand);
result.Wait();
// print the result
Console.WriteLine(return result.Result.Output);

Next, we implement the above methods and check R command execution performance by counting elapsed time. Make sure that a dplyr package is installed on your R environment.
Below is a full source code listing.

using Microsoft.R.Host.Client;
using System;
using C = System.Console;
class Program
{
 private static IRHostSession rSession;

 static void Main(string[] args)
 {
  // Initialize R session
  Init();

  var rcom = "library(dplyr); ";
  // Run dplyr command. R session loads dplyr library first time
  RunRCommand(rcom + "iris %>% filter(Species=='versicolor') %>% head(10)");
  C.ReadKey();

  // Run next dplyr command 
  RunRCommand(rcom + "iris %>% filter(Species=='setosa') %>% head(10)");
  C.ReadKey();

  // Run dplyr command again
  RunRCommand(rcom + "iris %>% filter(Species=='virginica') %>% head(10)");
  C.ReadKey();
 }

 private static void RunRCommand(string command)
 {
  C.WriteLine("Running Command: " + command);
  // count execution time
  var watch = System.Diagnostics.Stopwatch.StartNew();
  // execute command
  var result = ExecuteR(command);
  watch.Stop();
  C.WriteLine(result);
  C.WriteLine("Elapsed time: " + watch.ElapsedMilliseconds + " msec.");
 }

 private static string ExecuteR(string rcommand)
 {
  try
  {
   if (rSession == null || !rSession.IsHostRunning)
    return "Error! R session is not available!";

   var result = rSession.ExecuteAndOutputAsync(rcommand);
   result.Wait();
   return result.Result.Output;
  }
  catch (Exception ex)
  {
   return ex.ToString();
  }
 }

 private static void Init()
 {
  try
  {
   C.WriteLine("Session starting...");
   // count execution time 
   var watch = System.Diagnostics.Stopwatch.StartNew();
   // create session 
   rSession = RHostSession.Create("RwrapperSession");
   // start session 
   var sessionStartTask = rSession.StartHostAsync(new RHostSessionCallback());
   sessionStartTask.Wait();
   watch.Stop();
   C.WriteLine("Started! Elapsed time: " + watch.ElapsedMilliseconds + " msec.");
  }
  catch (Exception ex)
  {
   C.WriteLine(ex.ToString());
  }
 }
}


The result looks as below.


   As you have seen, the output shows that first, we've loaded the R session, then a dplyr package. The loading time of the library was long in a first call. The remaining executions with a dplyr package were fast.

Running R script from C# program

No comments:
Post a Comment