目的 独立 k 標本データに対して,各群のデータ数,平均値,標準偏差を求める。 さらに,独立 2 標本の場合には,平均値の差の検定(t 検定)またはマン・ホイットニーの U 検定(ウィルコクソンの順位和検定),独立 3 標本以上の場合には,一元配置分散分析またはクラスカル・ウォリス検定を行うこともできる。 使用法 indep.sample <- function(i, j, df, latex=TRUE, captions=NULL, labels=NULL, test=c("none", "parametric", "non-parametric"), statistics=c("mean", "median"), var.equal=FALSE, digits=3, output="", encoding=getOption("encoding")) 引数 i 分析対象となる変数が入っている列の番号 c 関数を使った複数指定可能 j 群を表す変数 factor の列番号 df 読み込んだデータフレームの名前 latex LaTeX ソースを出力する。Word 用なら,latex=FALSE にする captions latex=TRUE の場合,各表の表題を文字列ベクトルとして指定することができる(デフォルトではあり合わせの表題を付ける)。 labels latex=TRUE の場合,各表の label を文字列ベクトルとして指定することができる(デフォルトでは付けない)。 test 検定法を指定する。"parametric", "non-parametric" の何れか "parametric" の場合,2 群の場合には t.test 関数,3 群の場合には oneway.test 関数が呼ばれる "non-parametric" の場合,2 群の場合には wilcox.test 関数,3 群の場合には kruskal.test 関数が呼ばれる デフォルトは検定をしない statistics (平均値,標準偏差)を求める("mean")か(中央値,四分偏差)を求める("median")かを指定する var.equal t.test, oneway.test の var.equal 引数として使用する digits 平均値,標準偏差を書き出すときに小数点以下何桁までにするかを指定 デフォルトでは 3 output 出力コネクション デフルトはコンソールに出力 encoding ファイルに出力するときのエンコーディング(デフォルトは OS による) ソース インストールは,以下の 1 行をコピーし,R コンソールにペーストする source("http://aoki2.si.gunma-u.ac.jp/R/src/indep_sample.R", encoding="euc-jp") ##### # # 独立 k 標本の平均値,標準偏差を求め,必要なら平均値・代表値の差の検定を行う # ##### indep.sample <- function(i, # 分析対象の変数が入っているデータフレーム上の列番号または変数名ベクトル j, # 群を表す変数が入っているデータフレーム上の列番号または変数名ベクトル df, # データフレーム latex=TRUE, # LaTeX 形式で集計表を出力する(デフォルトは LaTeX 形式) captions=NULL, # latex=TRUE のときに,各表の表題を表す文字列ベクトルを指定できる(NULL のときはデフォルトの表題) labels=NULL, # latex=TRUE のときに,各表の label を表す文字列ベクトルを指定できる(NULL のときは付けない) test=c("none", "parametric", "non-parametric"), # デフォルト none では検定を行わない。検定を行うときはその種類を指定する statistics=c("mean", "median"), # (平均値,標準偏差)を求めるか(中央値,四分偏差)を求めるかを指定する var.equal=FALSE, # parametric の場合に等分散性を仮定するかどうかの引数 digits=3, # 平均値,標準偏差を表示するときの小数点以下の桁数 output="", # ファイルに出力するときはファイル名(デフォルトはコンソールに出力) encoding=getOption("encoding")) # ファイルに出力するときのエンコーディング(デフォルトは OS による) { # 下請け関数 getNum <- function(str, df) { # 変数名から列番号を得る names <- colnames(df) seq_along(names)[names %in% str] } SIQ <- function(x) return(diff(fivenum(x)[c(2,4)])) # 四分偏差を求める下請け関数 indep.sample.sub <- function(ii, jj) { group <- colnames(df)[jj] # 群を表す変数の名前 df2 <- df[, c(ii, jj)] # データフレームの列番号 ii, jj から 2 変数を取り出す df2 <- subset(df2, complete.cases(df2)) # 欠損値を持つケースを除く x <- df2[, 1] # 分析対象変数 g <- df2[, 2] # 群変数 lst <- list(g) # by 関数を適用するために,群をリスト化する nt <- length(x) # 全体のサンプルサイズ mt <- MEAN(x) # 全体の平均値 st <- SD(x) # 全体の標準偏差 n <- by(x, lst, length) # 各群のサンプルサイズ m <- by(x, lst, MEAN) # 各群の平均値(中央値) s <- by(x, lst, SD) # 各群の標準偏差(四分偏差) nr <- length(table(lst)) # 群の数 if (latex) { # LaTeX 形式で集計結果を出力する cat("\n\\begin{table}[htbp]\n", file=output) # \begin{table}[htbp] if (is.null(captions)) { cat(sprintf("\\caption{%s別の%sの集計}\n", # \caption{○○別の□□の集計} group, colnames(df2)[1]), file=output) } else { cat(sprintf("\\caption{%s}\n", captions[index]), file=output) # \caption{○○○○} } if (!is.null(labels)) { cat(sprintf("\\label{%s}\n", labels[index]), file=output) # \labels{○○○○} } cat("\\centering\n", file=output) # \centering cat("\\begin{tabular}{lccc} \\hline\n",file=output) # \begin{tabular}{lccc} \hline cat(sprintf("& \\multicolumn{3}{c}{%s}\\\\ \\cline{2-4}\n", # \multicolumn{3}{c}{□□} \\ \cline{2-4} colnames(df2)[1]), file=output) cat(group, "データ数", M.str, S.str, sep=" & ", # ○○ & データ数 & 平均値 & 標準偏差 file=output) cat("\\\\ \\hline\n", file=output) # \\ \hline for (l in 1:nr) { # 各群について, cat(names(n)[l], n[l], sprintf(format, m[l]), # 群の名前 & 数値 & 数値 & 数値 sprintf(format, s[l]), sep=" & ", file=output) cat("\\\\", file=output) # \\ if (l == nr) cat("\\hline\n", file=output) # 最後の群なら \hline そうでなければ何もなし else cat("\n", file=output) } cat("全体", nt, sprintf(format, mt), # 全体 & 数値 & 数値 & 数値 sprintf(format, st), sep=" & ", file=output) cat("\\\\ \\hline\n", file=output) # \\ \hline cat("\\end{tabular}\n", file=output) # \end{tabular} } else { # tab で区切って出力する cat("\n表 ", group, "別の", colnames(df2)[1], # 表 ○○別の□□の集計 "の集計", sep="", file=output) cat("\n", colnames(df2)[1], sep="\t", file=output, # □□ fill=TRUE) cat(group, "データ数", M.str, S.str, sep="\t", # ○○ データ数 平均値 標準偏差 file=output, fill=TRUE) for (l in 1:nr) { # 各群について, cat(names(n)[l], n[l], sprintf(format, m[l]), # 群の名前 数値 数値 数値 sprintf(format, s[l]), sep="\t", file=output, fill=TRUE) } cat("全体", nt, sprintf(format, mt), # 全体 数値 数値 数値 sprintf(format, st), sep="\t", file=output, fill=TRUE) } if (nr == 2) { # 2 群の場合には, if (latex && test != "none") { # LaTeX 形式で出力するときには,改行して次の行に出力準備 cat("\\\\ \\noindent\n", file=output) } if (test == "parametric") { # 平均値の差の検定のために t.test 関数を使う res <- t.test(x~g, var.equal=var.equal) # t.test を呼ぶ cat(sprintf(if (latex) "$t$値 = %.3f, 自由度 = %.3f, $P$値 = %.3f\n" else "t 値 = %.3f, 自由度 = %.3f, P 値 = %.3f\n", res$statistic, res$parameter, res$p.value), file=output) } else if (test == "non-parametric") { # マン・ホイットニーの U 検定 res <- wilcox.test(x~g) # wilcox.test を呼ぶ cat(sprintf(if (latex) "$U$ = %.3f, $P$値 = %.3f\n" else "U = %.3f, P 値 = %.3f\n", res$statistic, res$p.value), file=output) } } else if (nr >= 3) { if (latex && test != "none") { # LaTeX 形式で出力するときには,改行して次の行に出力準備 cat("\\\\ \\noindent\n", file=output) } if (test == "parametric") { # 一元配置分散分析 res <- oneway.test(x ~ g, var.equal=var.equal) cat(sprintf(if (latex) "$F$値 = %.3f, 自由度 = (%i, %.3f), $P$値 = %.3f\n" else "F 値 = %.3f, 自由度 = (%i, %.3f), P 値 = %.3f\n", res$statistic, res$parameter[1], res$parameter[2], res$p.value), file=output) } else if (test == "non-parametric") { # クラスカル・ウォリス検定 res <- kruskal.test(x~g) cat(sprintf(if (latex) "$\\chi_{kw}^2$ = %.3f, 自由度 = %i, $P$値 = %.3f\n" else "カイ二乗値(kw) = %.3f, 自由度 = %i, P 値 = %.3f\n", res$statistic, res$parameter, res$p.value), file=output) } } if (latex) { # LaTeX 形式で集計結果を出力する場合は, cat("\\end{table}\n", file=output) # \end{table} } } # 関数本体 if (output != "") { # 結果をファイルに出力する場合の処理 output <- file(output, open="w", encoding=encoding) } test <- match.arg(test) # 引数が省略形で与えられたときに,正確な名前をとる statistics <- match.arg(statistics) # 引数が省略形で与えられたときに,正確な名前をとる if (statistics == "mean") { MEAN <- mean # 位置の母数を求める関数:平均値 SD <- sd # 散布度を求める関数:標準偏差 M.str <- "平均値" S.str <- "標準偏差" } else { MEAN <- median # 位置の母数を求める関数:中央値 SD <- SIQ # 散布度を求める関数:四分偏差 M.str <- "中央値" S.str <- "四分偏差" } format <- paste("%.", digits, "f", sep="") # 小数点以下 3 桁で出力する書式 if (is.character(i[1])) { i <- getNum(i, df) } if (is.character(j[1])) { j <- getNum(j, df) } index <- 0 for (jj in j) { # j はベクトルまたはスカラーで,群を表す変数がある列番号 for (ii in i) { # i はベクトルまたはスカラーで,分析対象変数がある列番号 if (ii != jj) { # i, j の全ての組み合わせについて(ii と jj が違うときのみ), index <- index+1 # 集計のための下請け関数 indep.sample.sub を呼ぶ indep.sample.sub(ii, jj) } } } if (output != "") { # 結果をファイルに出力した場合の後始末 close(output) } } 使用例 男女 血液型 測定値1 測定値2 1 2 101.3 135.8 1 2 101.8 165.7 1 1 122.6 178.9 2 4 114.4 155.8 1 4 89.7 143.0 2 2 83.4 123.7 1 2 93.2 151.3 2 1 99.6 108.8 1 3 127.5 101.6 2 4 104.7 156.1 2 4 84.2 173.7 2 2 90.6 122.6 1 1 90.0 102.2 1 1 97.6 176.7 2 4 97.4 125.0 1 1 92.8 172.8 2 3 103.4 146.5 2 2 101.2 159.0 2 2 87.8 148.0 2 1 95.5 140.5 1 2 89.0 171.8 2 3 94.3 121.2 1 3 69.9 114.9 1 3 79.4 160.0 1 3 105.7 98.1 1 2 95.2 133.5 2 4 113.7 86.5 2 2 106.8 148.9 2 2 112.1 206.1 2 1 91.7 163.0 のようなファイル test.dat があるとする 入力と変数の定義 df <- read.table("test.dat", header=TRUE) df[,1] <- factor(df[,1], levels=1:2, labels=c("男", "女")) ファイルに出力するとき indep.sample(3:4, 1, df, latex=FALSE, output="ファイル名") 出力結果例 latex=FALSE の場合 > indep.sample(3:4, 1, df, latex=FALSE) 表 男女別の測定値1の集計 測定値1 男女 データ数 平均値 標準偏差 男 14 96.836 15.060 女 16 98.800 9.969 全体 30 97.883 12.413 表 男女別の測定値2の集計 測定値2 男女 データ数 平均値 標準偏差 男 14 143.307 29.535 女 16 142.838 28.217 全体 30 143.057 28.336 > indep.sample(3:4, 1, df, latex=FALSE, test="parametric") 表 男女別の測定値1の集計 測定値1 男女 データ数 平均値 標準偏差 男 14 96.836 15.060 女 16 98.800 9.969 全体 30 97.883 12.413 t 値 = -0.415, 自由度 = 22.068, P 値 = 0.682 表 男女別の測定値2の集計 測定値2 男女 データ数 平均値 標準偏差 男 14 143.307 29.535 女 16 142.838 28.217 全体 30 143.057 28.336 t 値 = 0.044, 自由度 = 27.085, P 値 = 0.965 > indep.sample(3:4, 1, df, latex=FALSE, test="parametric", var.equal=FALSE) 表 男女別の測定値1の集計 測定値1 男女 データ数 平均値 標準偏差 男 14 96.836 15.060 女 16 98.800 9.969 全体 30 97.883 12.413 t 値 = -0.415, 自由度 = 22.068, P 値 = 0.682 表 男女別の測定値2の集計 測定値2 男女 データ数 平均値 標準偏差 男 14 143.307 29.535 女 16 142.838 28.217 全体 30 143.057 28.336 t 値 = 0.044, 自由度 = 27.085, P 値 = 0.965 > indep.sample(3:4, 1, df, latex=FALSE, test="parametric", var.equal=TRUE) 表 男女別の測定値1の集計 測定値1 男女 データ数 平均値 標準偏差 男 14 96.836 15.060 女 16 98.800 9.969 全体 30 97.883 12.413 t 値 = -0.426, 自由度 = 28.000, P 値 = 0.673 表 男女別の測定値2の集計 測定値2 男女 データ数 平均値 標準偏差 男 14 143.307 29.535 女 16 142.838 28.217 全体 30 143.057 28.336 t 値 = 0.045, 自由度 = 28.000, P 値 = 0.965 latex=TRUE(デフォルト)の場合 > indep.sample(3, 1, df, test="non-parametric") \begin{table}[htbp] \caption{男女別の測定値1の集計} \begin{center} \begin{tabular}{lccc} \hline & \multicolumn{3}{c}{測定値1}\\ \cline{2-4} 男女 & データ数 & 平均値 & 標準偏差\\ \hline 男 & 14 & 96.836 & 15.060\\ 女 & 16 & 98.800 & 9.969\\\hline 全体 & 30 & 97.883 & 12.413\\ \hline \end{tabular} \\ \noindent $U$ = 97.000, $P$値 = 0.552 \end{center} \end{table}