C#通过R.Net调用R程序

R是一种面向统计学的开源编程语言和软件环境,它由语言,以及带调试器、绘图、系统函数访问和脚本的运行时环境组成。如果想在C#程序中调用R语言执行一些统计分析的功能,得到结果为自己使用,我们可以使用R.Net或者R(D)COM,在这里我只介绍R.NetR.Net是连接R..NET Framework的桥梁,要使用R.Net需要.NET Framework 4R安装环境下的native R DLLs(也就是说你需要安装R程序),R.Net可以在Windows, Linux MacOS下运行。

一、开发环境设置

(1)VS环境必须是.NET Framework 4及以上版本才可以

(2)安装R软件,R软件会有x64x86两个版本,在你的项目中会设置开发平台。如果你的vs项目设置的是x86,使用R.Net只能调用x86的程序;如果你的vs项目设置的是x64,使用R.Net只能调用x64的程序。否则会报错。代码中会详细介绍。

 

(3)在项目中添加R.Net引用

可以参考官网怎么添加引用http://rdotnet.codeplex.com/documentation

       

二、C#调用R.Net代码

(1)获取R程序路径

private void LoadRPath(string RVersion = "R-3.2.1")//默认R-3.2.1

{

    string dlldir = @"C:\Program Files\R\" + RVersion + @"\bin\x64";//默认64位

    bool r_located = false;

    var rPath = System.Environment.Is64BitProcess ?

    string.Format(@"C:\Program Files\R\" + RVersion + @"\bin\x64") :

    tring.Format(@"C:\Program Files\R\" + RVersion + @"\bin\i386");

    dlldir = rPath;

    while (r_located == false)

    {

       try

       {

           REngine.SetEnvironmentVariables(dlldir);

           r_located = true;

       }

       catch

       {

           if (System.Environment.Is64BitProcess)

           {

              MessageBox.Show(@"找不到R运行环境:\R\" + RVersion + @"\bin\x64 " + " \n请手动添加文件夹目录");

            }

            else

            {

               MessageBox.Show(@"找不到R运行环境:\R\" + RVersion + @"\bin\i386" + " \n请手动添加文件夹目录");

            }

            FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();

            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)

            {

                 dlldir = @folderBrowserDialog1.SelectedPath;

            }

       }

   }

}

这里需要判断R使用的是x86还是x64版本,因为R.Net依赖你的项目平台是x86还是x64

 

(2)调用R.Net具体代码

使用R.Net执行R语言其实就engine.Evaluate()里面执行R语句,如:

engine.Evaluate("dataset<-read.table(file.choose(),header=TRUE, sep = ',')");

可以将其结果转换为对应于R.Net或者.Net的数据结构。

a.读取文件表格数据

    

private void button1_Click(object sender, EventArgs e)

{

   dataGridView1.DataSource = null;

   dataGridView1.Refresh();

   try

   {

      engine.Evaluate("dataset<-read.table(file.choose(),header=TRUE, sep = ',')");

      DataFrame dataset = engine.Evaluate("dataset").AsDataFrame();

      engine.SetSymbol("dataset", dataset);

      for (int i = 0; i < dataset.ColumnCount; ++i)

      {

          dataGridView1.ColumnCount++;

          dataGridView1.Columns[i].Name = dataset.ColumnNames[i];

      }

      for (int i = 0; i < dataset.RowCount; ++i)

      {

          dataGridView1.RowCount++;

          dataGridView1.Rows[i].HeaderCell.Value = dataset.RowNames[i];

 

          for (int k = 0; k < dataset.ColumnCount; ++k)

          {

             dataGridView1[k, i].Value = dataset[i, k];

          }

      }

  }

  catch

  {

      MessageBox.Show(@"Equation error.");

  }

}

b、绘制直方图

 private void button2_Click(object sender, EventArgs e)

 {

      var x = engine.Evaluate("x <- rnorm(100, mean=50, sd=10)").AsNumeric();

      engine.Evaluate("hist(x)");

 }

     

c、绘制三维图

 private void button4_Click(object sender, EventArgs e)

 {

    var x = engine.Evaluate("x <- 1:100").AsNumeric();

    var y = engine.Evaluate("y <- 5:105").AsNumeric();

    engine.Evaluate("model = function                                                                                     (a,b){23.86+5.525*b-2.5725*a-6.6413*b^2-5.1862*a^2}"); //evaluate function

    engine.Evaluate("z = outer(x, y ,model)");

    engine.Evaluate("persp(x,y,z)");

 }

          

d、绘制等值线图

 private void button5_Click(object sender, EventArgs e)

 {

    var x = engine.Evaluate("x <- 1:100").AsNumeric();

    var y = engine.Evaluate("y <- 5:105").AsNumeric();

    engine.Evaluate("model = function (a,    b){23.86+5.525*b-2.5725*a-6.6413*b^2-5.1862*a^2}"); //evaluate function

    engine.Evaluate("z = outer(x, y ,model)");

    engine.Evaluate("contour(x,y,z, nlevels = 10)");    

 }

         

e、绘制直线图

 

 

 private void button7_Click(object sender, EventArgs e)

 {

      if (engine.IsRunning == false)

      {

           engine.Initialize();

      }

      List<double> x;

      double[,] y=new double[5,5];

      x = new List<double>();

      for(int i=0;i<5;i++)

      {

         x.Add(i);

         for (int j = 0; j < 4; j++)

         {

             y[i, j] = i+i *i+5+j;

         }

      }   

      var v1 = engine.CreateNumericVector(x);

      var v2 = engine.CreateNumericMatrix(y);

      engine.SetSymbol("v1", v1);

      engine.SetSymbol("v2", v2);

 

        engine.Evaluate("require('ggplot2')");

        engine.Evaluate("library('ggplot2')");

        engine.Evaluate("my_data <- data.frame(v2)");

        engine.Evaluate("colnames(my_data) <- c('Price', 'Quantity')");

        engine.Evaluate("myChart <- ggplot(my_data, aes(x=Price, y=Quantity)) + geom_line()");

        engine.Evaluate("print(myChart)");

 }

      

f、读取R脚本

engine.Evaluate("source('c:/src/path/to/myscript.r')");

可以直接将R语言要执行的代码写成脚本文件,然后直接执行R脚本。

 

 

三、数据类型对应表

R

R.NET

.NET Framework

Note

character vector

RDotNet.CharacterVector

System.String[]

 

integer vector

RDotNet.IntegerVector

System.Int32[]

The minimum value in R is -2^31+1 while that of .NET Framework is -2^31. Missing values are int.MinValue

real vector

RDotNet.NumericVector

System.Double[]

Missing values are represented as double.NaN

complex vector

RDotNet.ComplexVector

System.Numerics.Complex[]

System.Numerics assembly is required for .NET Framework 4.

raw vector

RDotNet.RawVector

System.Byte[]

 

logical vector

RDotNet.LogicalVector

System.Boolean[]

 

character matrix

RDotNet.CharacterMatrix

System.String[, ]

 

integer matrix

RDotNet.IntegerMatrix

System.Int32[, ]

The minimum value in R is -2^31+1 while that of .NET Framework is -2^31.

real matrix

RDotNet.NumericMatrix

System.Double[, ]

 

complex matrix

RDotNet.ComplexMatrix

System.Numerics.Complex[, ]

Reference to System.Numerics assembly is required.

raw matrix

RDotNet.RawMatrix

System.Byte[, ]

 

logical matrix

RDotNet.LogicalMatrix

System.Boolean[, ]

 

list

RDotNet.GenericVector

 

From version 1.1.

data frame

RDotNet.GenericVector

 

From version 1.1. RDotNet.DataFrame class is also available (below).

data frame

RDotNet.DataFrame

 

From version 1.3. And from version 1.5.3,DataFrameRowAttribute and DataFrameColumnAttribute are available for data mapping.

function

RDotNet.Function

 

From version 1.4. Including closure, built-in function, and special function.

factor

RDotNet.Factor

System.Int32[]

From version 1.5.2.

S4

RDotNet.S4Object

 

Not Available Yet. See S4 branch in the source control.

 

四、参考资料及网站

1、添加引用及样例代码 http://rdotnet.codeplex.com/documentation

2、R.Net源码 https://github.com/jmp75/rdotnet

3、老外的简单例子 https://psychwire.wordpress.com/tag/r-net/

4、https://psychwire.wordpress.com/category/r/

5、http://stackoverflow.com/questions/17548072/generate-an-r-timeseries-in-c-sharp-for-use-with-rdotnet?rq=1

6、http://stackoverflow.com/questions/26233526/multi-windows-r-graphs-in-c-sharp-with-rdotnet?rq=1

7、http://stackoverflow.com/questions/18055820/rdotnet-vs-r-scripting?rq=1

8、R软件下载 https://www.r-project.org/

posted @ 2015-08-22 14:37 羽过天晴 阅读(...) 评论(...) 编辑 收藏