ED50     Last modified: Apr 13, 2004

目的

ED50  や LD50 を求める

使用法

ed50(x, n, r, transform=c("none", "ln", "log"))

引数

x	各群の用量(ベクトル)
n	各群の例数(ベクトル)
r	各群の反応数(ベクトル)
transform
	用量をそのまま使うとき(デフォールト)は "none"
	自然対数変換するときは "ln"
	常用対数変換するときは "log"

ソース

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

# ED50 や LD50 を求める
ed50 <- function(    x,                                      # 各群の用量ベクトル
                        n,                                      # 各群の例数ベクトル
                        r,                                      # 各群の反応数ベクトル
                        transform=c("none", "ln", "log"))       # 対数変換をするかどうか
{
        # 第一近似
        estimation1 <- function(x, n, r)
        {
                select <- r > 0 & r < n                                # 条件に合うものだけを取り出す
                x <- x[select]
                n <- n[select]
                r <- r[select]
                p9 <- r/n                                    # 標本比率
                y <- qnorm(p9)+5                             # プロビット変換
                w <- 1
                wx2 <- sum(w*x^2)
                wy <- sum(w*y)
                wx <- sum(w*x)
                wyx <- sum(w*y*x)
                ww <- length(x)
                temp <- ww*wx2-wx^2
                alpha <- (wx2*wy-wx*wyx)/temp                        # 切片
                beta <- (ww*wyx-wx*wy)/temp                  # 傾き
                ollf <- sum(r*log(p9)+(n-r)*log(1-p9))               # 観察値の対数尤度
                list(ollf=ollf, alpha=alpha, beta=beta)
        }

        # 第二近似(第一近似から出発して収束計算)
        estimation2 <- function(x, n, r, alpha, beta, epsilon=1e-5)
        {
                sqrt.pi2 <- 1/sqrt(2*pi)
                for (ii in 1:100) {
                        y <- alpha+beta*x
                        x9 <- y-5
                        p9 <- pnorm(x9)
                        z <- exp(-x9^2/2)*sqrt.pi2
                        y <- y+ (r/n-p9)/z
                        w <- n*z^2/((1-p9)*p9)
                        wx2 <- sum(w*x^2)
                        wy <- sum(w*y)
                        wx <- sum(w*x)
                        wyx <- sum(w*y*x)
                        ww <- sum(w)
                        ssnwx <- wx2-wx^2/ww
                        beta1 <- (wyx-wx*wy/ww)/ssnwx
                        xbar <- wx/ww
                        alpha1 <- (wy/ww)-beta1*xbar
                        if (abs(alpha-alpha1)/alpha < epsilon && abs(beta-beta1)/beta < epsilon) {
                                ed50 <- (5-alpha1)/beta1     # ED50
                                se <- sqrt(1/ww+(ed50-xbar)^2/ssnwx)/abs(beta1)
                                g <- (qnorm(0.975)/beta1)^2/ssnwx
                                cl <- ed50+g*(ed50-xbar)/(1-g)
                                pm = qnorm(0.975)/beta1/(1-g)*sqrt((1-g)/ww+(ed50-xbar)^2/ssnwx)
                                return(list(alpha=alpha1, beta=beta1, ED50=ed50, SE=se, cll =cl-pm, clu=cl+pm))
                        }
                        alpha <- alpha1
                        beta <- beta1
                }
                stop("収束しませんでした")
        }

        # 適合度の検定
        GoodnessOfFitness <- function(x, n, r, alpha, beta)
        {
                p9 <- pnorm(alpha+beta*x-5)
                p0 <- r/n
                cllf <- sum(r*log(p9)+(n-r)*log(1-p9))               # あてはめ後の対数尤度
                q <- 1-p9
                chi <- sum(n*(p0-p9)^2/(q-q^2))                      # カイ二乗値
                df <- length(x)-2                            # 自由度
                p <- pchisq(chi, df, lower.tail=FALSE)               # P 値
                list(tbl=cbind(x, n, r, n*p9, p0, p9), cllf=cllf, chi=chi, df=df, p=p)
        }

        # 書式付きプリント関数
        printf <- function(fmt, ...) cat(sprintf(fmt, ...))

# ed50 関数本体開始

        transform <- match.arg(transform)                    # 引数の補完
        dose <- "x"                                          # 用量のラベル
        inv <- function(x) x                                 # 無変換のときの逆関数(無駄だけど)
        if (transform != "none") {
                stopifnot(x > 0)
                if (transform == "ln") {
                        x <- log(x)                          # 自然対数変換
                        dose <- "ln(x)"                              # 用量のラベル
                        inv <- function(x) exp(x)            # 自然対数の逆関数
                }
                else if (transform == "log") {
                        x <- log10(x)                                # 常用対数変換
                        dose <- "log10(x)"                   # 用量のラベル
                        inv <- function(x) 10^x                      # 常用対数の逆関数
                }
        }

        result <- estimation1(x, n, r)                               # 第一近似解
        ollf <- result$ollf                                  # 観察値の対数尤度
        alpha <- result$alpha                                        # 切片
        beta <- result$beta                                  # 傾き

        result <- estimation2(x, n, r, alpha, beta,          # 第二近似解
                                epsilon=1e-13)
        alpha <- result$alpha                                        # 切片
        beta <- result$beta                                  # 傾き
        printf("P_hat = %g + %g * %s\n", alpha, beta, dose)
        printf("ED50 = %g\n", inv(result$ED50))
        printf("95%% 信頼区間 = [ %g, %g ]\n\n", inv(result$cll), inv(result$clu))

        result <- GoodnessOfFitness(x, n, r, alpha, beta)
        printf("%7s %7s %7s %10s %10s %10s\n", "用量", "n", "r", "e", "r/n", "e/n")
        for (i in 1:nrow(result$tbl)) {
                temp <- result$tbl[i,]
                printf("%7.5g %7.0f %7.0f %10.5g %10.5f %10.5f\n", temp[1], temp[2], temp[3], temp[4], temp[5], temp[6])
        }
        printf("\n")
        printf("カイ二乗値 = %g, 自由度 = %d, P 値 = %.3f\n\n", result$chi, as.integer(result$df), result$p)
        printf("  観察値の対数尤度 = %g\n", ollf)
        printf("あてはめ後の対数尤度 = %g\n", result$cllf)
}


