LoginSignup
1
2

More than 5 years have passed since last update.

R.NETをExcelから動作させる 2017年版

Last updated at Posted at 2017-01-18

R.NETをExcelから呼び出す手法は

などで紹介されていますが、最近の環境だと動かなくなっているので、試行錯誤してみた結果を共有します。

ちなみにExcelは事情により2010を使っているので、最新版とかでどうなるかは未検証です。

準備

  • .NET Framework 4.0

  • R (https://www.r-project.org/)
    試したのは3.3.2です。

  • R.NET (http://rdotnet.codeplex.com/)
    NuGetパッケージ(ZIP圧縮)からdllを抽出し、下記DNAファイルと同じ場所に置いておく。

  • DynamicInterop
    NuGetパッケージからDynamicInterop.dllを抽出して、下記DNAファイルと同じ場所に置いておく。

  • Excel-DNA (http://excel-dna.net/)
    NuGetパッケージからxllとdllとを抽出し、ExcelDna.xllをUsingRdotNet.xllにリネーム。
    ExcelDna.Integration.dllを一緒に、下記DNAファイルと同じ場所に置いておく。

  • DNAファイル
    下記をテキストファイル(UTF-8推奨)で作成。

UsingRdotNet.dna
<DnaLibrary RuntimeVersion="v4.0" Name="R.NET" Description="R.NETをExcelから動作させる" Language="CS">
<Reference Path="ExcelDna.Integration.dll"  />
<Reference Path="RDotNet.NativeLibrary.dll"  />
<Reference Path="RDotNet.dll"  />
<Reference Path="DynamicInterop.dll"  />

<![CDATA[
using System;
using System.IO;
using System.Linq;
using ExcelDna.Integration;
using ExcelDna.Logging;
using RDotNet;

namespace UsingRDotNet
{
    public static class MyFunctions
    {
        static REngine _engine;
        static MyFunctions() // 静的コンストラクタ
        {
            try
            {
                REngine.SetEnvironmentVariables();
                _engine = REngine.GetInstance();
                _engine.Initialize();
            }
            catch (Exception ex)
            {
                LogDisplay.WriteLine("Error initializing RDotNet: " + ex.Message);
            }
        }

    // Ctrl+Shift+Enter
        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);
        }
    }
}
]]>
</DnaLibrary>

試し方

  1. 新規Excelブックを開く
  2. 上記ブックにUsingRdotNet.xllをドラッグ&ドロップし、「このアドインをこのセッションに限り有効にする」を選択
  3. セルに下記数式を入力 vbnet =TestRDotNet()
  4. セルの中身が#VALUE!にならなければ成功
  5. 別のセルを水平に5つ選択した後、 vbnet =MyRnorm(5) と数式入力し、Ctrl + Shift + Enterを同時押しして「配列数式」にする
  6. セルの中身が#NUM!にならずランダムな数値が5つ埋まっていれば成功

補記

環境によっては、使用するRのパスをREngine.GetInstance()で明示的に指定してやる必要があるようです。

DNAスクリプト(という言い方でいいのだろうか?)の問題点の切り分けにはLogDisplay.WriteLine()が非常に役に立ちました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2