読者です 読者をやめる 読者になる 読者になる

C#からggplot2でグラフを描く

ggplot2は統計処理で用いられるR言語向けのグラフ作成ライブラリです。高機能かつ綺麗な出力が得られるので人気のようです。ただ、Rは使ったことがないので、今回はC#からこのライブラリを使ってみたいと思います。

R.NET

C#からですと当然Rをそのまま操作することはできませんが、R.Netを使うことで間接的にC#からRを使うことができます。
R.NET documentation -- user version | R.NET -- user version

R.NETの例

インストール方法はnugetを使うだけなので簡単です。事前にRを入れておく必要があります。

RからC#へ 整数の一様乱数を1000個生成
REngine.SetEnvironmentVariables();
using (REngine r = REngine.GetInstance())
{
	r.Initialize();
	NumericVector x = r.Evaluate(@"runif(1000, min=1, max=10)").AsNumeric();
        Console.WriteLine(x[0]); // 3.68815191206522
}

runifはRの乱数の生成関数で、Evaluateの引数がRのコマンドになります。変数xの配列には1000個の乱数が入っています。

C#からRへ 配列の合計を表示
using (REngine r = REngine.GetInstance())
{
	r.Initialize();

	double[] value = { 1.1, 2.3, 3.5 };
	NumericVector cv = r.CreateNumericVector(value);
	r.SetSymbol("rv", cv); // Rでの名前をつける

	double sum = r.Evaluate(@"sum(rv)").AsNumeric().First();
	Console.WriteLine(sum); // 6.9
}

sumはRの合計関数です。
C#の変数をRの変数に変換することができればggplot2で表示できそうです。

ggplot2

このサイトを参考にして、散布図と近似曲線を表示してみます。
ggplot2 | R のグラフをより美しく

元のデータはC#で適当に作ります。横軸xが0から100の値で、縦軸yが横軸と同じ値に乱数を足したものです。
Rのxとyをそれぞれの軸に対応する変数名として定義しています。

var rd = new System.Random();
var x = Enumerable.Range(0, 200).Select(v => (double)v).ToArray();
var y = Enumerable.Range(0, 200).Select(v => (double)v + rd.Next(100)).ToArray();

// Rでの名前をつける
r.SetSymbol("x", r.CreateNumericVector(x));
r.SetSymbol("y", r.CreateNumericVector(y));

ggplot2はデータをdataframe形式で受け付けるようなので変換が必要です。その後、データの指定、表示する形式を決めます。
ggplot2のオブジェクトgにどんどん表示したいものを足していくイメージのようです。

r.Evaluate("library(ggplot2)");

// dataframe形式
r.Evaluate("df <- data.frame(x=x, y=y)");

// データを指定
r.Evaluate(@"g <- ggplot(df, aes(x = x, y = y))");

// 表示形式を指定
// 散布図
r.Evaluate(@"g <- g + geom_point(size = 1.0)");
// 近似曲線の種類はmethodで選ぶ
r.Evaluate(@"g <- g + geom_smooth(method = ""lm"")");
		
// ラベルの指定
r.Evaluate(@"g <- g + xlab(""x軸"")");
r.Evaluate(@"g <- g + ylab(""y軸"")");
r.Evaluate(@"g <- g + ggtitle(""タイトル"")");

// 表示
r.Evaluate(@"plot(g)");

f:id:wildpie:20170107204406p:plain