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

一、开发环境设置

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

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

 

android r文件调用函数 调用r软件_System

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

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

       

android r文件调用函数 调用r软件_android r文件调用函数_02

二、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.读取文件表格数据

   

android r文件调用函数 调用r软件_lua_03

 

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、绘制直方图

android r文件调用函数 调用r软件_android r文件调用函数_04

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、绘制三维图

android r文件调用函数 调用r软件_Click_05

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、绘制等值线图

android r文件调用函数 调用r软件_Click_06

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、绘制直线图

android r文件调用函数 调用r软件_System_07

 

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.