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