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

58 Views Asked by At
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
1

There are 1 best solutions below

0
SamR On BEST ANSWER

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