How to | データのサブグループに操作を行う方法
データをまとめている場合に,データをそのサブグループで解析すると役に立つということがよくある.例えば,収穫量を種の種類によって,患者が回復するのに平均でかかる時間を患者の年齢あるいは薬の種類によって,分類することができる.Wolfram言語では列のデータをその他の列の値に基づいて分割してから,結果のグループに対して希望する統計を計算することができる.
以下のデータは,3種類の土壌と2種類のトウモロコシの種について収穫高を表したものである:
agdata = {{clay, seedB, 175}, {silty, seedB, 180}, {clay, seedB, 165}, {sandy, seedA, 168}, {clay, seedA, 184}, {sandy, seedB, 171}, {sandy, seedB, 173}, {sandy, seedA, 189}, {clay, seedA, 186}, {silty, seedB, 174}, {clay, seedA, 192}, {clay, seedA, 184}, {clay, seedA, 179}, {sandy, seedA, 182}, {sandy, seedB, 177}, {silty, seedA, 180}, {clay, seedB, 175}, {silty, seedB, 181}, {sandy, seedA, 176}, {silty, seedB, 190}};データは,FirstをGatherByと一緒に使い各データ点の第1要素でデータをまとめることによって,土壌の種類ごとにグループ分けすることができる:
bySoilType = GatherBy[agdata, First]土壌の種類ごとの平均収穫高は,各リストから土壌の種類を抽出し,リスト中の収穫高のMean(最終要素)を計算することによって,計算することができる.上の3つのグループを反復子変数xの可能な値とし,Tableを使ってこの結果を得ることができる.
Tableを使って,それぞれのグループについて土壌の種類と平均収穫高を得る:
Table[{x[[1, 1]], N[Mean[x[[All, -1]]]]}, {x, bySoilType}]種の種類に基づいた収穫高についての情報を得る場合は,まずデータを各データ点の第2要素でグループ分けする.
純関数#[[2]]&をGatherByと一緒に使って,種の種類ごとにデータをまとめる:
bySeedType = GatherBy[agdata, #[[2]]&]種の種類ごとの平均値を計算する方法は,土壌の種類ごとの平均値を計算した方法と大変よく似ている.ただし,新しくグループ分けされたbySeedTypeデータを代りに使う.また,種の種類を得るために,第2要素が抽出される.
Tableを使って種の種類ごとの平均収穫高を計算する:
Table[{x[[1, 2]], N[Mean[x[[All, -1]]]]}, {x, bySeedType}]その他の記述統計も計算することができる.例えば,種の種類ごとの収穫高の範囲や最小・最大収穫高を計算したい場合があるかも知れない.
以下では,それぞれの種の種類について最小・最大収穫高を計算する:
Table[{x[[1, 2]], {N[Min[x[[All, -1]]]], N[Max[x[[All, -1]]]]}}, {x, bySeedType}]以下のデータは,特定の疾患について治療を受けた患者が飲んだ薬の種類,患者の年齢,回復にかかった時間を表す:
meddata = {{drugB, 67, 18}, {drugB, 48, 18}, {drugA, 33, 16}, {drugB, 76, 33}, {drugB, 33, 3}, {placebo, 40, 15}, {drugB, 78, 28}, {drugB, 54, 13}, {placebo, 46, 23}, {drugA, 36, 12}, {drugA, 69, 30}, {drugA, 78, 40}, {placebo, 77, 37}, {drugA, 79, 36}, {drugA, 45, 16}, {drugA, 36, 18}, {drugA, 58, 24}, {placebo, 25, 9}, {drugB, 75, 25}, {drugB, 22, 3}, {placebo, 51, 25}, {placebo, 27, 8}, {placebo, 47, 20}, {placebo, 69, 34}, {drugB, 52, 16}};トウモロコシの収穫高の例と同様に,いずれかの列でデータをグループ分けして,異なるグループについて結果を計算することができる.
byDrug = GatherBy[meddata, First]次の関数を使って,値のリストについて標本サイズ,平均値,中央値,範囲を求めることができる:
describe[values_] := {Length[values], Mean[values], Median[values], {Min[values], Max[values]}}Tableをdescribeと使って,薬ごとの記述統計を計算する.それぞれの薬の種類に対する結果の順番は,describeの定義に使われたもの(標本サイズ,平均値,中央値,標本範囲)と同じである:
Table[{x[[1, 1]], describe[N[x[[All, -1]]]]}, {x, byDrug} ]年齢ごとにグループ分けする場合は,個々の年齢ではなく,年齢範囲に対応するグループを作った方がいいこともある.この例では,患者の年齢を10年区切りでグループ分けしている.
この年齢グループを作成するために,各年齢を10で割ってから,IntegerPartを使って小数点の左の数字を取る.この数字に基づいて,GatherByを使ってデータをまとめる:
byAgeGroup = GatherBy[meddata, IntegerPart[#[[2]] / 10]&]Tableをdescribeと一緒に使って,年齢グループごとの記述統計を計算する.Sortを使って,年齢グループの低いものから順にデータを並べる:
Table[{10IntegerPart[x[[1, 2]] / 10], describe[N[x[[All, -1]]]]}, {x, byAgeGroup}]//Sortデータはまた複数カテゴリでグループ分けすることもできる.例えば,医学データは,GatherByのリストにおいてFirstおよびIntegerPartの両方を特定することによって,薬と年齢グループの両方でグループ分けすることができる.
byDrugAndAgeGroup = GatherBy[meddata, {First[#], IntegerPart[#[[2]] / 10]}&]上と同じように,グループ分けしたデータについて統計を計算することができる.ここでは,データは薬の種類ごとにグループ分けされ,Gridで表示されている:
Table[{x[[1, 1]], 10IntegerPart[x[[1, 2]] / 10], describe[N[x[[All, -1]]]]}, {x, byDrugAndAgeGroup}]//Sort//Grid表データを表示したりフォーマットしたりする方法についての詳細は,「表を操作する方法」を参照のこと.