山田(2015)の第1章、第2章を読んでいたらクラスごとの記述統計を効率的に求める関数を見つけたので備忘録としてメモ
例えば、以下のような、クラスごと(5クラス)に集計したデータがあるとする。
## class sex score ## 1 1 1 310 ## 2 1 1 335 ## 3 1 1 355 ## 4 1 1 350 ## 5 1 1 490 ## 6 1 1 350 ## 7 1 2 365 ## 8 1 1 210 ## 9 1 2 380 ## 10 1 1 425 ## 11 2 1 335 ## 12 2 2 355 ## 13 2 2 545 ## 14 2 1 415 ## 15 2 1 275 ## 16 2 2 425 ## 17 2 1 290 ## 18 2 2 355 ## 19 2 2 520 ## 20 2 1 755 ## 21 3 1 345 ## 22 3 1 565 ## 23 3 1 285 ## 24 3 1 240 ## 25 3 2 395 ## 26 3 1 470 ## 27 3 1 310 ## 28 3 2 405 ## 29 3 1 315 ## 30 3 1 260 ## 31 4 2 360 ## 32 4 1 230 ## 33 4 2 275 ## 34 4 1 410 ## 35 4 2 480 ## 36 4 2 310 ## 37 4 1 340 ## 38 4 2 210 ## 39 4 1 505 ## 40 4 2 375 ## 41 5 2 245 ## 42 5 1 215 ## 43 5 1 345 ## 44 5 1 280 ## 45 5 2 300 ## 46 5 1 300 ## 47 5 2 380 ## 48 5 1 275 ## 49 5 1 340 ## 50 5 2 230
このデータから、全体の平均値、標準偏差、最高点、最低点およびクラスごとの平均値、標準偏差、最高点、最低点を導き出したいとする。
Rにおいて上記のデータを導き出したい場合は、
mean() sd() max() min()
を使うことが考えられるがかなり面倒そう。そこで、以下の2つの解決策を考える。
解決策1:psychパッケージのdescribeBy()を使う。
describeBy()は
describeBy(処理したいデータ,属性)
と入力し、属性ごとの記述統計を算出することができる。例えば、上記データのclassごとにscoreの記述統計量を算出したい場合、以下のように入力する。
library(psych) #psychパッケージの読み込み describeBy(dat$score,dat$class) #処理したいデータ=datのscore, 属性=datのclass
## Descriptive statistics by group ## group: 1 ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 357 72.5 352.5 358.75 33.36 210 490 280 -0.16 -0.08 ## se ## X1 22.93 ## -------------------------------------------------------- ## group: 2 ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 427 145.68 385 405 107.49 275 755 480 0.97 -0.15 ## se ## X1 46.07 ## -------------------------------------------------------- ## group: 3 ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 359 101.18 330 348.12 100.08 240 565 325 0.67 -0.81 ## se ## X1 32 ## -------------------------------------------------------- ## group: 4 ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 349.5 98.08 350 347.5 100.08 210 505 295 0.14 -1.37 ## se ## X1 31.01 ## -------------------------------------------------------- ## group: 5 ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 291 53.11 290 289.38 70.42 215 380 165 0.14 -1.38 ## se ## X1 16.8
これで、各グループ(class 1からclass 5)の記述統計量が一発で算出された。超便利。ちなみに、n=データ数、mean=平均値、sd=標準偏差、median=中央値、min=最小値、max=最大値、skew=歪度、kurtosis=尖度、se=標準誤差
解決策2:tapply()を使う
tapply()は
tapply(処理したいデータ,属性,統計量)
とすることで、グループごとに算出したい統計量を一括で導き出すことができる。例えば、先程のデータでクラスごとの平均値を処理したい場合、以下のように入力する。
tapply(dat$score,dat$class,mean) #処理したいデータ=datのscore, 属性=datのclass,統計量=平均値
## 1 2 3 4 5 ## 357.0 427.0 359.0 349.5 291.0
上記の結果の1,2,3,4,5はそれぞれクラス1,クラス2…を指す。つまり、クラス1の平均値は357点、クラス2の平均値は427点…ということがこの関数一つで算出された。超便利。
tapply()で扱う統計量は平均値以外でも使うことができる。標準偏差や最小値、最大値も以下の通り。
tapply(dat$score,dat$class,sd) #グループごとにSDを算出
## 1 2 3 4 5 ## 72.50287 145.68230 101.18190 98.07735 53.11413
tapply(dat$score,dat$class,min) #グループごとに最小値を算出
## 1 2 3 4 5 ## 210 275 240 210 215
tapply(dat$score,dat$class,max) #グループごとに最大値を算出
## 1 2 3 4 5 ## 490 755 565 505 380
また、先程のpsychパッケージのdescribe()と組み合わせることもできる。
tapply(dat$score, dat$class, describe)
## $`1` ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 357 72.5 352.5 358.75 33.36 210 490 280 -0.16 -0.08 ## se ## X1 22.93 ## ## $`2` ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 427 145.68 385 405 107.49 275 755 480 0.97 -0.15 ## se ## X1 46.07 ## ## $`3` ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 359 101.18 330 348.12 100.08 240 565 325 0.67 -0.81 ## se ## X1 32 ## ## $`4` ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 349.5 98.08 350 347.5 100.08 210 505 295 0.14 -1.37 ## se ## X1 31.01 ## ## $`5` ## vars n mean sd median trimmed mad min max range skew kurtosis ## X1 1 10 291 53.11 290 289.38 70.42 215 380 165 0.14 -1.38 ## se ## X1 16.8
これで解決策1のdescribeBy()と同様、各クラスごとのデータ数、平均値、SD、最小値、最大値が一発で導き出すことができた。
まとめ
上のようなデータを、csvファイルから読み込んで、Rを用いてクラスごとに分析したい場合、解決策1、解決策2ともに以下の3行でOKという話。
解決策1の場合
dat<-read.csv("sample.csv",header=TRUE) library(psych) tapply(dat$score,dat$class,describe)
解決策2の場合
dat<-read.csv("sample.csv",header=TRUE) library(psych) describeBy(dat$score,dat$class)