Confidence Intervals for Lethal Dose (LD) for Logistic Regression in R

前端 未结 1 1492
一个人的身影
一个人的身影 2021-02-06 18:40

I want to find Lethal Dose (LD50) with its confidence interval in R. Other softwares line Minitab, SPSS, SAS provide three different versions of such c

1条回答
  •  既然无缘
    2021-02-06 19:39

    From the package drc, you can get the ED50 (same calculation), along with confidence intervals.

    library(drc) # Directly borrowed from the drc manual
    
    mod <- drm(affected/total ~ dose, weights = total,
    data = finney71[finney71$dose != 0, ], fct = LL2.2(), type = "binomial")
    
    #intervals on log scale
    ED(mod, c(50, 90, 95), interval = "fls", reference = "control") 
    
    Estimated effective doses
    (Back-transformed from log scale-based confidence interval(s))
    
         Estimate   Lower   Upper
    1:50   4.8289  4.3637  5.3437
    1:90   9.8021  8.0735 11.9008
    1:95  12.4704  9.7483 15.9525
    

    Which matches the manual output.

    The "finney71" data is included in this package, and your calculation of confidence intervals exactly matches the example given by the drc folks, down to the "# from MASS" comment. You should give credit to them, rather than claiming you wrote the code.


    There's a few other ways to figure this out. One is using parametric bootstrap, which is conveniently available through the boot package.

    First, we'll refit the model.

    library(boot)
    
    finney71 <- finney71[finney71$dose != 0,] # pre-clean data 
    fm1 <- glm(cbind(affected, total-affected) ~ log(dose),
                     family=binomial(link = logit), 
                     data=finney71)
    

    And for illustration, we can figure out the LD50 and LD75.

    statfun <- function(dat, ind) {
        mod <- update(fm1, data = dat[ind,])
        coefs <- coef(mod)
        c(exp(-coefs[1]/coefs[2]),
          exp((log(0.75/0.25) - coefs[2])/coefs[1]))
    }
    
    boot_out <- boot(data = finney71, statistic = statfun, R = 1000)
    

    The boot.ci function can work out a variety of confidence intervals for us, using this object.

    boot.ci(boot_out, index = 1, type = c('basic', 'perc', 'norm'))
    ##BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
    ##Based on 999 bootstrap replicates
    ##
    ##CALL : 
    ##boot.ci(boot.out = boot_out, type = c("basic", "perc", "norm"), 
    ##    index = 1)
    
    ##Intervals : 
    ##Level      Normal              Basic              Percentile     
    ##95%   ( 3.976,  5.764 )   ( 4.593,  5.051 )   ( 4.607,  5.065 )  
    

    The confidence intervals using the normal approximation are thrown off quite a bit by a few extreme values, which the basic and percentile-based intervals are more robust to.

    One interesting thing to note: if the sign of the slope is sufficiently unclear, we can get some rather extreme values (simulated as in this answer, and discussed more thoroughly in this blog post by Andrew Gelman).

    set.seed(1)
    x <- rnorm(100)        
    z = 0.05 + 0.1*x*rnorm(100, 0, 0.05) # small slope and more noise
    pr = 1/(1+exp(-z))        
    y = rbinom(1000, 1, pr)   
    sim_dat <- data.frame(x, y)  
    sim_mod <- glm(y ~ x, data = sim_dat, family = 'binomial')
    
    statfun <- function(dat, ind) {
        mod <- update(sim_mod, data = dat[ind,])
        -coef(mod)[1]/coef(mod)[2]
    }
    sim_boot <- boot(data = sim_dat, statistic = statfun, R = 1000)
    hist(sim_boot$t[,1], breaks = 100, 
              main = "Bootstrap of simulated model")
    

    The delta method above gives us mean = 6.448, lower ci = -36.22, and upper ci = 49.12, and all of the bootstrap CIs give us similarly extreme estimates.

    ##Level      Normal              Basic              Percentile     
    ##95%   (-232.19,  247.76 )   ( -20.17,   45.13 )   ( -32.23,   33.06 )  
    

    0 讨论(0)
提交回复
热议问题