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/