6

I'd like to know if its possible to run an Rscript while passing in a list of values, have that R script run and then output a resluting list of values back to c#.

I've seen people say that R.NET is good but I've only seen examples of using it to create values directly, manipulate them, access them etc when what I want to do is run already created scripts that will take in data, process it and return data. I also know that I could do this with csv files but the point is I would like to cut out the middle man.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
EvilWeebl
  • 689
  • 1
  • 8
  • 16

1 Answers1

5

This question is about 5 years old and there are some answers available for this like here. I will go through it with a very simple R script.

It is good to start with this link

In this simple example, I pass 3 to R, add it with 5 and get the result (8) back.

Steps

  1. Create a text file as name.r, with your r code, something like below. I named it as rcodeTest.r

    library(RODBC) # you can write the results to a database by using this library
    args = commandArgs(trailingOnly = TRUE) # allows R to get parameters
    cat(as.numeric(args[1])+5)# converts 3 to a number (numeric)
    

Then create a c# class (call it anything, I called it RScriptRunner) like below, also available at here. This is a simple class which just calls a procedure (an exe file)

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Web;

    /// <summary>
    /// Summary description for RScriptRunner
    /// </summary>
    public class RScriptRunner
    {
        public RScriptRunner()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        // Runs an R script from a file using Rscript.exe.
        /// 
        /// Example: 
        ///
        ///   RScriptRunner.RunFromCmd(curDirectory +         @"\ImageClustering.r", "rscript.exe", curDirectory.Replace('\\','/'));
        ///   
        /// Getting args passed from C# using R:
        ///
        ///   args = commandArgs(trailingOnly = TRUE)
        ///   print(args[1]);
        ///  
        ///   
        /// rCodeFilePath          - File where your R code is located.
        /// rScriptExecutablePath  - Usually only requires "rscript.exe"
        /// args                   - Multiple R args can be seperated by spaces.
        /// Returns                - a string with the R responses.
        public static string RunFromCmd(string rCodeFilePath, string         rScriptExecutablePath, string args)
        {
            string file = rCodeFilePath;
            string result = string.Empty;

            try
            {

                var info = new ProcessStartInfo();
                info.FileName = rScriptExecutablePath;
                info.WorkingDirectory =         Path.GetDirectoryName(rScriptExecutablePath);
                info.Arguments = rCodeFilePath + " " + args;

                info.RedirectStandardInput = false;
                info.RedirectStandardOutput = true;
                info.UseShellExecute = false;
                info.CreateNoWindow = true;

                using (var proc = new Process())
                {
                    proc.StartInfo = info;
                    proc.Start();
                    result = proc.StandardOutput.ReadToEnd();

                }

                return result;
            }
            catch (Exception ex)
            {
                throw new Exception("R Script failed: " + result, ex);
            }
        }
    }

Then call and pass parameters like

     result = RScriptRunner.RunFromCmd(path + @"\rcodeTest.r", @"D:\Programms\R-3.3.3\bin\rscript.exe", "3");

rscript.exe is located in your R directory, and path is the location of your r script (rcodeTest.r)

Now you can have the result 8=5+3 as output as shown below. enter image description here

Mohsen Sichani
  • 1,002
  • 12
  • 33
  • My Rscript return data.frame with header and 3 rows. how do I read it? – Janatbek Orozaly Dec 07 '17 at 18:25
  • 1
    Do you have any restriction for using a database? If not, create a table and store the values in this table (R) , and pass the table name to your script (C#). or just use a predefined table and schema. You may need to use RODBC package in R for this. – Mohsen Sichani Dec 08 '17 at 00:31
  • I do have read permission now, but I have to ask for write permission. but is there a way to read the output as is? without saving it in DB? or prepare the whole table as a string and send it as a string? I am lost. I Also created a rest API with plumber, it is returning me the expected JSON result, but it's single threaded, so only one process allowed at a time. – Janatbek Orozaly Dec 08 '17 at 16:52
  • 2
    Not sure but guess the easiest way is DB or write it to a file. A data type equivalent to data frame is required if you pass the output as a dataframe, which I do not think exist (Might be defined as a class or https://stackoverflow.com/questions/13590478/data-structure-similar-to-data-frames-in-r ). Another way is to convert the data frame to a string (like JSON) as you mentioned and then decode that. If you find a way please share – Mohsen Sichani Dec 12 '17 at 18:09
  • 1
    just creating a temp file from c#, passing to rscript the name of the file, witing to it and returning back the signal string that file is created and has been written – Janatbek Orozaly Dec 12 '17 at 19:03