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

Posted on 2008-11-21 17:57  封维波  阅读(2684)  评论(0)    收藏  举报

R软件是一款功能强大的统计软件,而且是开源项目,所以如果没有银子买SAS这样的系统的时候, R软件是最好的选择。但是不要以为免费的东西就是粗制滥造,R软件绝对不逊色与其它众多的商业统计软件,同Linux一样,拥有众多支持者的R软件一直在成长,不断的有新的软件包加入到R软件的程序库里。到目前为止,R软件的软件包覆盖了统计计算的所有领域,从传统的回归分析到前沿的金融时间序列分析都有。

C#是Microsoft公司推出的新一代程序编程语言,不仅是纯粹的面向对象,而且在VS 2005的支持下,拥有快速开发应用程序的能力,集成了大量的控件,不论是开发Windows程序,还是开发Web应用,均相当出色。所以,使用C#来开发我们的应用,是明智的选择。

统计模型在开发应用的过程中,特别是对银行、证卷和保险这些行业,都有着非常广泛的应用。不过,对于这些行业的从业者而言,掌握行业知识、统计知识和计算机能力的人很少。即使拥有这些能力,做这些工作也是相当耗费精力和时间的。所以开发出这些行业有针对性的行业软件就非常的重要。除了能够降低使用门槛,减轻工作负担以外,关键是能够跟即时。快速的对市场和行情做出决策是相当重要的。利用C#做应用程序,R软件做后台的统计分析,这是我们的想法。试想如果自己用代码去实现一个简单的统计回归,检验分析,绝对不是一件容易的事情。

在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;
 3
 4
 5namespace Common.Regression
 6{
 7    /// <summary>
 8    /// IRegression 回归类接口
 9    /// </summary>

10    public interface IRegression
11    {
12        double[,] Data
13        {
14            get;
15            set;
16        }

17
18        RegressionSummary Summary
19        {
20            get;
21        }

22
23        void DoRegression();
24
25        void ReleaseLock();
26
27
28    }

29
30}

 

  1using System;
  2using STATCONNECTORSRVLib;
  3using RServerManager;
  4using System.Threading;
  5
  6namespace Common.Regression
  7{
  8    /// <summary>
  9    /// BaseRegression 回归抽象基类
 10    /// </summary>

 11    public abstract class BaseRegression : IRegression
 12    {
 13        private static ServerPool mServerPool = null;
 14        private ServerItem mServerItem = null;
 15        private IStatConnector mStatConnector = null;
 16
 17        private static string mKey = "R";
 18        private static string mClient = "this is client";
 19        private static int mWaitTime = 50;
 20        private static int mMaxLoop = 20;
 21        private static int mMaxServerCount = 5;
 22        private static int mServerCount = 0;
 23
 24        static BaseRegression()
 25        {
 26            if (mServerPool == null)
 27            {
 28                mServerPool = new ServerPool();
 29            }

 30        }

 31
 32        private double[,] mData;
 33        public double[,] Data
 34        {
 35            get
 36            {
 37                return mData;
 38            }

 39            set
 40            {
 41                mData = value;
 42            }

 43        }

 44
 45        private RegressionSummary mSummary;
 46        public RegressionSummary Summary
 47        {
 48            get
 49            {
 50                return mSummary;
 51            }

 52            set
 53            {
 54                mSummary = value;
 55            }

 56        }

 57
 58        /// <summary>
 59        /// 执行回归函数
 60        /// </summary>

 61        public abstract void DoRegression();
 62
 63        /// <summary>
 64        /// 得到执行R代码的连接
 65        /// </summary>
 66        /// <returns></returns>

 67        protected IStatConnector GetStatConnector()
 68        {
 69            mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
 70            int count = 0;
 71            while (mServerItem == null)
 72            {
 73                if (mServerCount < mMaxServerCount)
 74                {
 75                    //当小于最小服务器数目时,增加连接
 76                    mStatConnector = new StatConnectorClass();
 77                    mStatConnector.Init(mKey);
 78                    mServerPool.Add(mStatConnector, mKey);
 79                    mServerCount++;
 80                    mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
 81                    break;
 82                }

 83                if (count < mMaxLoop)
 84                {
 85                    Thread.Sleep(mWaitTime);
 86                    count++;
 87                    mServerItem = mServerPool.GetServerExclusive(mKey, mClient);
 88                }

 89                else
 90                {
 91                    return null;
 92                }

 93            }

 94
 95            mStatConnector = mServerItem.Server;
 96            return mStatConnector;
 97           
 98        }

 99
100        /// <summary>
101        /// 释放锁定
102        /// </summary>

103        public void ReleaseLock()
104        {
105            if (mServerItem != null)
106            {
107                mServerItem.ReleaseLock();
108            }

109        }

110
111        public BaseRegression()
112        {           
113        }

114    }

115
116}

 

 

 

 1using System;
 2using System.Data;
 3using System.Configuration;
 4using STATCONNECTORSRVLib;
 5
 6namespace Common.Regression
 7{
 8    /// <summary>
 9    /// LogicRegression 利用Logistic模型进行回归
10    /// </summary>

11    public class LogisticRegression : BaseRegression
12    {
13        private IStatConnector mStatConnector;
14        public LogisticRegression()
15        {
16            mStatConnector = GetStatConnector();
17        }

18
19        public override void DoRegression()
20        {
21            if (Data == null)
22            {
23                return;
24            }

25          
26            mStatConnector.SetSymbol("dd", Data);
27            mStatConnector.EvaluateNoReturn("Y <- dd[,1]");
28            mStatConnector.EvaluateNoReturn("X <- dd[,-1]");
29
30            mStatConnector.EvaluateNoReturn("gr<-glm(Y~X , family=binomial(logit))");
31            mStatConnector.EvaluateNoReturn("ss<-summary(gr)");
32
33            Summary = new RegressionSummary(mStatConnector);
34            
35        }

36    }

37
38}

 

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3