简体   繁体   English

如何使ExcelDNA与R.Net一起工作

[英]How to get ExcelDNA work with R.Net

I am a C# and R beginner trying to run the example http://mockquant.blogspot.com/2011/07/yet-another-way-to-use-r-in-excel-for.html 我是C#和R的初学者,尝试运行示例http://mockquant.blogspot.com/2011/07/yet-another-way-to-use-r-in-excel-for.html

<DnaLibrary RuntimeVersion="v4.0" Name="My First XLL" Language="CS">
<ExternalLibrary Path="R.NET.dll" />
<Reference Name="R.NET" />
<![CDATA[using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ExcelDna.Integration;
    using RDotNet;

    namespace CSLib
    {
        public class CSLib
        {
            static REngine rengine = null;
            static CSLib()
            {
                // Set the folder in which R.dll locates.
                REngine.SetDllDirectory(@"C:\Program Files\R\R-2.13.0\bin\i386");
                rengine = REngine.CreateInstance("RDotNet", new[] { "-q" });
            }            
            [ExcelFunction(Description = "get random numbers obey to normal distribution")]
            public static double [] MyRnorm(int number)
            {
                return (rengine.EagerEvaluate("rnorm(" + number + ")").AsNumeric().ToArray<double>());
            }
        }
    }

I have updated the link in the line SetDLLdirectory and I tried both 32bit and 64 bit versions of R (my cpu system is win7/64 bit) 我已经更新了SetDLLdirectory行中的链接,并尝试了32位和64位版本的R(我的CPU系统是win7 / 64位)

I tried with earlier stable versions of RDotNet and googled for updates to the example code, eg. 我尝试使用RDotNet的早期稳定版本,并用google搜索了示例代码的更新,例如。 here: 这里:

https://groups.google.com/d/msg/exceldna/7_wr8pwuCZ0/GLKlVFjr6l8J https://groups.google.com/d/msg/exceldna/7_wr8pwuCZ0/GLKlVFjr6l8J

    <DnaLibrary RuntimeVersion="v4.0" Name="My First XLL" Language="CS">
<ExternalLibrary Path="RDotNet.dll" />
<ExternalLibrary Path="RDotNet.NativeLibrary.dll" />
<Reference Name="RDotNet" />
<Reference Name="RDotNet.NativeLibrary" />
<![CDATA[

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExcelDna.Integration;
using RDotNet;

namespace CSLib
{
    public class CSLib
    {
        static REngine rengine = null;
        static CSLib()
        {
            // Set the folder in which R.dll locates.
            var oldPath = System.Environment.GetEnvironmentVariable("PATH");
            var rPath = @"C:\Program Files\R\R-3.0.1\bin\x64";
    var newPath = string.Format("{0}{1}{2}", rPath, System.IO.Path.PathSeparator, oldPath);

            System.Environment.SetEnvironmentVariable("PATH", newPath);
            rengine = REngine.CreateInstance("RDotNet");
        }            
        [ExcelFunction(Description = "get random numbers obey to normal distribution")]
        public static double [] MyRnorm(int number)
        {
            return (rengine.Evaluate("rnorm(" + number + ")").AsNumeric().ToArray<double>());
        }
    }
}

]]>
</DnaLibrary>

But I could not make it work... 但是我无法使其工作...

After trying the older versions of r.net I also tried the newest version with the old code and then I tried to adaptthe example code present on R.Net website to the code above, presuming that initialisation of r engine now uses the path in the registry: 在尝试了较旧版本的r.net之后,我还尝试了使用旧代码的最新版本,然后我尝试将R.Net网站上的示例代码改编为上述代码,并假设r引擎的初始化现在使用了注册表:

<DnaLibrary RuntimeVersion="v4.0" Name="R.NET" Description="R.NETExcel" Language="CS">
<Reference Path="RDotNet.NativeLibrary.dll"  />
<Reference Path="RDotNet.dll"  />
<Reference Path="DynamicInterop.dll"  />

<![CDATA[
using System;
using System.IO;
using System.Linq;
using RDotNet;
using DynamicInterop;

namespace CSLib
{
    public class CSLib
    {




        public static double[] MyRnorm(int number)
        {
        REngine.SetEnvironmentVariables(); 
        REngine engine = REngine.GetInstance(); 
            engine.Initialize();

        return (engine.Evaluate("rnorm(" + number + ")").AsNumeric().ToArray<double>());

        engine.Dispose();   
    }

    }
}
]]>

</DnaLibrary>

This is also giving no results. 这也没有结果。 Excel function retrns #num error. Excel函数修复#num错误。

I am certain that ExcelDNA works when I comment out the section trying to connect to R and paste some other simple function like sum two values. 我确信当我注释掉试图连接到R的部分并粘贴一些其他简单函数(例如,求和两个值)时,ExcelDNA可以工作。

I believe that my problems may be related to new developments in RdotNet making the example code above obsolete (eg. it could be new way of initialising REngine instance). 我相信我的问题可能与RdotNet的新发展有关,使上面的示例代码过时了(例如,它可能是初始化REngine实例的新方法)。 I am also wondering about the possibility of or 32 bit /64 bit conflict, that is why I also tried to make it work on 32 bit, win xp, dot.net 4.0 - with no results. 我也想知道是否存在32位/ 64位冲突的可能性,这就是为什么我也尝试使其在32位,win XP,dot.net 4.0上工作-没有结果。

What then should be the right way of connecting ExcelDNA to the current R.NET version? 那么将ExcelDNA连接到当前R.NET版本的正确方法是什么?

Thank you very much in advance for help. 预先非常感谢您的帮助。

These steps worked fine for me: 这些步骤对我来说很好:

  1. Ensure the R is installed. 确保已安装R。 In my Windows "Add or Remove Programs" list I see "R for Windows 3.02. 在我的Windows“添加或删除程序”列表中,我看到“ Windows 3.02R。

  2. Create a new "Class Library" project in Visual Studio. 在Visual Studio中创建一个新的“类库”项目。

  3. In the NuGet package Manager Console, execute the commands: 在NuGet软件包管理器控制台中,执行以下命令:

     PM> Install-Package Excel-DNA PM> Install-Package R.NET.Community 
  4. Add the following code to the main .cs file: 将以下代码添加到主.cs文件中:

     using System; using System.Linq; using ExcelDna.Integration; using ExcelDna.Logging; using RDotNet; namespace UsingRDotNet { public class AddIn : IExcelAddIn { public void AutoOpen() { MyFunctions.InitializeRDotNet(); } public void AutoClose() { } } public static class MyFunctions { static REngine _engine; internal static void InitializeRDotNet() { try { REngine.SetEnvironmentVariables(); _engine = REngine.GetInstance(); _engine.Initialize(); } catch (Exception ex) { LogDisplay.WriteLine("Error initializing RDotNet: " + ex.Message); } } public static double[] MyRnorm(int number) { return (_engine.Evaluate("rnorm(" + number + ")").AsNumeric().ToArray<double>()); } public static object TestRDotNet() { // .NET Framework array to R vector. NumericVector group1 = _engine.CreateNumericVector(new double[] { 30.02, 29.99, 30.11, 29.97, 30.01, 29.99 }); _engine.SetSymbol("group1", group1); // Direct parsing from R script. NumericVector group2 = _engine.Evaluate("group2 <- c(29.89, 29.93, 29.72, 29.98, 30.02, 29.98)").AsNumeric(); // Test difference of mean and get the P-value. GenericVector testResult = _engine.Evaluate("t.test(group1, group2)").AsList(); double p = testResult["p.value"].AsNumeric().First(); return string.Format("Group1: [{0}], Group2: [{1}], P-value = {2:0.000}", string.Join(", ", group1), string.Join(", ", group2), p); } } } 
  5. F5 to run the add-in in Excel. F5以在Excel中运行加载项。

  6. Enter the formula =TestRDotNet() and =MyRNorm(5)`. 输入公式= TestRDotNet() and = MyRNorm(5)`。 Numbers appear in Excel. 数字出现在Excel中。

I've added the "UsingRDotNet" project to the Excel-DNA Samples on GitHub . 我已经在GitHub上Excel-DNA Samples中添加了“ UsingRDotNet”项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM