2015-03-26 7 views
2

Я C# и начинающий R пытается запустить пример http://mockquant.blogspot.com/2011/07/yet-another-way-to-use-r-in-excel-for.htmlКак получить ExcelDNA работу с R.Net

<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 (моя система процессора - win7/64 бит)

Я пробовал с более ранними стабильными версиями RDotNet и искал обновления для кода примера, например. здесь:

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 я также попробовал новую версию со старым кодом, а затем я попытался adaptthe пример кода, присутствующего на сайте R.Net в коде выше, предполагая, что инициализацию г двигатель теперь использует путь в реестре:

<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 ошибку.

Я уверен, что ExcelDNA работает, когда я прокомментирую раздел, пытающийся подключиться к R и вставить другую простую функцию, такую ​​как сумма двух значений.

Я считаю, что мои проблемы могут быть связаны с новыми разработками в RdotNet, делая примерный код выше устаревшего (например, это может быть новый способ инициализации экземпляра REngine). Я также задаюсь вопросом о возможности конфликта 32 бит/64 бит, поэтому я также попытался заставить его работать с 32-разрядным, win xp, dot.net 4.0 - без каких-либо результатов.

Какой должен быть правильный способ подключения ExcelDNA к текущей версии R.NET?

Благодарим вас за помощь.

+0

У вас есть сам R? – Govert

+0

Вы можете получить #NUM из своего последнего примера, если вы вызываете его с помощью 0 или опускаете параметр в формуле Excel и называете его '= MyRnorm()'. Это верно. – Govert

ответ

3

Эти шаги работали отлично для меня:

  1. Убедитесь, установлен R. В моем Windows «Установка и удаление программы» список, который я вижу «R для ОС Windows 3.02.

  2. Создать новый„проект библиотеки классов“в Visual Studio.

  3. В пакете NuGet Manager Console, выполните команды :

    PM> Install-Package Excel-DNA 
    PM> Install-Package R.NET.Community 
    
  4. Добавьте следующий код к основному .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, чтобы запустить надстройку я n в Excel.

  6. Введите формулу = TestRDotNet() and = MyRNorm (5) `. Числа отображаются в Excel.

Я добавил проект "UsingRDotNet" в Excel-DNA Samples on GitHub.

+0

Теперь он работает !!! Я использовал ваш код плюс я переустановил пакет R. Похоже, что путь теперь считывается из реестра Windows. И ранее я не отмечал «Write R version number to registry» во время установки. Решение нуждается в этой записи для работы. Благодарим за помощь. Я буду использовать ваш пример в качестве шаблона для дальнейшего приключения с R в Excel! Я хотел бы спросить, возможно ли изменить пример, чтобы относительный путь мог быть прочитан переносимым R (http://sourceforge.net/projects/rportable/), например. копию R, хранящуюся в подпапке компиляции. –

+1

Если вы выясните, как бороться с переносной установкой R, я был бы рад принять запрос на перенос, который обновляет образец ;-) – Govert

+0

Теперь я переношу портативный R со следующего сайта: http: // sourceforge. net/projects/rportable/(также предлагается портативная R-Studio. Единственный способ, который приходит мне на ум, на моем уровне, - это нести со мной шаблонный файл reg. Идеально было бы по-прежнему быть в состоянии укажите в программе C#, где путь (в качестве альтернативы чтению реестра Windows). И тогда, возможно, можно будет указать относительный путь к самой программе, подпапку с R-портативной. –

Смежные вопросы