この記事でわかること。
- Rで複雑、大量のクロス集計を効率的に行う方法の仕組みがわかります。
- table関数やdplyrパッケージのgroup_byやsummarise関数とは違ったアプローチの集計方法が身につきます。
※長くなりそうなので、Rのコードを使った解説はこちらの別記事にします。
アンケートのデータなどを集計する場合、↓のようなことをするイメージで集計が必要になることがあります。
table関数やgroup_by関数などを使ってもできないことはないのかもしれませんが、集計の対象項目が増えてくるとそのやり方では面倒になることが多いです。
実際に私が行っているクロス集計の方法は、前処理が少し必要になりますが項目が多くなっても効率的に対応ができるので、この記事ではその方法を紹介します。
この記事で紹介するクロス集計の手順です。
メモ
- 集計に必要な項目のローデータを01の形にする
- 行列の計算(乗算)により実数表(N表)を作成する
- 実数表を全体で割り算を行い%表を作成する
では、簡単なデータで集計の仕組み、考え方を説明し、実際にRのコードで応用的な説明をします。
Contents
クロス集計に利用する元のローデータと集計イメージ
3人の簡単データを例に説明をします。
A001さんは男性で10代、A002さんは女性で20代、A003さんは男性で30代と言う意味のデータです。
男性 |
女性 |
10代 |
20代 |
30代 |
|
A001 |
1 |
0 |
1 |
0 |
0 |
A002 |
0 |
1 |
0 |
1 |
0 |
A003 |
1 |
0 |
0 |
0 |
1 |
上のデータから下の実数表を行列の乗算(掛け算)を使って作成します。
10代 |
20代 |
30代 |
|
男性 |
1 |
0 |
1 |
女性 |
0 |
1 |
0 |
上の表を%表にすると下のようになります。最終的にここまでRで作成するのがゴールです。
全体(N) |
10代 |
20代 |
30代 |
|
男性 |
2 |
50.0 |
0.0 |
50.0 |
女性 |
1 |
0.0 |
100.0 |
0.0 |
全体(N)の列はこの集計表では男性が2人、女性が1人いるということを表しています。
横%表なんて言い方もしますが、男性ベースでみると10代の割合は50%、30代の割合が50%、女性ベースでみると20代が100%(女性は全員20代)といった感じで横方向に読み取ります。
行列の乗算を使った実数表の作成するために必要な行列の知識
行列の乗算を使って実数表を作成するためには、次の2つの行列の知識が必要になります。
- 行列の乗算
- 行列の転置
どちらもそれほど難しくはないですが、初めて知る人もいると思うので詳しく説明します。
すでに↑のことはわかっている人は、このパートは飛ばして構いません。
行列の乗算とは
行列Aと行列Bの掛け算は下の通りです。
※と言っても、分からない人もいると思うので、もう少し詳しく説明します。
実際に下のAとBの2つの行列のデータを使ってAB(行列の乗算)の説明します。
まず、下の赤い四角で囲った部分の計算を考えましょう。
AとBのそれぞれ赤で囲った数字を掛けて足すとae + bgの計算になります。
続いて青の部分の計算を考えましょう。
AとBのそれぞれ青で囲った数字を掛けて足すとaf + bhの計算になります。
同様にオレンジの部分を考えると以下の通りです。
最後に緑の部分を考えます。
ひと通り計算が終わって、最終的な結果は以下の通りです。
まとめると
行列の掛け算は、掛けられる行列(例の場合だとA)の行の各要素と、掛ける行列(例の場合だとB)の列の各要素を掛け合わして合計するという作業になります。
今回の例は2×2の行列だったので比較的単純でしたが、行列のサイズが大きくなっても同じ手順です。
ただ、行列の乗算を考える際に、一つ大事なことがあります。Aの行数とBの列数の数が一致しないと行列の乗算はできないということです。
考えてみればわかりますが、Aの行とBの列の要素同士を掛け算してから足すので、Aの行数とBの列数が違うと計算ができません。
2×2の行列Aと3×3の行列Bの積を計算しようとすると、Aの行列の2つの要素に対してBの行列は3つの要素を持っているので、要素数が違うので計算ができなくなります。
クロス集計のコードを書くとそこまで気にすることはないのですが、たまにエラーが出たときにこれが原因の場合もあるので頭の片隅に入れておいてください。
行列の転置
行列の乗算に比べたらこちらは簡単だと思います。
難しく説明すると
「転置行列は、元の行列のi行j列の要素が、転置行列のj行i列の要素になったものである。」
なのですが、もう少し具体的に説明すると。
先ほど計算した下の行列を転置すると
2×2の行列だとわかりづらいですが、2と3の位置が入れ替わっていますね。
3×3の行列の例を見てみます。
どのような形の行列でも、次の考え方をすれば転置ができます。
- 元の行列の1列目を転置する行列の1行目に、
- 元の行列の2列目を転置する行列の2行目に、
- 元の行列の3列目を転置する行列の3行目に、
- ・・・
- 元の行列のn列目を転置する行列のn行目に、
・・といった感じです。
図であらわすと上のようなイメージですね。
左の行列だと青の列が1列目の成分です。その成分を転置後の行列だと1行目の成分になっていますね。
同様に2列目の赤の成分が転置後は2行目の成分になっています。
行列の乗算を使った実数表の作り方・考え方
実数表を作成するために必要な行列の知識が終わったので、
先ほどのデータに戻って実際に件数表の作り方を考えてみます。
男性 | 女性 | 10代 | 20代 | 30代 | |
A001 | 1 | 0 | 1 | 0 | 0 |
A002 | 0 | 1 | 0 | 1 | 0 |
A003 | 1 | 0 | 0 | 0 | 1 |
結果から先に言うと「転置した性別の01の行列」に「年代の01の行列」を掛けると実数表になります。
実際に見てみましょう。
下の積の部分に注目して、1行目を男性、2行目を女性。1列目を10代、2列目を20代、3列目を30代とすると、
最初の実数表の結果と一致します。
10代 | 20代 | 30代 | |
男性 | 1 | 0 | 1 |
女性 | 0 | 1 | 0 |
これは偶然ではなく、次のように理由で説明ができます。
性別を転置した行列なので、
- 青で囲まれた部分は男性であるかそうでないかを表します。
- 赤で囲まれた部分は女性であるかそうでないかを表します。
年代の行列も同様で、
緑→10代、黄色→20代、紫→30代といった具合です。
行列の積の1つ目の成分では、青の囲みの各要素と緑の囲み各要素を掛け合わせてすべてを足していますので、
青と緑の両方が1の人の数を数えているのと同じことになります。
※どちらかが0だと要素同士の掛け算の結果が0になりますので。。
もう少し補足すると、性別を転置した行列の1列目と年代の行列の1行目というのは、同じ「A001さん」のデータなので、
性別の1行1列目は男性かそうではないか?、1行2列目は女性かそうでないか?と言う意味のデータです。
年代の行列の1列目も同様で、10代かそうではないか?、20代か?、30代か?・・・となります。
元のローデータと見比べてみても明らかですよね。
男性 | 女性 | 10代 | 20代 | 30代 | |
A001 | 1 | 0 | 1 | 0 | 0 |
A002 | 0 | 1 | 0 | 1 | 0 |
A003 | 1 | 0 | 0 | 0 | 1 |
このような考え方で、性別と年代で両方とも1の部分を数えているだけなので、行列の積を求めることで実数表を作ることができます。
整理すると、実数表の横の要素(今回の例だと性別)の01のデータを転置した行列と、実数表の縦の部分(今回の例だと年代)の01のデータの行列の積を求めることで件数表を作成することができます。
応用編としても少し大きなデータを例に考えます
今回の例に使うのはこちらのデータ。
男性 |
女性 |
10代 |
20代 |
30代 |
男性 10代 |
男性 20代 |
男性 30代 |
女性 10代 |
女性 20代 |
女性 30代 |
|
A001 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
A002 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
A003 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
A004 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
A005 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
A006 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
上のデータを集計して、最終的には下の実数表を作成します。
男性10代 |
男性20代 |
男性30代 |
女性10代 |
女性20代 |
女性30代 |
|
男性 |
2 |
1 |
0 |
0 |
0 |
0 |
女性 |
0 |
0 |
0 |
0 |
1 |
2 |
10代 |
2 |
0 |
0 |
0 |
0 |
0 |
20代 |
0 |
1 |
0 |
0 |
1 |
0 |
30代 |
0 |
0 |
0 |
0 |
0 |
2 |
このくらいのデータになると数式エディタで対応するのが大変になってくるので、エクセルのキャプチャで説明します。
まず、実数表の横に要素のデータを作成し、転置します。この行列をAとします。
実際に計算に使うのは青いセルの部分のみです。
続いて、実数表の縦の要素の性年代の行列を作成します。この行列をBとします。
実際に計算に使うのはこちらも同様に青いセルの部分のみです。
実数表の作成には
AB(行列の積)を求める必要がありますが、すべて説明すると長くなるので赤枠同士の要素の計算だけを説明します。
男性×男性10代の両方を満たす件数を計算する部分は
1×1+0×0+1×0+1×1+0×0+0×0=2となります。
この様に実数表の横の要素や縦の要素が増えても01のデータを作成してしまえば、行列の積を求めるだけで実数表が作成されます。
各要素の01のデータを作るのが大変を思われるかもしれませんが、Rには便利な関数が沢山あるのでそんなに大変ではありません。
長くなってしまったので、実際のRのコードの説明は次の記事にしたいと思います。
それでは。