使用例

x <- c(10, 20, 30)
n <- rep(10, 3)
r <- c(1, 5, 8)
ed50(x, n, r)
ed50(x, n, r, tr="ln")

出力結果例

> ed50(x, n, r)	# 用量をそのまま使う場合
P_hat = 2.78185 + 0.104719 * x	# α,βの推定値
ED50 = 21.1818	# ED50 の推定値
95% 信頼区間 = [ 15.2076, 28.0387 ]	# ED50 の 95% 信頼区間

   用量       n       r          e        r/n        e/n	# サマリー
     10      10       1     1.2081    0.10000    0.12081
     20      10       5     4.5075    0.50000    0.45075
     30      10       8     8.2211    0.80000    0.82211

カイ二乗値 = 0.172154, 自由度 = 1, P 値 = 0.678	# 適合度の検定の結果

  観察値の対数尤度 = -15.1863
あてはめ後の対数尤度 = -15.2728

> ed50(x, n, r, tr="ln")	# 用量を自然対数変換する場合
P_hat = -0.745754 + 1.92892 * ln(x)
ED50 = 19.663
95% 信頼区間 = [ 13.8884, 27.9769 ]

   用量       n       r          e        r/n        e/n
 2.3026      10       1    0.96075    0.10000    0.09608
 2.9957      10       5     5.1308    0.50000    0.51308
 3.4012      10       8     7.9243    0.80000    0.79243

カイ二乗値 = 0.0120987, 自由度 = 1, P 値 = 0.912

  観察値の対数尤度 = -15.1863
あてはめ後の対数尤度 = -15.1924


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

Made with Macintosh