在C#中怎样调用R软件呢。R软件不只是一种统计工具,它还是一种语言,就语法形式而言跟S语言非常相识。所以类似与数据库一样,在客户端不是就只能调用一些函数,而是可以用数据库提供的SQL语言编写出拥有灵活多变,满足各种需求的功能。R语言也一样,可以在客户端,用S语言编写程序,传送到R软件,R软件计算完成后将结果在传回C#
。既然需要来回传送,必然需要中间的桥梁,就像数据库需要驱动程序一样,在C#中调用R软件,需要安装R(D)COM,R(D)COM是一种DCOM组件,可以注册到Windows的组件服务中,供程序调用。如果用C#开发Web程序,由于ASP.NET是用ASPNET这个用户在执行,而这个用户的权限很低,所以如果要调用R(D)COM的服务的化,需要给ASPNET授予权限。
所有具体的操作,使用方法,可以参考:
http://www.codeproject.com/KB/cs/RtoCSharp.aspx
----------------------------------------------------------------------------------------------------------------------------
1using System;
2using System.Configuration;
5namespace Common.Regression
6{
/** <summary>
/// IRegression 回归类接口
/// </summary>
public interface IRegression
{
double[,] Data
{
get;
set;
}
RegressionSummary Summary
{
get;
}
void DoRegression();
void ReleaseLock();
}
}
-------------------------------------------------------------------------
1using System;
2using STATCONNECTORSRVLib;
3using RServerManager;
4using System.Threading;
6namespace Common.Regression
7{
/** <summary>
/// BaseRegression 回归抽象基类
/// </summary>
public abstract class BaseRegression : IRegression
{
private static ServerPool mServerPool = null;
private ServerItem mServerItem = null;
private IStatConnector mStatConnector = null;
private static string mKey = "R";
private static string mClient = "this is client";
private static int mWaitTime = 50;
private static int mMaxLoop = 20;
private static int mMaxServerCount = 5;
private static int mServerCount = 0;
static BaseRegression()
{
if (mServerPool == null)
{
mServerPool = new ServerPool();
}
}
private double[,] mData;
public double[,] Data
{
get
{
return mData;
}
set
{
mData = value;
}
}
private RegressionSummary mSummary;
public RegressionSummary Summary
{
get
{
return mSummary;
}
set
{
mSummary = value;
}
}
/** <summary>
/// 执行回归函数
/// </summary>
public abstract void DoRegression();
/** <summary>
/// 得到执行R代码的连接
/// </summary>
/// <returns></returns>
protected IStatConnector GetStatConnector()
{
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
int count = 0;
while (mServerItem == null)
{
if (mServerCount < mMaxServerCount)
{
//当小于最小服务器数目时,增加连接
mStatConnector = new StatConnectorClass();
mStatConnector.Init(mKey);
mServerPool.Add(mStatConnector, mKey);
mServerCount++;
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
break;
}
if (count < mMaxLoop)
{
Thread.Sleep(mWaitTime);
count++;
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
}
else
{
return null;
}
}
mStatConnector = mServerItem.Server;
return mStatConnector;
}
/** <summary>
/// 释放锁定
/// </summary>
public void ReleaseLock()
{
if (mServerItem != null)
{
mServerItem.ReleaseLock();
}
}
public BaseRegression()
{
}
}
}
----------------------------------------------------------------------------------------
1using System;
2using System.Data;
3using System.Configuration;
4using STATCONNECTORSRVLib;
6namespace Common.Regression
7{
/** <summary>
/// LogicRegression 利用Logistic模型进行回归
/// </summary>
public class LogisticRegression : BaseRegression
{
private IStatConnector mStatConnector;
public LogisticRegression()
{
mStatConnector = GetStatConnector();
}
public override void DoRegression()
{
if (Data == null)
{
return;
}
mStatConnector.SetSymbol("dd", Data);
mStatConnector.EvaluateNoReturn("Y <- dd[,1]");
mStatConnector.EvaluateNoReturn("X <- dd[,-1]");
mStatConnector.EvaluateNoReturn("gr<-glm(Y~X , family=binomial(logit))");
mStatConnector.EvaluateNoReturn("ss<-summary(gr)");
Summary = new RegressionSummary(mStatConnector);
}
}
}
在http://cran.r-project.org/可以下载R软件,选择Other,下载R_Scilab_DCOM3.0-1B5.exe,就是R(D)COM。
在安装了R(D)COM之后,假设安装目录为“D:\Program Files\(D)COM Server\bin“。在该目录下有RServerManager.exe,在VS2008/2010中通过Add Reference->Browse,选择RServerManager.exe。添加以后,会增加RServerManager, ConnectorCommonLib,
每次创建一个StatConnectorClass对象时,都会启动一个服务,用于处理一个连接对象所提交的请求,这个资源不会自己停止,所以需要一个类似于连接池的服务管理器。在R(D)COM中提供了两个类ServerPool和ServerItem来完成服务管理的功能。下面的类封装了该操作。
2using STATCONNECTORSRVLib;
3using RServerManager;
4using System.Threading;
6namespace Common.Regression
7{
/** <summary>
/// BaseRegression 回归抽象基类
/// </summary>
public abstract class BaseRegression : IRegression
{
private static ServerPool mServerPool = null;
private ServerItem mServerItem = null;
private IStatConnector mStatConnector = null;
17 private static string mKey = "R";
private static string mClient = "this is client";
private static int mWaitTime = 50;
private static int mMaxLoop = 20;
private static int mMaxServerCount = 5;
private static int mServerCount = 0;
24 static BaseRegression()
{
if (mServerPool == null)
{
mServerPool = new ServerPool();
}
}
32 private double[,] mData;
public double[,] Data
{
get
{
return mData;
}
set
{
mData = value;
}
}
45 private RegressionSummary mSummary;
public RegressionSummary Summary
{
get
{
return mSummary;
}
set
{
mSummary = value;
}
}
58 /** <summary>
/// 执行回归函数
/// </summary>
public abstract void DoRegression();
63 /** <summary>
/// 得到执行R代码的连接
/// </summary>
/// <returns></returns>
protected IStatConnector GetStatConnector()
{
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
int count = 0;
while (mServerItem == null)
{
if (mServerCount < mMaxServerCount)
{
//当小于最小服务器数目时,增加连接
mStatConnector = new StatConnectorClass();
mStatConnector.Init(mKey);
mServerPool.Add(mStatConnector, mKey);
mServerCount++;
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
break;
}
if (count < mMaxLoop)
{
Thread.Sleep(mWaitTime);
count++;
mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
}
else
{
return null;
}
}
95 mStatConnector = mServerItem.Server;
return mStatConnector;
}
100 /** <summary>
/// 释放锁定
/// </summary>
public void ReleaseLock()
{
if (mServerItem != null)
{
mServerItem.ReleaseLock();
}
}
public BaseRegression()
{
}
}
}
从BaseRegression继承的类将拥有可以被管理。
using System;
using System.Configuration;
namespace Common.Regression
{
/// <summary>
/// IRegression 回归类接口
/// </summary>
public interface IRegression
{
double[,] Data
{
get;
set;
}
RegressionSummary Summary
{
get;
}
void DoRegression();
void ReleaseLock();
}
}