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的程序。否则会报错。代码中会详细介绍。
(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/
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/