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?
问题:
回答1:
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:
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();
回答3:
I would presume that C# has a function similar to system()
which would allow you to call scripts running via Rscript.exe
.
回答4:
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
回答5:
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");
}
}