独立 k 標本     Last modified: Dec 12, 2012

目的

独立 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}


・ 直前のページへ戻る  ・ E-mail to Shigenobu AOKI

Made with Macintosh