F#でRをいじってみる

# 噂のF#でRをやってみる
F#はType Providerという機能があって別の言語を型を付けた状態で扱うことが出来るらしい。
今回はF#でRを使ってみようと思います。
[F# R Type Provider](http://bluemountaincapital.github.io/FSharpRProvider/index.html)
Rはすでにインストールされている前提でいきます。

## Visual Studio 2017でF#のプロジェクトを作成
新しいプロジェクト > Visual F# > コンソールアプリケーション

## NuGetでRRroviderをインストール

ツール > NuGetパッケージマネージャー > ソリューションのNuGetパッケージの管理

参照タブを押して
RProviderを検索 > 選択してインストール
（参考）https://www.nuget.org/packages/RProvider

## F# InteractiveでRProviderを使えるようにする

表示 > その他のウィンドウ > F# Interactive

ソリューションエクスプローラーを開いて参照設定を右クリック > 参照をF# Interactiveに送信

これでF# InteractiveにRProviderの参照が通りました。

# F# InteractiveでRをいじってみる。

F# Interactive中では行末を;;で終わらせる必要があります。
今後のコードは;;がついた状態で紹介します。

## Rをやってる人への注意点
R使っている人にとってはびっくりするかもしれませんが、いつもRを起動すると自動的に開かれるパッケージが明に指定しないと開かれません。R.~でRの関数が使えるのですが、それが見つからない場合はパッケージを開けていないと考えられますのでopen RProvider.~で指定してください。

## Rのライブラリを開く

```fsharp
open System;;
open RDotNet;;
open RProvider;;
open RProvider.graphics;;
open RProvider.stats;;
open RProvider.``base``;;
open RProvider.utils;;
open RProvider.methods;;
```
このような形でRのパッケージを開いていってください。
Program.fsに書けばインテリセンスが効くので好きなパッケージを選んで下さい。

## 何はともあれc()関数
Rの関数はR.~で開くことが出来ます。c()でベクターを作ってみましょう。

```fsharp
let v = R.c(1,2,3);;
```

じゃあvと打ってvの中身を確かめてみます。

```fsharp
v;;
```

```
val it : SymbolicExpression =
  RDotNet.SymbolicExpression {Engine = RDotNet.REngine;
                              IsClosed = false;
                              IsInvalid = false;
                              IsProtected = true;
                              Type = NumericVector;}
```

...
...

SymbolicExprerrionって何？

どうもF#ではR関数で得た値はSymbolicExpressionとして保持されているようです。

どうしても中身が見たい場合はR.showで見てやる必要があります。

## R.showで中身を見る
F#ではパイプライン演算子|>で値を渡すことが出来ます。
Rでいう%>%なのですが、実はRの%>%はF#の|>を参考に作られたそうです。
これを使ってR.showに先ほどの変数vを渡しましょう。

```fsharp
v |> R.show;;
```

```
In GetStaticParametersForMethod
[1] 1 2 3
val it : SymbolicExpression =
  RDotNet.SymbolicExpression {Engine = RDotNet.REngine;
                              IsClosed = false;
                              IsInvalid = false;
                              IsProtected = true;
                              Type = Null;}
```

無事中身を見ることが出来ました。
出来ない場合は、open RProvider.methods出来ているか確認してください。


## irisを開く
Rユーザーなら次にやることはirisデータセットを開くことだと思います。
irisデータはdatasetsパッケージに入っているのでこれを開きます。

```fsharp
open RProvider.datasets;;
```
その後、irisをirisにバインドします。

```fsharp
let iris = R.iris;;
```
```
val iris : SymbolicExpression
```

これをR.showに渡してやると、

```fsharp
iris |> R.show;;
```
```
In GetStaticParametersForMethod
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
1            5.1         3.5          1.4         0.2     setosa
2            4.9         3.0          1.4         0.2     setosa
3            4.7         3.2          1.3         0.2     setosa
:
:
```

中身見れました。

コツをつかめばいろいろできます。

```fsharp
iris |> R.str;;
```
```
In GetStaticParametersForMethod
'data.frame':	150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
:
:
```


```fsharp
iris |> R.summary |> R.show;;
```
```
In GetStaticParametersForMethod
In GetStaticParametersForMethod
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300  
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
       Species  
 setosa    :50  
 versicolor:50  
 virginica :50  
                
:
:                
```

# まとめ
とりあえず、F#でRが使えるというところまでやってみました。
最近のRだとパイプライン演算子で書かれていることが多いと思いますので、プログラムの移行はしやすいかもしれません。%>%を|>に変えるだけです。
頑張ればF#にRの関数を使ったアプリケーションを作れそうなので、今後時間があれば試していきたいと思います。