サンプルサイズ     Last modified: Nov 16, 2004

目的

二群の平均値の差(両側検定)を行うときに必要な各群あたりのサンプルサイズを求める。
R には,power.t.test という関数が用意されている。精度的には power.t.test を使う方がよい。

使用法

sample.size(alpha, powd, esize)

引数

alpha	有意水準(α)
powd	望む検出力(1-β)
esize	効果量

ソース

インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/sample_size.R", encoding="euc-jp")

# 二群の平均値の差(両側検定)を行うときに必要な各群あたりのサンプルサイズを求める
sample.size <- function(alpha,                                       # 有意水準
                        powd,                                   # 検出力
                        esize)                                  # 効果量
{

        gcf <- function(a, x)
        {
                ITMAX <- 100
                EPS <- 3e-7
                FPMIN <- 1e-30
        
                b <- x+1-a
                c <- 1/FPMIN
                d <- 1/b
                h <- d
                for (i in 1:ITMAX) {
                        an <- -i*(i-a)
                        b <- b+ 2
                        d <- an*d+b
                        if (abs(d) < FPMIN) d <- FPMIN
                        c <- b+an/c
                        if (abs(c) < FPMIN) c <- FPMIN
                        d <- 1/d
                        del <- d*c
                        h <- h*del
                        if (abs(del-1) < EPS) {
                                return(exp(-x+a*log(x)-lgamma(a))*h)
                        }
                }
                stop("error")
        }

        gser <- function(a, x)                                       # 不完全ガンマ関数
        {
                ITMAX <- 100
                EPS <- 3e-7
        
                if (x == 0) {
                        return(0)
                }
                else if (x > 0) {
                        ap <- a
                        del <- sum <- 1/a
                        for (n in 1:ITMAX) {
                                ap <- ap+1
                                del <- del*x/ap
                                sum <- sum+del
                                if (abs(del) < abs(sum)*EPS) {
                                        return(sum*exp(-x+a*log(x)-lgamma(a)))
                                }
                        }
                }
                stop("error")
        }

        gammp <- function(a, x)                                      # pgamma(x, a)
        {
                ifelse(x < a+1, gser(a, x), 1-gcf(a, x))
        }

        erff <- function(x)                                  # 1-2*pnorm(x*sqrt(2), lower.tail=FALSE)
        {
                ifelse(x < 0, -gammp(0.5, x*x), gammp(0.5, x*x))
        }

        betacf <- function(a, b, x)
        {
                ITMAX <- 100
                EPS <- 3e-7
                FPMIN <- 1e-30
        
                qab <- a+b
                qap <- a+1
                qam <- a-1
                c <- 1
                d <- 1-qab*x/qap
                if (abs(d) < FPMIN) d <- FPMIN
                d <- 1/d
                h <- d
                for (m in 1:ITMAX) {
                        m2 <- 2*m
                        aa <- m*(b-m)*x/((qam+m2)*(a+m2))
                        d <- 1+aa*d
                        if (abs(d) < FPMIN) d <- FPMIN
                        c <- 1+aa/c
                        if (abs(c) < FPMIN) c <- FPMIN
                        d <- 1/d
                        h <- h*d*c
                        aa <- -(a+m)*(qab+m)*x/((a+m2)*(qap+m2))
                        d <- 1+aa*d
                        if (abs(d) < FPMIN) d <- FPMIN
                        c <- 1+aa/c
                        if (abs(c) < FPMIN) c <- FPMIN
                        d <- 1/d
                        del <- d*c
                        h <- h*del
                        if (abs(del-1) < EPS) return(h)
                }
                stop("error")
        }

        betai <- function(a, b, x)                           # 不完全ベータ関数
        {
                if (x < 0 || x > 1) stop("error")
                bt <- ifelse(x == 0 || x == 1, 0, exp(lbeta(a, b)+a*log(x)+b*log(1-x)))
                ifelse(x < (a+1)/(a+b+2), bt*betacf(a, b, x)/a, 1-bt*betacf(b, a, 1-x)/b)
        }

        sub1 <- function(n, esize, alpha)
        {
                df <- n-2
                t <- qt(alpha/2, df, lower.tail=FALSE)
                dd <- 1-0.25/df+1/(32*df*df)
                0.5*(1+erff((esize*sqrt(n)-sqrt(2)*t*dd) / (2*sqrt(1+t*t*(1-dd*dd)))))
        }

# 関数本体

        n <- 0
        powa <- 0
        INTV <- 200
        EPS <- 0.001
        dir <- -1

        while (powa <= powd) {
                n <- n+100
                powa <- sub1(n, esize, alpha)
        }

        while (abs((powa-powd)/powd) >= EPS) {
                INTV <- INTV*0.5
                n <- n+dir*INTV*0.5
                powa <- sub1(n, esize, alpha)
                dir <- ifelse(powa < powd, 1, -1)
        }
        return(n)
}


使用例

sample.size(0.05, 0.8, 0.5)

出力結果例

> sample.size(0.05, 0.8, 0.5)
[1] 64.84375

同じことを power.t.test でやってみる。

> power.t.test(sig.level=0.05, power=0.8, delta=0.5)

     Two-sample t test power calculation 

              n = 63.76576
          delta = 0.5
             sd = 1
      sig.level = 0.05
          power = 0.8
    alternative = two.sided

 NOTE: n is number in *each* group 


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

Made with Macintosh