我是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>());
            }
        }
    }


我已经更新了SetDLLdirectory行中的链接,并尝试了32位和64位版本的R(我的cpu系统是win7 / 64位)

我尝试使用RDotNet的早期稳定版本,并用google搜索了示例代码的更新,例如。这里:

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>


但是我无法使其工作...

在尝试了较旧版本的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>


这也没有结果。 Excel函数修复#num错误。

我确信当我注释掉试图连接到R的部分并粘贴一些其他简单函数(例如,求和两个值)时,ExcelDNA可以工作。

我相信我的问题可能与RdotNet的新发展有关,使上面的示例代码过时了(例如,它可能是初始化REngine实例的新方法)。我也想知道32位/ 64位冲突的可能性,这就是为什么我也尝试使其在32位,win XP,dot.net 4.0上工作-没有结果。

那么将ExcelDNA连接到当前R.NET版本的正确方法是什么?

预先非常感谢您的帮助。

最佳答案

这些步骤对我来说很好:


确保已安装R。在我的Windows“添加或删除程序”列表中,我看到“ Windows 3.02R。
在Visual Studio中创建一个新的“类库”项目。
在NuGet软件包管理器控制台中,执行以下命令:

PM> Install-Package Excel-DNA
PM> Install-Package R.NET.Community

将以下代码添加到主.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);
        }
    }
}

F5以在Excel中运行加载项。
输入公式= TestRDotNet()and = MyRNorm(5)`。数字出现在Excel中。


我已经将“ UsingRDotNet”项目添加到Excel-DNA Samples on GitHub

10-05 23:50