2010-12-20 17 views
9

Tengo un programa C# que genera algún código R. En este momento, guardo el script en un archivo y luego lo copio/pego en la consola R. Sé que hay una interfaz COM para R, pero no parece funcionar con la última versión de R (o cualquier versión posterior a 2.7.8). ¿Hay alguna manera de que pueda ejecutar mediante programación el script R desde C# después de guardarlo en un archivo?Ejecutando el script R programáticamente

Respuesta

6

Para hacer esto en C# tendrá que utilizar

shell (R CMD BATCH myRprogram.R) 

Asegúrese de envolver sus parcelas como esto

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

o imagen envoltorios

+0

bien, así que ahora tengo: filled.contour (...) savePlot ("heatmap1.png", type = "png") ¿Estás sugiriendo lo cambio a: png ("heatmap1. png ") filled.contour (...) dev.off() –

+0

¡Eso funcionó! ¡Gracias! –

+0

Si tiene parcelas de celosía o ggplot2, probablemente necesitará usar print() alrededor de las declaraciones de parcelas. –

2

Supongo que C# tiene una función similar a system() que le permite llamar a los scripts que se ejecutan a través de Rscript.exe.

+0

Pensé en eso, excepto cuando ejecuto el script usando Rscript, no guarda los gráficos correctamente. El script crea una colección de heatmaps y guarda los gráficos en diferentes archivos. Cuando ejecuto Rscript, solo guarda la última imagen en un archivo pdf en lugar de los archivos png separados que obtengo al ejecutar a través del IDE. –

+1

Así es como R funciona de manera interactiva versus no interactiva. Abra dispositivos como 'pdf()' o 'png()' o 'jpeg()' o ... explícitamente con argumentos de nombre de archivo. –

+0

Pensé que estaba haciendo eso: savePlot ("heatmap1.png", type = "png"); –

1

Nuestra solución basada en esta respuesta en stackoverflow Call R (programming language) from .net

Con mono Para cambiar, enviamos el código R de la cadena y lo guardamos en el archivo temporal, ya que el usuario ejecuta un código R personalizado cuando es necesario.

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); 
      } 
     } 
    } 
} 

completa entrada en el blog: http://kostylizm.blogspot.ru/2014/05/run-r-code-from-c-sharp.html

7

Aquí está la clase Hace poco escribí para este propósito. También se puede pasar y devolver argumentos de C# y 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); 
      } 
    } 
} 

NOTA: Es posible que desee añadir el siguiente código a que, si está interesado en la limpieza del proceso.

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

+0

No funciona para mí, y no limpia nuevas instancias cmd * .exe - vea http://stackoverflow.com/questions/8559956/c-sharp-process-start-failed-to-dispose-thread-resources –

+0

Lo uso todo el tiempo. Es probable que tenga un problema con rScriptExecutablePath (es posible que el proceso no tenga acceso a la ruta exe completa o que necesite crear una variable de entorno para Rscript.exe), el código R que está intentando ejecutar (si falla el código R, verá no hay resultados o error), o podría estar perdiendo Rscript.exe. –

0

Aquí es una forma sencilla de lograr esto,

Mi RSCRIPT se encuentra en:

C: \ Archivos de programa \ R \ R-3.3.1 \ bin \ Rscript.exe

R Código se encuentra en:

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"); 
     } 
      } 
Cuestiones relacionadas