群馬大学 | 医学部 | サイトトップ | 医学情報処理演習
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