群馬大学 | 医学部 | サイトトップ | 医学情報処理演習

2009年度第3回「記述統計量」課題解答例

2009年10月26日

課題

前回も使ったsample02.txtを用い,男女別(注:性別を示す変数名はSEXで,値は女性が"F"で男性が"M")にヘモグロビン濃度(変数名HB)の記述統計量(平均値,不偏標準偏差,中央値,四分位偏差)を計算しなさい。

学籍番号・氏名とともに,下のフォームにRのコードと結果を貼り付けて送信すること。

なお,質問,感想などがあれば,解答(出力結果)の欄に,出力結果の後に記入してもよい。他の人にも役に立つような質問であれば次回の演習で説明するが,マイナーな質問あるいは発展的な質問で個人的に回答を要する場合はメールアドレスも忘れずに入力すること。

解答例

講義中に示した通り,男女別にいくつかの記述統計量を計算させるには,tapply()関数を使うと楽である。使い方は基本的に,tapply(処理したい変数, 分類したい変数, 関数名)となる。また,元々Rに組み込まれていない関数でも,function()関数を使って定義することができる。つまり,多くの人が正しく解答したように,下記のコードが解答の一例である。

dat <- read.delim("http://phi.med.gunma-u.ac.jp/medstat/sample02.txt")
siqr <- function(X) { (fivenum(X)[4] - fivenum(X)[2])/2 }
tapply(dat$HB,dat$SEX,mean)
tapply(dat$HB,dat$SEX,sd)
tapply(dat$HB,dat$SEX,median)
tapply(dat$HB,dat$SEX,siqr)

これを実行して得られる結果は,下の枠内のようになる。

> tapply(dat$HB,dat$SEX,mean)
       F        M 
12.89130 15.40526 
> tapply(dat$HB,dat$SEX,sd)
       F        M 
1.219878 1.507629 
> tapply(dat$HB,dat$SEX,median)
    F     M 
13.10 15.45 
> tapply(dat$HB,dat$SEX,siqr)
   F    M 
0.55 0.75 

別解

しかし,少し考えればわかるように,関数定義は自由にできるのだから,tapply()を4回もさせなくても,先に4種の記述統計量を返す関数を定義してしまうこともできる。また,実は最近のバージョンのRでは,四分位範囲を計算する関数はIQR()として実装済みであった(ただし内部的にquantile()を使って計算しているので,fivenum()を使った結果とは完全には一致しない場合がある)。

以上の2点から,もっと効率が良く,結果も見やすくなる,次のようなコードを書くことができる。

dat <- read.delim("http://phi.med.gunma-u.ac.jp/medstat/sample02.txt")
msmi <- function(X) {
 res <- c(mean(X),sd(X),median(X),IQR(X)/2)
 names(res) <- c("平均値","不偏標準偏差","中央値","四分位偏差")
 res }
tapply(dat$HB,dat$SEX,msmi)

これを実行して得られる結果は,下の枠内のようになる。上の出力と見比べると,こちらの方が優れていることが明らかだろう。

> tapply(dat$HB,dat$SEX,msmi)
$F
      平均値 不偏標準偏差       中央値   四分位偏差 
   12.891304     1.219878    13.100000     0.550000 

$M
      平均値 不偏標準偏差       中央値   四分位偏差 
   15.405263     1.507629    15.450000     0.725000