您的位置:首页 > 编程语言 > C#

C#调用R软件:R(D)COM

2013-12-03 09:29 507 查看
在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,
STATCONNECTORSEVLib三个引用。可以通过VS2008的对象察看器看三个引用中的类和函数。

每次创建一个StatConnectorClass对象时,都会启动一个服务,用于处理一个连接对象所提交的请求,这个资源不会自己停止,所以需要一个类似于连接池的服务管理器。在R(D)COM中提供了两个类ServerPool和ServerItem来完成服务管理的功能。下面的类封装了该操作。
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;

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();

}



}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: