転職ドラフトの回答率をRを使って集計してみた

[転職ドラフト｜ITエンジニアを年収・仕事内容つきで競争入札](https://job-draft.jp/) の回答期限が終了したので、回答率を集計してみた。

元々、スクレイピングとRの練習で始めたのだが、[前回](http://qiita.com/osd/items/318c1d65c29c4f50ace9) はデータの表示だけで終わらせてしまったので、今回は R のスクリプトも書いていく。

# 扱うデータ

スクレイピングを使って、[社名,ユーザーID,指名額,回答] のデータを抽出し、tmp.csv に置く。

```
$ head -n 3 tmp.csv
name,user_id,income,reply
Speee,1,ゴッド,承諾
Retty,2,ウィザード,承諾
```

# 全体の回答率

```
> x = read.csv("tmp.csv")
> table(x$reply)

  辞退   承諾 未返答
   123    197     57
>
> round(prop.table(y) * 100)

  辞退   承諾 未返答
    33     52     15
```

read.csv はデフォルトで header=T なので、1行目はデータ領域ではなく、ヘッダーとして扱われる。
`x$reply` とすることで、その列データが取り出せる。

`table` を使って集計ができる。

`prop.table` で割合に変換できる。

指名全体の、33%が辞退、52％が承諾、15%が未返答である。

# 会社ごとの回答率

```
> table(x$name, x$reply)

                                     辞退 承諾 未返答
  BASE                                  4    6      2
  freee                                 8   21      2
  Retty                                21   28     14
  Sansan                               19   20      8
  Speee                                14   10      4
  VASILY                                3    4      1
  イグニス                                1    2      0
  クルーズ                                2    4      1
  サイバーエージェント（ゲーム事業）              8    9      2
  ディー・エヌ・エー                          6   15      2
  ナイル(旧:ヴォラーレ)                      2    2      1
  フリークアウト                            11   13      2
  ペロリ                                  4    4      5
  ミクシィ                                 4    4      1
  ヤフー                                  8   10      3
  リクルートライフスタイル                      5   30      9
  リブセンス                                3   15      0
```

`table`に二つの要素を渡すことで、集計ができる。

小計を追加するには幾つかやり方があるようだ。
ピボットテーブルを扱うには、`reshape2`が有名らしいのだが、tidyr[^1]も良いよ、という話で、迷ったので、ライブラリを使わずベタな方法でいく。

```
> y = table(x$name, x$reply)
> y = cbind(y, "合計" = rowSums(y))
> y
                                   辞退 承諾 未返答 合計
BASE                                  4    6      2   12
freee                                 8   21      2   31
Retty                                21   28     14   63
Sansan                               19   20      8   47
Speee                                14   10      4   28
VASILY                                3    4      1    8
イグニス                               1    2      0    3
クルーズ                               2    4      1    7
サイバーエージェント（ゲーム事業）             8    9      2   19
ディー・エヌ・エー                         6   15      2   23
ナイル(旧:ヴォラーレ)                     2    2      1    5
フリークアウト                           11   13      2   26
ペロリ                                 4    4      5   13
ミクシィ                                4    4      1    9
ヤフー                                 8   10      3   21
リクルートライフスタイル                    5   30      9   44
リブセンス                              3   15      0   18
>

> z = cbind(y, "辞退率" = floor(y[,1] * 100 / y[,4]), "承諾率" = floor(y[,2] * 100 / y[,4]), "未返答率" = floor(y[,3] * 100 / y[,4]))
> z
                                   辞退  承諾   未返答 合計   辞退率   承諾率   未返答率
BASE                                  4    6      2   12     33     50       16
freee                                 8   21      2   31     25     67        6
Retty                                21   28     14   63     33     44       22
Sansan                               19   20      8   47     40     42       17
Speee                                14   10      4   28     50     35       14
VASILY                                3    4      1    8     37     50       12
イグニス                                1    2      0    3     33     66        0
クルーズ                                2    4      1    7     28     57       14
サイバーエージェント（ゲーム事業）              8    9      2   19     42     47       10
ディー・エヌ・エー                          6   15      2   23     26     65        8
ナイル(旧:ヴォラーレ)                      2    2      1    5     40     40       20
フリークアウト                            11   13      2   26     42     50        7
ペロリ                                  4    4      5   13     30     30       38
ミクシィ                                 4    4      1    9     44     44       11
ヤフー                                  8   10      3   21     38     47       14
リクルートライフスタイル                     5   30      9   44     11     68       20
リブセンス                               3   15      0   18     16     83        0
>
```

cbind で列を結合できる。合計を結合した。
合計列と、各々の列に対して、100を掛けてfloor することで、パーセント化。
多少のズレは気にしない。

```
> z[rev(order(z[,6])),5:7]
                                   辞退率 承諾率 未返答率
リブセンス                             16     83        0
リクルートライフスタイル                   11     68       20
freee                               25     67        6
イグニス                              33     66        0
ディー・エヌ・エー                        26     65        8
クルーズ                              28     57       14
フリークアウト                           42     50        7
VASILY                              37     50       12
BASE                                33     50       16
ヤフー                                38     47       14
サイバーエージェント（ゲーム事業）            42     47       10
ミクシィ                               44     44       11
Retty                               33     44       22
Sansan                              40     42       17
ナイル(旧:ヴォラーレ)                    40     40       20
Speee                               50     35       14
ペロリ                                30     30       38
>
```

承諾率で昇順ソートしてみた。

z[,6]が承諾率の列。
order を使うと、順序のindex が返る。

> order(z[,6])
 [1] 13  5 11  4  3 14  9 15  1  6 12  8 10  7  2 16 17

ので、rev で逆順。
[,5:7]で、5列目から7列目までを抽出。
全部合わせると`z[rev(order(z[,6])),5:7]`となる。
なんだこのリブセンスの承諾率！？

# 指名額ごとの回答率

```
> y = table(x$income, x$reply)
> y

             辞退 承諾 未返答
  ウィザード    15   20     13
  ゴッド        2    3      1
  スター      32   56     18
  ノービス      0    3      0
  ノーマル     33   44     11
  プチリッチ    41   71     14
>
> my_order = c(2, 1, 3, 6, 5, 4)
> y = y[my_order,]
> y

             辞退 承諾 未返答
  ゴッド        2    3      1
  ウィザード    15   20     13
  スター      32   56     18
  プチリッチ    41   71     14
  ノーマル     33   44     11
  ノービス      0    3      0
>
```

`table(x$income, x$reply)` で集計。
順序を変更したかったので、手動で順序ベクトルを作成して、並び替え。

後は上と同じコードを使う。

```
> y = cbind(y, "合計" = rowSums(y))
> z = cbind(y, "辞退率" = floor(y[,1] * 100 / y[,4]), "承諾率" = floor(y[,2] * 100 / y[,4]), "未返答率" = floor(y[,3] * 100 / y[,4]))
> z[,5:7]
           辞退率 承諾率 未返答率
ゴッド         33     50       16
ウィザード      31     41       27
スター        30     52       16
プチリッチ      32     56       11
ノーマル       37     50       12
ノービス        0    100        0
```

指名額が高いほうが承諾率が高いのかと思ったが、そんなことはなかった。

# ユーザーごとの回答率

ユーザーは多いので、さらにまとめてみる。
承諾率を[0, 1〜10, 11〜20, ..., 90〜99, 100]の階層で分割する。

```
y = table(x$user_id, x$reply)
......

> as.matrix(table(cut(z[,6], c(-1, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99, 100))))
         [,1]
(-1,0]     43
(0,10]      0
(10,20]     3
(20,30]     4
(30,40]     0
(40,50]    16
(50,60]     3
(60,70]     8
(70,80]     4
(80,90]     0
(90,99]     0
(99,100]   54
```

z[,6] は承諾率。
cut を使って、データを指定した範囲にマッピングする。
`(-1,0]` は、-1を含まず、0を含む範囲。
`(0,10]` は、0を含まず、10を含む範囲。
いわゆる開空間と閉空間。

table で集計して、as.matrix で縦に変換した(縦横変換のやり方が分からなかったので行列に直すことで縦形式に整形した)。

承諾率が 0 ということは、[辞退,未返答] だけの人が43人居ることを表している。
指名があった人は135人なので、実は32%の人が一件も承諾していない。
しかし逆に言えば68％の人が承諾している。
マッチング率68%は、良さそうな気がするが、実際のところどうなんだろう？

ちなみに、未返答率100%の人は20人居た。

> length(z[,7][z[,7] == 100])
[1] 20

ヒストグラムで書くとこんな感じ。

![image](https://qiita-image-store.s3.amazonaws.com/0/30755/1ac41479-1111-9daf-6ab2-2117ac9b9b49.png)

# まとめ

- Rを使って、集計してみた。
- table が便利
- cut が便利
- order で任意に順序が入れ替えられて便利
- 今回の転職ドラフト、7割くらいが次のアクションに繋がっていた。
- 指名額が高いから承諾するという傾向はなかった。

とにかく、Rが便利。

# 参考
[reshape2によるクロス集計（Excelピボットテーブルと同じ操作を行う）](http://homepage2.nifty.com/nandemoarchive/sas_r_excel/r_kowaza_reshape2.htm)
[reshape2: 柔軟なデータ変形ツール - Watal M. Iwasaki](https://heavywatal.github.io/rstats/reshape2.html)
[秩序と情報とブロッコリー: R言語のcut関数の使い方](http://data-hacker.blogspot.jp/2013/05/rcut.html)
[r - Add column sum to table - Stack Overflow](http://stackoverflow.com/questions/27969616/add-column-sum-to-table)

[^1]: https://heavywatal.github.io/rstats/tidyr.html