rstatistical-test

Why does the `conf.level` argument have no impact on the result of the `binom::binom.confint` function?


library(binom)

x <- 10  
n <- 20 

binom.confint(x, n, methods = "prop.test", conf.level = 0.80)
#      method  x  n mean    lower    upper
# 1 prop.test 10 20  0.5 0.299298 0.700702
binom.confint(x, n, methods = "prop.test", conf.level = 0.95)
#      method  x  n mean    lower    upper
# 1 prop.test 10 20  0.5 0.299298 0.700702

It does work with binom.test though

binom.test(x, n, conf.level=0.80)$conf.int
# [1] 0.3381709 0.6618291
binom.test(x, n, conf.level=0.95)$conf.int
# [1] 0.2719578 0.7280422

Solution

  • This seems to be a bug in the package. According to the docs for the methods argument:

    prop.test: equivalent to prop.test(x = x, n = n, conf.level = conf.level)$conf.int.

    However, if we look at the source:

    if(any(method == "prop.test") || all.methods) {
        ci <- lapply(seq_along(x), function(i) stats::prop.test(x[i], n[i])$conf.int)
    }
    

    You can see that the conf.level argument is not passed to prop.test(), so it always uses the default (0.95). It should say:

    lapply(seq_along(x), function(i) stats::prop.test(x[i], 
        n[i], conf.level = conf.level)$conf.int)
    

    This would lead to different output for different CIs:

    lapply(seq_along(x), function(i) stats::prop.test(x[i], 
            n[i], conf.level = 0.95)$conf.int)
    # [[1]]
    # [1] 0.299298 0.700702
    
    lapply(seq_along(x), function(i) stats::prop.test(x[i], 
            n[i], conf.level = 0.8)$conf.int)
    # [[1]]
    # [1] 0.362262 0.637738
    

    I am not entirely sure how to fix this. The Github repo seems to be read-only so you can't open an issue or Pull Request. Perhaps you could contact the package maintainers using the details on the CRAN page. In the meantime you could try the hot fix below.

    Hot fix

    This is not the way to build a robust codebase but if you need a short-term solution you can patch the function like this:

    # Replace the relevant line
    binom_confint_body2  <- sub(
        "function(i) stats::prop.test(x[i], n[i])$conf.int)",
        "function(i) stats::prop.test(x[i], n[i], conf.level = conf.level)$conf.int)",
        body(binom.confint), 
        fixed = TRUE
    )
    
    # Get access to binom.methods in the binom environment
    binom_confint_body2  <- gsub(
        "binom.methods",
        "binom:::binom.methods",
        binom_confint_body2, 
        fixed = TRUE
    )
    
    # Create the function text
    binom_confint2_txt  <- paste(c(
        'binom.confint2  <- function (x, n, conf.level = 0.95, methods = "all", ...) {',
        binom_confint_body2,
        "}}",
        collapse = "\n"
    ))
    
    # eval the function text to create binom.confint2()
    eval(parse(text = binom_confint2_txt))
    

    Then we can run binom.confin2:

    # Run the function
    binom.confint2(x, n, methods = "prop.test", conf.level = 0.95)
    #      method  x  n mean    lower    upper
    # 1 prop.test 10 20  0.5 0.299298 0.700702
    
    binom.confint2(x, n, methods = "prop.test", conf.level = 0.80)
    #      method  x  n mean    lower    upper
    # 1 prop.test 10 20  0.5 0.362262 0.637738