15

I have a C# program that generates some R code. Right now I save the script to file and then copy/paste it into the R console. I know there is a COM interface to R, but it doesn't seem to work with the latest version of R (or any version after 2.7.8). Is there some way I can just programmatically execute the R script from C# after saving it to file?

    5 Answers 5

    12

    Here is the class I recently wrote for this purpose. You can also pass in and return arguments from C# and R:

    /// <summary> /// This class runs R code from a file using the console. /// </summary> public class RScriptRunner { /// <summary> /// 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]); /// </summary> /// <param name="rCodeFilePath">File where your R code is located.</param> /// <param name="rScriptExecutablePath">Usually only requires "rscript.exe"</param> /// <param name="args">Multiple R args can be seperated by spaces.</param> /// <returns>Returns a string with the R responses.</returns> 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); } } } 

    NOTE: You may want to add the following to you code, if you are interested in cleaning up the process.

    proc.CloseMainWindow(); proc.Close();

    2
    • Does not work for me, and does not clean up new cmd*.exe instances - see stackoverflow.com/questions/8559956/…CommentedJun 30, 2015 at 14:21
    • I use it all the time. You likely have an issue with rScriptExecutablePath (you process may not have access to the full exe path or you need to create an environment variable for Rscript.exe) , the R code you are trying to run (if the R code fails you will see no results or error), or you could be missing Rscript.exe.
      – Jake Drew
      CommentedJun 30, 2015 at 15:02
    7

    To do this in C# you'll need to use

    shell (R CMD BATCH myRprogram.R) 

    Be sure to wrap your plots like this

    pdf(file="myoutput.pdf") plot (x,y) dev.off() 

    or image wrappers

    2
    • Okay, so right now I have: filled.contour(...) savePlot("heatmap1.png", type="png") You're suggesting I change it to: png("heatmap1.png") filled.contour(...) dev.off()CommentedDec 20, 2010 at 1:16
    • 1
      If you have lattice or ggplot2 plots, you will probably need to use print() around plot statements.CommentedDec 20, 2010 at 10:13
    2

    Here is a simple way to achieve that,

    My Rscript is located at:

    C:\Program Files\R\R-3.3.1\bin\RScript.exe

    R Code is at :

    C:\Users\lenovo\Desktop\R_trial\withoutALL.R

     using System; using System.Diagnostics; public partial class Rscript_runner : System.Web.UI.Page { protected void Button1_Click(object sender, EventArgs e) { Process.Start(@"C:\Program Files\R\R-3.3.1\bin\RScript.exe","C:\\Users\\lenovo\\Desktop\\R_trial\\withoutALL.R"); } } 
      1

      I would presume that C# has a function similar to system() which would allow you to call scripts running via Rscript.exe.

      4
      • I thought of that, except when I run the script using Rscript, it doesn't save the plots properly. The script creates a collection of heatmaps and saves the plots to different files. When I run Rscript, it just saves the last picture in a pdf file instead of the separate png files I get when executing through the IDE.CommentedDec 20, 2010 at 0:48
      • 1
        That's how R works interactively versus non-interactively. Open devices like pdf() or png() or jpeg() or ... explicitly with filename arguments.CommentedDec 20, 2010 at 0:56
      • I thought I was doing that: savePlot("heatmap1.png", type="png");CommentedDec 20, 2010 at 1:03
      • 1
        As I said once before, there is a difference between interactive mode (where savePlot() has a meaning) and non-interactive mode where you open devices.CommentedDec 20, 2010 at 3:12
      1

      Our solution based on this answer on stackoverflow Call R (programming language) from .net

      With monor change, we send R code from string and save it to temp file, since user run custom R code when needed.

      public static void RunFromCmd(string batch, params string[] args) { // Not required. But our R scripts use allmost all CPU resources if run multiple instances lock (typeof(REngineRunner)) { string file = string.Empty; string result = string.Empty; try { // Save R code to temp file file = TempFileHelper.CreateTmpFile(); using (var streamWriter = new StreamWriter(new FileStream(file, FileMode.Open, FileAccess.Write))) { streamWriter.Write(batch); } // Get path to R var rCore = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\R-core") ?? Registry.CurrentUser.OpenSubKey(@"SOFTWARE\R-core"); var is64Bit = Environment.Is64BitProcess; if (rCore != null) { var r = rCore.OpenSubKey(is64Bit ? "R64" : "R"); var installPath = (string)r.GetValue("InstallPath"); var binPath = Path.Combine(installPath, "bin"); binPath = Path.Combine(binPath, is64Bit ? "x64" : "i386"); binPath = Path.Combine(binPath, "Rscript"); string strCmdLine = @"/c """ + binPath + @""" " + file; if (args.Any()) { strCmdLine += " " + string.Join(" ", args); } var info = new ProcessStartInfo("cmd", strCmdLine); 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(); } } else { result += "R-Core not found in registry"; } Console.WriteLine(result); } catch (Exception ex) { throw new Exception("R failed to compute. Output: " + result, ex); } finally { if (!string.IsNullOrWhiteSpace(file)) { TempFileHelper.DeleteTmpFile(file, false); } } } } 

      Full blog post: http://kostylizm.blogspot.ru/2014/05/run-r-code-from-c-sharp.html

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.