pROC/ 0000755 0001762 0000144 00000000000 15042637256 011067 5 ustar ligges users pROC/tests/ 0000755 0001762 0000144 00000000000 15040443562 012222 5 ustar ligges users pROC/tests/testthat/ 0000755 0001762 0000144 00000000000 15042637256 014071 5 ustar ligges users pROC/tests/testthat/test-ci.formula.R 0000644 0001762 0000144 00000002271 15040443562 017223 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.formula")
test_that("bootstrap cov works with smooth and !reuse.auc", {
skip_slow()
if (getRversion() > "3.6.0") {
suppressWarnings(RNGkind(sample.kind = "Rounding"))
}
for (pair in list(
list(ci, list()),
list(ci.se, list(boot.n = 10)),
list(ci.sp, list(boot.n = 10)),
list(ci.thresholds, list(boot.n = 10)),
list(ci.coords, list(boot.n = 10, x = 0.5)),
list(ci.auc, list())
)) {
fun <- pair[[1]]
# First calculate ci with .default
args.default <- c(
list(
response = aSAH$outcome,
predictor = aSAH$s100b
),
pair[[2]]
)
set.seed(42) # For reproducible CI
obs.default <- do.call(fun, args.default)
# Then with .formula
args.formula <- c(
list(
formula = outcome ~ s100b,
data = aSAH
),
pair[[2]]
)
set.seed(42) # For reproducible CI
obs.formula <- do.call(fun, args.formula)
# Here we check both returned the same result
# We ignore attributes, as we have different
# roc objects, and unfortunately equivalent means
# we only test near equality
expect_equivalent(obs.default, obs.formula)
}
})
pROC/tests/testthat/helper-skip.R 0000644 0001762 0000144 00000000450 15040443562 016427 0 ustar ligges users # Skip slow tests
skip_slow <- function(message = "Slow test skipped") {
if (exists("run_slow_tests", envir = .GlobalEnv)) {
if (!get("run_slow_tests", envir = .GlobalEnv)) {
skip(message)
}
} else if (!identical(Sys.getenv("RUN_SLOW_TESTS"), "true")) {
skip(message)
}
}
pROC/tests/testthat/test-cov.R 0000644 0001762 0000144 00000011054 15040443562 015752 0 ustar ligges users library(pROC)
data(aSAH)
test_that("cov with delong works", {
expect_equal(cov(r.wfns, r.ndka), -0.000532967856762438)
expect_equal(cov(r.ndka, r.s100b), -0.000756164938056579)
expect_equal(cov(r.s100b, r.wfns), 0.00119615567376754)
})
test_that("cov with obuchowski works", {
expect_equal(cov(r.wfns, r.ndka, method = "obuchowski"), -3.917223e-06)
expect_equal(cov(r.ndka, r.s100b, method = "obuchowski"), 0.0007945308)
expect_equal(cov(r.s100b, r.wfns, method = "obuchowski"), 0.0008560803)
})
test_that("cov works with auc and mixed roc/auc", {
expect_equal(cov(auc(r.wfns), auc(r.ndka)), -0.000532967856762438)
expect_equal(cov(auc(r.ndka), r.s100b), -0.000756164938056579)
expect_equal(cov(r.s100b, auc(r.wfns)), 0.00119615567376754)
})
test_that("cov with delong and percent works", {
expect_equal(cov(r.wfns.percent, r.ndka.percent), -5.32967856762438)
expect_equal(cov(r.ndka.percent, r.s100b.percent), -7.56164938056579)
expect_equal(cov(r.s100b.percent, r.wfns.percent), 11.9615567376754)
})
test_that("cov with delong, percent and mixed roc/auc works", {
expect_equal(cov(auc(r.wfns.percent), r.ndka.percent), -5.32967856762438)
expect_equal(cov(r.ndka.percent, auc(r.s100b.percent)), -7.56164938056579)
expect_equal(cov(auc(r.s100b.percent), auc(r.wfns.percent)), 11.9615567376754)
})
test_that("cov with obuchowski, percent and mixed roc/auc works", {
expect_equal(cov(auc(r.wfns.percent), r.ndka.percent, method = "obuchowski"), -0.03917223)
expect_equal(cov(r.ndka.percent, auc(r.s100b.percent), method = "obuchowski"), 7.9453082)
expect_equal(cov(auc(r.s100b.percent), auc(r.wfns.percent), method = "obuchowski"), 8.560803)
})
test_that("cov with different auc specifications warns", {
expect_warning(cov(r.wfns, r.ndka.percent))
expect_warning(cov(r.wfns.percent, r.ndka))
# Also mixing auc/roc
expect_warning(cov(auc(r.wfns), r.ndka.percent))
expect_warning(cov(r.wfns, auc(r.ndka.percent)))
expect_warning(cov(r.wfns, auc(r.ndka.percent)))
})
test_that("cov with delong, percent and direction = >", {
expect_equal(cov(r.ndka.percent, r.s100b.percent), -7.56164938056579)
})
test_that("cov with delong, percent, direction = > and mixed roc/auc", {
r1 <- roc(aSAH$outcome, -aSAH$ndka, percent = TRUE)
r2 <- roc(aSAH$outcome, -aSAH$s100b, percent = TRUE)
expect_equal(cov(r1, r2), -7.56164938056579)
expect_equal(cov(auc(r1), auc(r2)), -7.56164938056579)
expect_equal(cov(auc(r1), r2), -7.56164938056579)
expect_equal(cov(r1, auc(r2)), -7.56164938056579)
})
test_that("cov with bootstrap works", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42)
expect_equal(cov(r.wfns, r.ndka, method = "bootstrap", boot.n = 100), -0.000648524)
expect_equal(cov(r.ndka.percent, r.s100b.percent, method = "bootstrap", boot.n = 100), -7.17528365)
expect_equal(cov(r.s100b.partial1, r.wfns.partial1, method = "bootstrap", boot.n = 100), 2.294465e-05)
expect_equal(cov(r.wfns, r.ndka, method = "bootstrap", boot.n = 100, boot.stratified = FALSE), -0.0007907488)
})
test_that("bootstrap cov works with mixed roc, auc and smooth.roc objects", {
skip_slow()
for (roc1 in list(r.s100b, auc(r.s100b), smooth(r.s100b), r.s100b.partial2, r.s100b.partial2$auc)) {
for (roc2 in list(r.wfns, auc(r.wfns), smooth(r.wfns), r.wfns.partial1, r.wfns.partial1$auc)) {
n <- round(runif(1, 3, 9)) # keep boot.n small
stratified <- sample(c(TRUE, FALSE), 1)
suppressWarnings( # All sorts of warnings are expected
obtained <- cov(roc1, roc2,
method = "bootstrap",
boot.n = n, boot.stratified = stratified
)
)
expect_is(obtained, "numeric")
expect_false(is.na(obtained))
}
}
})
test_that("bootstrap cov works with smooth and !reuse.auc", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
# First calculate cov by giving full curves
roc1 <- smooth(roc(aSAH$outcome, aSAH$wfns, partial.auc = c(0.9, 1), partial.auc.focus = "sensitivity"))
roc2 <- smooth(roc(aSAH$outcome, aSAH$s100b, partial.auc = c(0.9, 1), partial.auc.focus = "sensitivity"))
suppressWarnings(RNGkind(sample.kind = "Rejection"))
set.seed(42) # For reproducible CI
expected_cov <- cov(roc1, roc2, boot.n = 100)
expect_equal(expected_cov, -0.0000030024)
# Now with reuse.auc
set.seed(42) # For reproducible CI
obtained_cov <- cov(smooth(r.wfns), smooth(r.s100b),
reuse.auc = FALSE,
partial.auc = c(0.9, 1), partial.auc.focus = "sensitivity",
boot.n = 100
)
expect_equal(expected_cov, obtained_cov)
})
pROC/tests/testthat/test-print.R 0000644 0001762 0000144 00000020102 15040443562 016311 0 ustar ligges users library(pROC)
data(aSAH)
context("print")
test_that("print.auc works", {
expect_output(print(auc(r.wfns)), "^Area under the curve: 0.8237$")
expect_output(print(auc(r.ndka.percent)), "^Area under the curve: 61.2%$")
expect_output(print(r.ndka.partial1$auc), "^Partial area under the curve \\(specificity 0\\.99-0\\.9\\): 0\\.01046$")
expect_output(print(r.s100b.percent.partial1$auc), "^Partial area under the curve \\(specificity 99%-90%\\): 2.983%$")
expect_output(print(r.s100b.partial2$auc), "^Partial area under the curve \\(sensitivity 0.99-0.9\\): 0.01376$")
})
test_that("print.roc works", {
expect_known_output(print(r.wfns), "print_output/r.wfns")
expect_known_output(print(r.ndka), "print_output/r.ndka")
expect_known_output(print(r.s100b), "print_output/r.s100b")
expect_known_output(print(r.wfns.percent), "print_output/r.wfns.percent")
expect_known_output(print(r.ndka.percent), "print_output/r.ndka.percent")
expect_known_output(print(r.s100b.percent), "print_output/r.s100b.percent")
expect_known_output(print(r.wfns.partial1), "print_output/r.wfns.partial1")
expect_known_output(print(r.ndka.partial1), "print_output/r.ndka.partial1")
expect_known_output(print(r.s100b.partial1), "print_output/r.s100b.partial1")
expect_known_output(print(r.wfns.percent.partial1), "print_output/r.wfns.percent.partial1")
expect_known_output(print(r.ndka.percent.partial1), "print_output/r.ndka.percent.partial1")
expect_known_output(print(r.s100b.percent.partial1), "print_output/r.s100b.percent.partial1")
expect_known_output(print(r.s100b.partial2), "print_output/r.s100b.partial2")
expect_known_output(print(roc(outcome ~ ndka, aSAH)), "print_output/ndka_formula")
})
test_that("print.multiclass.roc works", {
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka)), "print_output/multiclass"), "2")
expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, levels = c(3, 4, 5))), "print_output/multiclass_levels")
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, percent = TRUE)), "print_output/multiclass_percent"), "2")
})
test_that("print.multiclass.roc works", {
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka)), "print_output/multiclass"), "2")
expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, levels = c(3, 4, 5))), "print_output/multiclass_levels")
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, percent = TRUE)), "print_output/multiclass_percent"), "2")
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, partial.auc = c(1, .9))), "print_output/multiclass_partial"), "2")
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$ndka, partial.auc = c(1, .9), partial.auc.focus = "se")), "print_output/multiclass_partial_se"), "2")
expect_warning(expect_known_output(print(multiclass.roc(aSAH$gos6, aSAH$wfns, partial.auc = c(1, .9), partial.auc.correct = TRUE)), "print_output/multiclass_partial_correct"), "2")
})
test_that("print.multiclass_roc_multivariate works", {
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
set.seed(42)
preds <- lapply(n, function(x) runif(x, 0.4, 0.6))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.7)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0.2, 0.8)),
"X3" = c(runif(n[1] + n[2], 0.3, 0.7), preds[[3]])
))
expect_known_output(print(multiclass.roc(responses, predictor)), "print_output/mv_multiclass")
expect_warning(expect_known_output(print(multiclass.roc(responses, predictor, levels = c("X2", "X3"))), "print_output/mv_multiclass_levels"), "X1")
expect_known_output(print(multiclass.roc(responses, predictor, percent = TRUE)), "print_output/mv_multiclass_percent")
expect_known_output(print(multiclass.roc(responses, predictor, partial.auc = c(1, .9))), "print_output/mv_multiclass_partial")
expect_known_output(print(multiclass.roc(responses, predictor, partial.auc = c(1, .9), partial.auc.focus = "se")), "print_output/mv_multiclass_partial_se")
expect_known_output(print(multiclass.roc(responses, predictor, partial.auc = c(1, .9), partial.auc.correct = TRUE)), "print_output/mv_multiclass_partial_correct")
})
test_that("print works with a formula", {
expect_known_output(print(roc(outcome ~ ndka, aSAH)), "print_output/r.ndka.formula")
expect_warning(expect_known_output(print(multiclass.roc(gos6 ~ ndka, aSAH)), "print_output/mv_multiclass.ndka.formula"), "2")
})
test_that("print works without the auc", {
expect_known_output(print(roc(outcome ~ ndka, aSAH, auc = FALSE)), "print_output/r.ndka.formula.no_auc")
})
test_that("print works with the CI", {
skip_slow()
if (getRversion() > "3.6.0") {
suppressWarnings(RNGkind(sample.kind = "Rounding"))
}
set.seed(42) # For reproducible CI
expect_known_output(print(roc(outcome ~ ndka, aSAH, ci = TRUE)), "print_output/r.ndka.formula.ci")
})
test_that("print.smooth.roc works", {
expect_known_output(print(smooth(roc(aSAH$outcome, aSAH$ndka))), "print_output/smooth.ndka")
expect_known_output(print(smooth(roc(outcome ~ s100b, aSAH))), "print_output/smooth.s100b.formula")
expect_known_output(print(smooth(roc(aSAH$outcome, aSAH$ndka))), "print_output/smooth.wfns")
expect_known_output(print(smooth(roc(aSAH$outcome, aSAH$ndka), method = "binormal")), "print_output/smooth.s100b.binormal")
expect_known_output(print(smooth(roc(outcome ~ s100b, aSAH), method = "fitdistr")), "print_output/smooth.s100b.fitdistr")
expect_known_output(print(smooth(roc(outcome ~ s100b, aSAH), method = "density")), "print_output/smooth.s100b.density")
testthat::skip_if_not_installed("logcondens")
expect_known_output(print(smooth(roc(outcome ~ s100b, aSAH), method = "logcondens")), "print_output/smooth.s100b.logcondens")
expect_known_output(print(smooth(roc(outcome ~ s100b, aSAH), method = "logcondens.smooth")), "print_output/smooth.s100b.logcondens.smooth")
})
test_that("print works with ci.auc", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
expect_known_output(print(ci.auc(r.ndka, method = "bootstrap", boot.n = 3)), "print_output/r.ndka.ci.auc")
})
test_that("print works with ci.coords", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
expect_known_output(print(ci.coords(r.ndka, x = c(0.5, 0.2), boot.n = 3)), "print_output/r.ndka.ci.coords")
})
test_that("print works with ci.thresholds", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
expect_known_output(print(ci.thresholds(r.ndka, thresholds = c(0.5, 0.2), boot.n = 3)), "print_output/r.ndka.ci.thresholds")
})
test_that("print works with ci.se", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
expect_known_output(print(ci.se(r.ndka, boot.n = 3)), "print_output/r.ndka.ci.se")
})
test_that("print works with ci.sp", {
skip_slow()
skip_if(getRversion() < "3.6.0") # added sample.kind
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
expect_known_output(print(ci.sp(r.ndka, boot.n = 3)), "print_output/r.ndka.ci.sp")
})
test_that("print works with a formula passed as variable", {
x <- outcome ~ ndka
expect_known_output(print(roc(x, aSAH)), "print_output/ndka_formula_var")
})
test_that("print works with a formula with data attached", {
attach(aSAH)
x <- outcome ~ ndka
expect_known_output(print(roc(x)), "print_output/ndka_formula_var_attached")
expect_known_output(print(roc(outcome ~ ndka)), "print_output/ndka_formula_attached")
detach(aSAH)
})
test_that("print works with a formula with data attached with 'with'", {
x <- outcome ~ ndka
expect_known_output(with(aSAH, print(roc(x))), "print_output/ndka_formula_var_attached")
expect_known_output(with(aSAH, print(roc(outcome ~ ndka))), "print_output/ndka_formula_attached")
})
pROC/tests/testthat/test-ci.auc.R 0000644 0001762 0000144 00000005230 15040443562 016324 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.auc")
expected.ci.auc <- c(0.501244999271703, 0.611957994579946, 0.722670989888189)
test_that("ci.auc with delong works", {
test.ci <- ci.auc(r.ndka)
expect_is(test.ci, "ci.auc")
expect_equal(as.numeric(test.ci), expected.ci.auc)
})
test_that("ci.auc with delong and percent works", {
expect_equal(as.numeric(ci.auc(r.ndka.percent)), expected.ci.auc * 100)
})
test_that("ci.auc works with an auc", {
expect_equal(as.numeric(ci.auc(auc(r.ndka))), expected.ci.auc)
})
test_that("ci.auc works with a formula", {
expect_equal(as.numeric(ci.auc(outcome ~ ndka, data = aSAH)), expected.ci.auc)
expect_equal(
as.numeric(ci.auc(outcome ~ ndka, data = aSAH, subset = (gender == "Female"))),
c(0.5261398281, 0.6671428571, 0.8081458862)
)
})
test_that("ci.auc works with a response, predictor", {
expect_equal(as.numeric(ci.auc(aSAH$outcome, aSAH$ndka)), expected.ci.auc)
})
test_that("ci.auc works with a direction = >", {
expect_equal(as.numeric(ci.auc(aSAH$outcome, -aSAH$ndka)), expected.ci.auc)
})
test_that("ci.auc works with a direction = > and percent", {
expect_equal(as.numeric(ci.auc(aSAH$outcome, -aSAH$ndka, percent = TRUE)), expected.ci.auc * 100)
})
test_that("ci.auc.auc works with a partial AUC from a roc with full AUC", {
ci.s100b <- ci.auc(r.s100b)
expect_equal(attr(ci.s100b, "method"), "delong")
pauc.s100b <- auc(r.s100b, partial.auc = c(1, .9), partial.auc.focus = "se", partial.auc.correct = TRUE)
ci.pauc.s100b <- ci.auc(pauc.s100b, boot.n = 10)
expect_equal(attr(ci.pauc.s100b, "method"), "bootstrap")
expect_equal(attr(attr(ci.pauc.s100b, "auc"), "partial.auc"), c(1, .9))
expect_equal(attr(attr(ci.pauc.s100b, "auc"), "partial.auc.focus"), "sensitivity")
expect_equal(attr(attr(ci.pauc.s100b, "auc"), "partial.auc.correct"), TRUE)
})
# Only test whether ci.auc runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
for (stratified in c(TRUE, FALSE)) {
for (test.roc in list(r.s100b, smooth(r.s100b), auc(r.s100b), r.s100b.partial1, r.s100b.partial2$auc)) {
test_that("ci.auc with bootstrap works", {
n <- round(runif(1, 3, 9)) # keep boot.n small
test.ci <- ci.auc(test.roc, method = "bootstrap", boot.n = n, conf.level = .91, boot.stratified = stratified)
expect_is(test.ci, "ci.auc")
expect_equal(attr(test.ci, "conf.level"), .91)
expect_equal(attr(test.ci, "boot.n"), n)
expect_equal(attr(test.ci, "names"), c("4.5%", "50%", "95.5%"))
expect_equal(attr(test.ci, "boot.stratified"), stratified)
expect_equal(attr(test.ci, "method"), "bootstrap")
})
}
}
pROC/tests/testthat/test-onload.R 0000644 0001762 0000144 00000002065 15040443562 016441 0 ustar ligges users library(pROC)
context("onLoad")
test_that(".parseRcppVersion works", {
expect_equal(pROC:::.parseRcppVersion("65538"), "1.0.2")
expect_equal(pROC:::.parseRcppVersion("1"), "0.0.1")
})
test_that("We're running the right Rcpp version", {
skip_if_not(exists("run_slow_tests") && run_slow_tests, message = "Skipping error-prone Rcpp version check")
skip_if(Rcpp:::getRcppVersion() == "1.0.3", "RCPP_VERSION broken in 1.0.3")
# This check will often fail, RCPP_VERSION is regularly out of sync,
# for instance Rcpp 1.0.4.6 has RCPP_VERSION 1.0.4. We can't expect
# it to be silent, however we still want it to execute without error
# expect_silent(pROC:::.checkRcppVersion())
pROC:::.checkRcppVersion()
# Replace the actual RcppVersion with a dummy function that returns 1
# (= 0.0.1) so we actually see a warning
saved.RcppVersion <- pROC:::RcppVersion
assignInNamespace("RcppVersion", function() {
return("1")
}, "pROC")
expect_warning(pROC:::.checkRcppVersion())
# Restore
assignInNamespace("RcppVersion", saved.RcppVersion, "pROC")
})
pROC/tests/testthat/test-plot.R 0000644 0001762 0000144 00000015037 15040443562 016146 0 ustar ligges users context("plot")
# Tests powered by vdiffr.
# To update the reference with vdiffr:
# > library(vdiffr)
# > source("tests/testthat.R")
# > manage_cases()
test_that("plot draws correctly", {
skip_if(getRversion() < "4.1")
test_basic_plot <- function() plot(r)
# S100b
r <- r.s100b
expect_doppelganger("basic-s100b", test_basic_plot)
r <- r.ndka
expect_doppelganger("basic-ndka", test_basic_plot)
r <- r.wfns
expect_doppelganger("basic-wfns", test_basic_plot)
})
test_that("legacy.axis works correctly", {
skip_if(getRversion() < "4.1")
r <- r.s100b
test_legacy.axis_plot <- function() plot(r, legacy.axes = TRUE)
expect_doppelganger("legacy.axes", test_legacy.axis_plot)
})
test_that("Advanced screenshot 1 works correctly", {
skip_if(getRversion() < "4.1")
test_advanced_screenshot_1 <- function() {
plot(r.s100b.percent,
reuse.auc = FALSE, partial.auc = c(100, 90), partial.auc.correct = TRUE, # define a partial AUC (pAUC)
print.auc = TRUE, # display pAUC value on the plot with following options:
print.auc.pattern = "Corrected pAUC (100-90%% SP):\n%.1f%%", print.auc.col = "#1c61b6",
auc.polygon = TRUE, auc.polygon.col = "#1c61b6", # show pAUC as a polygon
max.auc.polygon = TRUE, max.auc.polygon.col = "#1c61b622", # also show the 100% polygon
main = "Partial AUC (pAUC)"
)
plot(r.s100b.percent,
reuse.auc = FALSE, partial.auc = c(100, 90), partial.auc.correct = TRUE,
partial.auc.focus = "se", # focus pAUC on the sensitivity
add = TRUE, type = "n", # add to plot, but don't re-add the ROC itself (useless)
print.auc = TRUE, print.auc.pattern = "Corrected pAUC (100-90%% SE):\n%.1f%%", print.auc.col = "#008600",
print.auc.y = 40, # do not print auc over the previous one
auc.polygon = TRUE, auc.polygon.col = "#008600",
max.auc.polygon = TRUE, max.auc.polygon.col = "#00860022"
)
}
expect_doppelganger("advanced.screenshot.1", test_advanced_screenshot_1)
})
test_that("Advanced screenshot 2 works correctly", {
skip_slow()
skip_if(getRversion() < "4.1")
test_advanced_screenshot_2 <- function() {
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
suppressMessages(rocobj <- plot.roc(aSAH$outcome, aSAH$s100b,
main = "Confidence intervals", percent = TRUE,
ci = TRUE, # compute AUC (of AUC by default)
print.auc = TRUE
)) # print the AUC (will contain the CI)
ciobj <- ci.se(rocobj, # CI of sensitivity
specificities = seq(0, 100, 5)
) # over a select set of specificities
plot(ciobj, type = "shape", col = "#1c61b6AA") # plot as a blue shape
plot(ci(rocobj, of = "thresholds", thresholds = "best")) # add one threshold
}
expect_doppelganger("advanced.screenshot.2", test_advanced_screenshot_2)
})
test_that("Advanced screenshot 3 works correctly", {
skip_if(getRversion() < "4.4.0")
test_advanced_screenshot_3 <- function() {
plot(r.s100b.percent, main = "Smoothing")
lines(smooth(r.s100b.percent), # smoothing (default: binormal)
col = "#1c61b6"
)
lines(smooth(r.s100b.percent, method = "density"), # density smoothing
col = "#008600"
)
lines(
smooth(r.s100b.percent,
method = "fitdistr", # fit a distribution
density = "lognormal"
), # let the distribution be log-normal
col = "#840000"
)
legend("bottomright", legend = c("Empirical", "Binormal", "Density", "Fitdistr\n(Log-normal)"), col = c("black", "#1c61b6", "#008600", "#840000"), lwd = 2)
}
expect_doppelganger("advanced.screenshot.3", test_advanced_screenshot_3)
})
test_that("Advanced screenshot 4 works correctly", {
skip_slow()
skip_if(getRversion() < "4.1")
test_advanced_screenshot_4 <- function() {
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
suppressMessages(rocobj <- plot.roc(aSAH$outcome, aSAH$s100b,
main = "Confidence intervals of specificity/sensitivity", percent = TRUE,
ci = TRUE, of = "se", # ci of sensitivity
specificities = seq(0, 100, 5), # on a select set of specificities
ci.type = "shape", ci.col = "#1c61b6AA" # plot the CI as a blue shape
))
plot(ci.sp(rocobj, sensitivities = seq(0, 100, 5)), # ci of specificity
type = "bars"
) # print this one as bars
}
expect_doppelganger("advanced.screenshot.4", test_advanced_screenshot_4)
})
test_that("Advanced screenshot 5 works correctly", {
skip_slow()
skip_if(getRversion() < "4.1")
test_advanced_screenshot_5 <- function() {
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
suppressMessages(plot.roc(aSAH$outcome, aSAH$s100b,
main = "Confidence interval of a threshold", percent = TRUE,
ci = TRUE, of = "thresholds", # compute AUC (of threshold)
thresholds = "best", # select the (best) threshold
print.thres = "best" # also highlight this threshold on the plot
))
}
expect_doppelganger("advanced.screenshot.5", test_advanced_screenshot_5)
})
test_that("Advanced screenshot 6 works correctly", {
skip_if(getRversion() < "4.1")
test_advanced_screenshot_6 <- function() {
plot(r.s100b.percent, main = "Statistical comparison", col = "#1c61b6")
lines(r.ndka.percent, col = "#008600")
testobj <- roc.test(r.s100b.percent, r.ndka.percent)
text(50, 50, labels = paste("p-value =", format.pval(testobj$p.value)), adj = c(0, .5))
legend("bottomright", legend = c("S100B", "NDKA"), col = c("#1c61b6", "#008600"), lwd = 2)
}
expect_doppelganger("advanced.screenshot.6", test_advanced_screenshot_6)
})
test_that("plot and lines work with formula and subset", {
skip_if(getRversion() < "4.1")
test_plot_formula <- function() {
suppressMessages(plot.roc(outcome ~ ndka, data = aSAH, subset = gender == "Female", col = "red"))
suppressMessages(lines.roc(outcome ~ ndka, data = aSAH))
suppressMessages(lines.roc(outcome ~ ndka, data = aSAH, subset = gender == "Male", col = "blue"))
}
expect_doppelganger("plot_formula", test_plot_formula)
})
test_that("PR curve with CI works", {
skip_slow()
skip_if(getRversion() < "4.1")
test_plot_pr <- function() {
RNGkind(sample.kind = "Rejection")
set.seed(42) # For reproducible CI
co <- coords(r.s100b, x = "all", input = "recall", ret = c("recall", "precision"))
ci <- ci.coords(r.s100b, x = seq(0, 1, .1), input = "recall", ret = "precision")
plot(co, type = "l", ylim = c(0, 1))
testthat::expect_warning(plot(ci, type = "shape"), "Low definition shape")
plot(ci, type = "bars")
lines(co)
}
expect_doppelganger("plot_pr", test_plot_pr)
})
pROC/tests/testthat/test-geom_polygon_auc.R 0000644 0001762 0000144 00000002214 15040443562 020507 0 ustar ligges users context("geom_polygon_auc")
test_that("geom_polygon_auc works", {
test_geom_polygon_auc_screenshot <- function() {
print(ggroc(r.s100b) + geom_polygon_auc(r.s100b$auc))
}
expect_ggroc_doppelganger("geom_polygon_auc.screenshot", test_geom_polygon_auc_screenshot)
})
test_that("geom_polygon_auc works with percent and legacy.axes = TRUE", {
test_geom_polygon_auc_percent_legacy_screenshot <- function() {
print(ggroc(r.s100b.percent, legacy.axes = TRUE) + geom_polygon_auc(r.s100b.percent$auc, legacy.axes = TRUE))
}
expect_ggroc_doppelganger("geom_polygon_auc.percent.legacy.screenshot", test_geom_polygon_auc_percent_legacy_screenshot)
})
test_that("geom_polygon_auc works with percent and legacy.axes = TRUE", {
test_geom_polygon_auc_partial_screenshot <- function() {
auc_sp <- auc(r.s100b, partial.auc = c(0.8, 0.9), partial.auc.focus = "sp")
auc_se <- auc(r.s100b, partial.auc = c(0.8, 0.9), partial.auc.focus = "se")
print(ggroc(r.s100b) +
geom_polygon_auc(auc_se) +
geom_polygon_auc(auc_sp))
}
expect_ggroc_doppelganger("geom_polygon_auc.partial.screenshot", test_geom_polygon_auc_partial_screenshot)
})
pROC/tests/testthat/helper-coords-expected.R 0000644 0001762 0000144 00000073253 15040443562 020564 0 ustar ligges users # expected.coords <- coords(r.s100b, "all", ret="all")
# dump("expected.coords", "", control = c("all", "hexNumeric"))
expected.coords <-
structure(list(
threshold = c(
-Inf, 0x1.1eb851eb851ecp-5, 0x1.70a3d70a3d70ap-5,
0x1.c28f5c28f5c29p-5, 0x1.0a3d70a3d70a4p-4, 0x1.3333333333334p-4,
0x1.5c28f5c28f5c2p-4, 0x1.851eb851eb852p-4, 0x1.ae147ae147ae2p-4,
0x1.d70a3d70a3d7p-4, 0x1p-3, 0x1.147ae147ae148p-3, 0x1.28f5c28f5c29p-3,
0x1.3d70a3d70a3d7p-3, 0x1.51eb851eb851fp-3, 0x1.6666666666666p-3,
0x1.7ae147ae147aep-3, 0x1.a3d70a3d70a3ep-3, 0x1.ccccccccccccdp-3,
0x1.e147ae147ae14p-3, 0x1.f5c28f5c28f5cp-3, 0x1.051eb851eb852p-2,
0x1.0f5c28f5c28f6p-2, 0x1.199999999999ap-2, 0x1.28f5c28f5c29p-2,
0x1.3d70a3d70a3d7p-2, 0x1.4cccccccccccdp-2, 0x1.570a3d70a3d71p-2,
0x1.6147ae147ae14p-2, 0x1.75c28f5c28f5cp-2, 0x1.947ae147ae148p-2,
0x1.ae147ae147ae1p-2, 0x1.bd70a3d70a3d7p-2, 0x1.c7ae147ae147bp-2,
0x1.d1eb851eb851fp-2, 0x1.dc28f5c28f5c2p-2, 0x1.e666666666666p-2,
0x1.f0a3d70a3d70ap-2, 0x1.fae147ae147aep-2, 0x1.051eb851eb852p-1,
0x1.147ae147ae148p-1, 0x1.23d70a3d70a3ep-1, 0x1.47ae147ae147ap-1,
0x1.68f5c28f5c28fp-1, 0x1.7333333333333p-1, 0x1.828f5c28f5c29p-1,
0x1.970a3d70a3d7p-1, 0x1.ae147ae147ae1p-1, 0x1.d1eb851eb851ep-1,
0x1.83d70a3d70a3dp+0, Inf
), specificity = c(
0x0p+0, 0x0p+0, 0x1.1c71c71c71c72p-4,
0x1.c71c71c71c71cp-4, 0x1.1c71c71c71c72p-3, 0x1.c71c71c71c71cp-3,
0x1.38e38e38e38e4p-2, 0x1.8e38e38e38e39p-2, 0x1.f1c71c71c71c7p-2,
0x1.1555555555555p-1, 0x1.1555555555555p-1, 0x1.2aaaaaaaaaaabp-1,
0x1.471c71c71c71cp-1, 0x1.638e38e38e38ep-1, 0x1.78e38e38e38e4p-1,
0x1.871c71c71c71cp-1, 0x1.8e38e38e38e39p-1, 0x1.9c71c71c71c72p-1,
0x1.9c71c71c71c72p-1, 0x1.9c71c71c71c72p-1, 0x1.a38e38e38e38ep-1,
0x1.a38e38e38e38ep-1, 0x1.a38e38e38e38ep-1, 0x1.a38e38e38e38ep-1,
0x1.aaaaaaaaaaaabp-1, 0x1.aaaaaaaaaaaabp-1, 0x1.b1c71c71c71c7p-1,
0x1.b8e38e38e38e4p-1, 0x1.cp-1, 0x1.cp-1, 0x1.c71c71c71c71cp-1,
0x1.c71c71c71c71cp-1, 0x1.ce38e38e38e39p-1, 0x1.ce38e38e38e39p-1,
0x1.d555555555555p-1, 0x1.dc71c71c71c72p-1, 0x1.eaaaaaaaaaaabp-1,
0x1.f1c71c71c71c7p-1, 0x1.f1c71c71c71c7p-1, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0
), sensitivity = c(
0x1p+0, 0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1,
0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1, 0x1.ce0c7ce0c7ce1p-1,
0x1.c18f9c18f9c19p-1, 0x1.a895da895da89p-1, 0x1.8f9c18f9c18fap-1,
0x1.831f3831f3832p-1, 0x1.76a2576a2576ap-1, 0x1.5da895da895dbp-1,
0x1.512bb512bb513p-1, 0x1.512bb512bb513p-1, 0x1.44aed44aed44bp-1,
0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1,
0x1.3831f3831f383p-1, 0x1.2bb512bb512bbp-1, 0x1.2bb512bb512bbp-1,
0x1.1f3831f3831f4p-1, 0x1.12bb512bb512cp-1, 0x1.063e7063e7064p-1,
0x1.063e7063e7064p-1, 0x1.f3831f3831f38p-2, 0x1.da895da895da9p-2,
0x1.c18f9c18f9c19p-2, 0x1.c18f9c18f9c19p-2, 0x1.a895da895da89p-2,
0x1.a895da895da89p-2, 0x1.8f9c18f9c18fap-2, 0x1.8f9c18f9c18fap-2,
0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2,
0x1.5da895da895dbp-2, 0x1.44aed44aed44bp-2, 0x1.2bb512bb512bbp-2,
0x1.2bb512bb512bbp-2, 0x1.12bb512bb512cp-2, 0x1.f3831f3831f38p-3,
0x1.c18f9c18f9c19p-3, 0x1.8f9c18f9c18fap-3, 0x1.2bb512bb512bbp-3,
0x1.f3831f3831f38p-4, 0x1.8f9c18f9c18fap-4, 0x1.2bb512bb512bbp-4,
0x1.8f9c18f9c18fap-5, 0x1.8f9c18f9c18fap-6, 0x0p+0
), accuracy = c(
0x1.738a31d738a32p-2,
0x1.6a7a5616a7a56p-2, 0x1.97c9a0d97c9a1p-2, 0x1.b2f9341b2f934p-2,
0x1.c518eb9c518ecp-2, 0x1.e0487ede0487fp-2, 0x1.06cbe4d06cbe5p-1,
0x1.18eb9c518eb9cp-1, 0x1.2f9341b2f9342p-1, 0x1.3d2b0b53d2b0bp-1,
0x1.38a31d738a31dp-1, 0x1.3d2b0b53d2b0bp-1, 0x1.4ac2d4f4ac2d5p-1,
0x1.5ce28c75ce28cp-1, 0x1.65f268365f268p-1, 0x1.6f0243f6f0244p-1,
0x1.738a31d738a32p-1, 0x1.7c9a0d97c9a0ep-1, 0x1.78121fb78122p-1,
0x1.738a31d738a32p-1, 0x1.78121fb78122p-1, 0x1.738a31d738a32p-1,
0x1.6f0243f6f0244p-1, 0x1.6a7a5616a7a56p-1, 0x1.6f0243f6f0244p-1,
0x1.6a7a5616a7a56p-1, 0x1.6a7a5616a7a56p-1, 0x1.6a7a5616a7a56p-1,
0x1.6f0243f6f0244p-1, 0x1.6a7a5616a7a56p-1, 0x1.6f0243f6f0244p-1,
0x1.6a7a5616a7a56p-1, 0x1.6f0243f6f0244p-1, 0x1.65f268365f268p-1,
0x1.6a7a5616a7a56p-1, 0x1.6f0243f6f0244p-1, 0x1.78121fb78122p-1,
0x1.78121fb78122p-1, 0x1.738a31d738a32p-1, 0x1.7c9a0d97c9a0ep-1,
0x1.78121fb78122p-1, 0x1.738a31d738a32p-1, 0x1.6f0243f6f0244p-1,
0x1.6a7a5616a7a56p-1, 0x1.616a7a5616a7ap-1, 0x1.5ce28c75ce28cp-1,
0x1.585a9e9585a9fp-1, 0x1.53d2b0b53d2b1p-1, 0x1.4f4ac2d4f4ac3p-1,
0x1.4ac2d4f4ac2d5p-1, 0x1.463ae71463ae7p-1
), tn = c(
0x0p+0, 0x0p+0,
0x1.4p+2, 0x1p+3, 0x1.4p+3, 0x1p+4, 0x1.6p+4, 0x1.cp+4, 0x1.18p+5,
0x1.38p+5, 0x1.38p+5, 0x1.5p+5, 0x1.7p+5, 0x1.9p+5, 0x1.a8p+5,
0x1.b8p+5, 0x1.cp+5, 0x1.dp+5, 0x1.dp+5, 0x1.dp+5, 0x1.d8p+5,
0x1.d8p+5, 0x1.d8p+5, 0x1.d8p+5, 0x1.ep+5, 0x1.ep+5, 0x1.e8p+5,
0x1.fp+5, 0x1.f8p+5, 0x1.f8p+5, 0x1p+6, 0x1p+6, 0x1.04p+6, 0x1.04p+6,
0x1.08p+6, 0x1.0cp+6, 0x1.14p+6, 0x1.18p+6, 0x1.18p+6, 0x1.2p+6,
0x1.2p+6, 0x1.2p+6, 0x1.2p+6, 0x1.2p+6, 0x1.2p+6, 0x1.2p+6, 0x1.2p+6,
0x1.2p+6, 0x1.2p+6, 0x1.2p+6, 0x1.2p+6
), tp = c(
0x1.48p+5, 0x1.4p+5,
0x1.4p+5, 0x1.4p+5, 0x1.4p+5, 0x1.28p+5, 0x1.2p+5, 0x1.1p+5,
0x1p+5, 0x1.fp+4, 0x1.ep+4, 0x1.c000000000001p+4, 0x1.bp+4, 0x1.bp+4,
0x1.ap+4, 0x1.ap+4, 0x1.ap+4, 0x1.ap+4, 0x1.9p+4, 0x1.8p+4, 0x1.8p+4,
0x1.7000000000001p+4, 0x1.6p+4, 0x1.5p+4, 0x1.5p+4, 0x1.4p+4,
0x1.3p+4, 0x1.2p+4, 0x1.2p+4, 0x1.1p+4, 0x1.1p+4, 0x1p+4, 0x1p+4,
0x1.c000000000001p+3, 0x1.c000000000001p+3, 0x1.c000000000001p+3,
0x1.c000000000001p+3, 0x1.ap+3, 0x1.8p+3, 0x1.8p+3, 0x1.6p+3,
0x1.4p+3, 0x1.2p+3, 0x1p+3, 0x1.8p+2, 0x1.4p+2, 0x1p+2, 0x1.8p+1,
0x1p+1, 0x1p+0, 0x0p+0
), fn = c(
0x0p+0, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0, 0x1p+2, 0x1.4p+2, 0x1.cp+2, 0x1.2p+3, 0x1.4p+3, 0x1.6p+3,
0x1.9fffffffffffep+3, 0x1.cp+3, 0x1.cp+3, 0x1.ep+3, 0x1.ep+3,
0x1.ep+3, 0x1.ep+3, 0x1p+4, 0x1.1p+4, 0x1.1p+4, 0x1.1ffffffffffffp+4,
0x1.3p+4, 0x1.4p+4, 0x1.4p+4, 0x1.5p+4, 0x1.6p+4, 0x1.7p+4, 0x1.7p+4,
0x1.8p+4, 0x1.8p+4, 0x1.9p+4, 0x1.9p+4, 0x1.bp+4, 0x1.bp+4, 0x1.bp+4,
0x1.bp+4, 0x1.cp+4, 0x1.dp+4, 0x1.dp+4, 0x1.ep+4, 0x1.fp+4, 0x1p+5,
0x1.08p+5, 0x1.18p+5, 0x1.2p+5, 0x1.28p+5, 0x1.3p+5, 0x1.38p+5,
0x1.4p+5, 0x1.48p+5
), fp = c(
0x1.2p+6, 0x1.2p+6, 0x1.0cp+6, 0x1p+6,
0x1.fp+5, 0x1.cp+5, 0x1.9p+5, 0x1.6p+5, 0x1.28p+5, 0x1.08p+5,
0x1.08p+5, 0x1.ep+4, 0x1.ap+4, 0x1.6p+4, 0x1.3p+4, 0x1.1p+4,
0x1p+4, 0x1.cp+3, 0x1.cp+3, 0x1.cp+3, 0x1.ap+3, 0x1.ap+3, 0x1.ap+3,
0x1.ap+3, 0x1.8p+3, 0x1.8p+3, 0x1.6p+3, 0x1.4p+3, 0x1.2p+3, 0x1.2p+3,
0x1p+3, 0x1p+3, 0x1.cp+2, 0x1.cp+2, 0x1.8p+2, 0x1.4p+2, 0x1.8p+1,
0x1p+1, 0x1p+1, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0
), npv = c(
NaN,
0x0p+0, 0x1.aaaaaaaaaaaabp-1, 0x1.c71c71c71c71cp-1, 0x1.d1745d1745d17p-1,
0x1.999999999999ap-1, 0x1.a12f684bda12fp-1, 0x1.999999999999ap-1,
0x1.9745d1745d174p-1, 0x1.97829cbc14e5ep-1, 0x1.8f5c28f5c28f6p-1,
0x1.86fb586fb587p-1, 0x1.8888888888889p-1, 0x1.9p-1, 0x1.8f0f0f0f0f0f1p-1,
0x1.9249249249249p-1, 0x1.93d4bb7e327a9p-1, 0x1.96cb65b2d96cbp-1,
0x1.914c1bacf914cp-1, 0x1.8bf258bf258bfp-1, 0x1.8d79435e50d79p-1,
0x1.884fcace213f3p-1, 0x1.8348348348348p-1, 0x1.7e613716aefccp-1,
0x1.8p-1, 0x1.7b425ed097b42p-1, 0x1.784a062b2e43ep-1, 0x1.7575757575757p-1,
0x1.7711dc47711dcp-1, 0x1.72c234f72c235p-1, 0x1.745d1745d1746p-1,
0x1.702e05c0b817p-1, 0x1.71c71c71c71c7p-1, 0x1.69bd37a6f4deap-1,
0x1.6b5ad6b5ad6b6p-1, 0x1.6cefa8d9df51bp-1, 0x1.7p-1, 0x1.6db6db6db6db7p-1,
0x1.6a052bf5a814bp-1, 0x1.6cfd7720f353ap-1, 0x1.6969696969697p-1,
0x1.65e7254813e23p-1, 0x1.6276276276276p-1, 0x1.5f15f15f15f16p-1,
0x1.5885fb37072d7p-1, 0x1.5555555555555p-1, 0x1.5233ab7315234p-1,
0x1.4f2094f2094f2p-1, 0x1.4c1bacf914c1cp-1, 0x1.4924924924925p-1,
0x1.463ae71463ae7p-1
), ppv = c(
0x1.738a31d738a32p-2, 0x1.6db6db6db6db7p-2,
0x1.7ecdc1cb5d4efp-2, 0x1.89d89d89d89d9p-2, 0x1.9191919191919p-2,
0x1.9765d9765d976p-2, 0x1.aca6b29aca6b3p-2, 0x1.be5be5be5be5cp-2,
0x1.dae6076b981dbp-2, 0x1.fp-2, 0x1.e79e79e79e79ep-2, 0x1.ee58469ee5848p-2,
0x1.04d4873ecade3p-1, 0x1.1a1f58d0fac68p-1, 0x1.27d27d27d27d2p-1,
0x1.3594d653594d6p-1, 0x1.3cf3cf3cf3cf4p-1, 0x1.4cccccccccccdp-1,
0x1.4834834834835p-1, 0x1.435e50d79435ep-1, 0x1.4c1bacf914c1cp-1,
0x1.471c71c71c71dp-1, 0x1.41d41d41d41d4p-1, 0x1.3c3c3c3c3c3c4p-1,
0x1.45d1745d1745dp-1, 0x1.4p-1, 0x1.4444444444444p-1, 0x1.4924924924925p-1,
0x1.5555555555555p-1, 0x1.4ec4ec4ec4ec5p-1, 0x1.5c28f5c28f5c3p-1,
0x1.5555555555555p-1, 0x1.642c8590b2164p-1, 0x1.5555555555556p-1,
0x1.6666666666667p-1, 0x1.79435e50d7944p-1, 0x1.a5a5a5a5a5a5bp-1,
0x1.bbbbbbbbbbbbcp-1, 0x1.b6db6db6db6dbp-1, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0,
NaN
), fdr = c(
0x1.463ae71463ae7p-1, 0x1.4924924924925p-1, 0x1.40991f1a51588p-1,
0x1.3b13b13b13b14p-1, 0x1.3737373737373p-1, 0x1.344d1344d1345p-1,
0x1.29aca6b29aca7p-1, 0x1.20d20d20d20d2p-1, 0x1.128cfc4a33f13p-1,
0x1.08p-1, 0x1.0c30c30c30c31p-1, 0x1.08d3dcb08d3ddp-1, 0x1.f656f1826a43ap-2,
0x1.cbc14e5e0a72fp-2, 0x1.b05b05b05b05bp-2, 0x1.94d653594d653p-2,
0x1.8618618618618p-2, 0x1.6666666666666p-2, 0x1.6f96f96f96f97p-2,
0x1.79435e50d7943p-2, 0x1.67c8a60dd67c9p-2, 0x1.71c71c71c71c7p-2,
0x1.7c57c57c57c58p-2, 0x1.8787878787878p-2, 0x1.745d1745d1746p-2,
0x1.8p-2, 0x1.7777777777777p-2, 0x1.6db6db6db6db7p-2, 0x1.5555555555555p-2,
0x1.6276276276276p-2, 0x1.47ae147ae147bp-2, 0x1.5555555555555p-2,
0x1.37a6f4de9bd38p-2, 0x1.5555555555555p-2, 0x1.3333333333333p-2,
0x1.0d79435e50d79p-2, 0x1.6969696969697p-3, 0x1.1111111111111p-3,
0x1.2492492492492p-3, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, NaN
), fpr = c(
0x1p+0,
0x1p+0, 0x1.dc71c71c71c72p-1, 0x1.c71c71c71c71cp-1, 0x1.b8e38e38e38e4p-1,
0x1.8e38e38e38e39p-1, 0x1.638e38e38e38ep-1, 0x1.38e38e38e38e4p-1,
0x1.071c71c71c71cp-1, 0x1.d555555555556p-2, 0x1.d555555555556p-2,
0x1.aaaaaaaaaaaaap-2, 0x1.71c71c71c71c8p-2, 0x1.38e38e38e38e4p-2,
0x1.0e38e38e38e38p-2, 0x1.e38e38e38e39p-3, 0x1.c71c71c71c71cp-3,
0x1.8e38e38e38e38p-3, 0x1.8e38e38e38e38p-3, 0x1.8e38e38e38e38p-3,
0x1.71c71c71c71c8p-3, 0x1.71c71c71c71c8p-3, 0x1.71c71c71c71c8p-3,
0x1.71c71c71c71c8p-3, 0x1.5555555555554p-3, 0x1.5555555555554p-3,
0x1.38e38e38e38e4p-3, 0x1.1c71c71c71c7p-3, 0x1p-3, 0x1p-3, 0x1.c71c71c71c72p-4,
0x1.c71c71c71c72p-4, 0x1.8e38e38e38e38p-4, 0x1.8e38e38e38e38p-4,
0x1.5555555555558p-4, 0x1.1c71c71c71c7p-4, 0x1.555555555555p-5,
0x1.c71c71c71c72p-6, 0x1.c71c71c71c72p-6, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0
), tpr = c(
0x1p+0, 0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1,
0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1, 0x1.ce0c7ce0c7ce1p-1,
0x1.c18f9c18f9c19p-1, 0x1.a895da895da89p-1, 0x1.8f9c18f9c18fap-1,
0x1.831f3831f3832p-1, 0x1.76a2576a2576ap-1, 0x1.5da895da895dbp-1,
0x1.512bb512bb513p-1, 0x1.512bb512bb513p-1, 0x1.44aed44aed44bp-1,
0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1,
0x1.3831f3831f383p-1, 0x1.2bb512bb512bbp-1, 0x1.2bb512bb512bbp-1,
0x1.1f3831f3831f4p-1, 0x1.12bb512bb512cp-1, 0x1.063e7063e7064p-1,
0x1.063e7063e7064p-1, 0x1.f3831f3831f38p-2, 0x1.da895da895da9p-2,
0x1.c18f9c18f9c19p-2, 0x1.c18f9c18f9c19p-2, 0x1.a895da895da89p-2,
0x1.a895da895da89p-2, 0x1.8f9c18f9c18fap-2, 0x1.8f9c18f9c18fap-2,
0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2,
0x1.5da895da895dbp-2, 0x1.44aed44aed44bp-2, 0x1.2bb512bb512bbp-2,
0x1.2bb512bb512bbp-2, 0x1.12bb512bb512cp-2, 0x1.f3831f3831f38p-3,
0x1.c18f9c18f9c19p-3, 0x1.8f9c18f9c18fap-3, 0x1.2bb512bb512bbp-3,
0x1.f3831f3831f38p-4, 0x1.8f9c18f9c18fap-4, 0x1.2bb512bb512bbp-4,
0x1.8f9c18f9c18fap-5, 0x1.8f9c18f9c18fap-6, 0x0p+0
), tnr = c(
0x0p+0,
0x0p+0, 0x1.1c71c71c71c72p-4, 0x1.c71c71c71c71cp-4, 0x1.1c71c71c71c72p-3,
0x1.c71c71c71c71cp-3, 0x1.38e38e38e38e4p-2, 0x1.8e38e38e38e39p-2,
0x1.f1c71c71c71c7p-2, 0x1.1555555555555p-1, 0x1.1555555555555p-1,
0x1.2aaaaaaaaaaabp-1, 0x1.471c71c71c71cp-1, 0x1.638e38e38e38ep-1,
0x1.78e38e38e38e4p-1, 0x1.871c71c71c71cp-1, 0x1.8e38e38e38e39p-1,
0x1.9c71c71c71c72p-1, 0x1.9c71c71c71c72p-1, 0x1.9c71c71c71c72p-1,
0x1.a38e38e38e38ep-1, 0x1.a38e38e38e38ep-1, 0x1.a38e38e38e38ep-1,
0x1.a38e38e38e38ep-1, 0x1.aaaaaaaaaaaabp-1, 0x1.aaaaaaaaaaaabp-1,
0x1.b1c71c71c71c7p-1, 0x1.b8e38e38e38e4p-1, 0x1.cp-1, 0x1.cp-1,
0x1.c71c71c71c71cp-1, 0x1.c71c71c71c71cp-1, 0x1.ce38e38e38e39p-1,
0x1.ce38e38e38e39p-1, 0x1.d555555555555p-1, 0x1.dc71c71c71c72p-1,
0x1.eaaaaaaaaaaabp-1, 0x1.f1c71c71c71c7p-1, 0x1.f1c71c71c71c7p-1,
0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0
), fnr = c(
0x0p+0, 0x1.8f9c18f9c18fap-6,
0x1.8f9c18f9c18fap-6, 0x1.8f9c18f9c18fap-6, 0x1.8f9c18f9c18fap-6,
0x1.8f9c18f9c18fap-4, 0x1.f3831f3831f38p-4, 0x1.5da895da895dbp-3,
0x1.c18f9c18f9c19p-3, 0x1.f3831f3831f38p-3, 0x1.12bb512bb512cp-2,
0x1.44aed44aed449p-2, 0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2,
0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-2,
0x1.76a2576a2576ap-2, 0x1.8f9c18f9c18fap-2, 0x1.a895da895da89p-2,
0x1.a895da895da89p-2, 0x1.c18f9c18f9c17p-2, 0x1.da895da895da9p-2,
0x1.f3831f3831f38p-2, 0x1.f3831f3831f38p-2, 0x1.063e7063e7064p-1,
0x1.12bb512bb512cp-1, 0x1.1f3831f3831f4p-1, 0x1.1f3831f3831f4p-1,
0x1.2bb512bb512bbp-1, 0x1.2bb512bb512bbp-1, 0x1.3831f3831f383p-1,
0x1.3831f3831f383p-1, 0x1.512bb512bb513p-1, 0x1.512bb512bb513p-1,
0x1.512bb512bb513p-1, 0x1.512bb512bb513p-1, 0x1.5da895da895dbp-1,
0x1.6a2576a2576a2p-1, 0x1.6a2576a2576a2p-1, 0x1.76a2576a2576ap-1,
0x1.831f3831f3832p-1, 0x1.8f9c18f9c18fap-1, 0x1.9c18f9c18f9c2p-1,
0x1.b512bb512bb51p-1, 0x1.c18f9c18f9c19p-1, 0x1.ce0c7ce0c7ce1p-1,
0x1.da895da895da9p-1, 0x1.e7063e7063e7p-1, 0x1.f3831f3831f38p-1,
0x1p+0
), `1-specificity` = c(
0x1p+0, 0x1p+0, 0x1.dc71c71c71c72p-1,
0x1.c71c71c71c71cp-1, 0x1.b8e38e38e38e4p-1, 0x1.8e38e38e38e39p-1,
0x1.638e38e38e38ep-1, 0x1.38e38e38e38e4p-1, 0x1.071c71c71c71cp-1,
0x1.d555555555556p-2, 0x1.d555555555556p-2, 0x1.aaaaaaaaaaaaap-2,
0x1.71c71c71c71c8p-2, 0x1.38e38e38e38e4p-2, 0x1.0e38e38e38e38p-2,
0x1.e38e38e38e39p-3, 0x1.c71c71c71c71cp-3, 0x1.8e38e38e38e38p-3,
0x1.8e38e38e38e38p-3, 0x1.8e38e38e38e38p-3, 0x1.71c71c71c71c8p-3,
0x1.71c71c71c71c8p-3, 0x1.71c71c71c71c8p-3, 0x1.71c71c71c71c8p-3,
0x1.5555555555554p-3, 0x1.5555555555554p-3, 0x1.38e38e38e38e4p-3,
0x1.1c71c71c71c7p-3, 0x1p-3, 0x1p-3, 0x1.c71c71c71c72p-4, 0x1.c71c71c71c72p-4,
0x1.8e38e38e38e38p-4, 0x1.8e38e38e38e38p-4, 0x1.5555555555558p-4,
0x1.1c71c71c71c7p-4, 0x1.555555555555p-5, 0x1.c71c71c71c72p-6,
0x1.c71c71c71c72p-6, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0
), `1-sensitivity` = c(
0x0p+0,
0x1.8f9c18f9c19p-6, 0x1.8f9c18f9c19p-6, 0x1.8f9c18f9c19p-6, 0x1.8f9c18f9c19p-6,
0x1.8f9c18f9c18f8p-4, 0x1.f3831f3831f38p-4, 0x1.5da895da895dcp-3,
0x1.c18f9c18f9c18p-3, 0x1.f3831f3831f38p-3, 0x1.12bb512bb512cp-2,
0x1.44aed44aed44ap-2, 0x1.5da895da895dap-2, 0x1.5da895da895dap-2,
0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-2,
0x1.76a2576a2576ap-2, 0x1.8f9c18f9c18fap-2, 0x1.a895da895da8ap-2,
0x1.a895da895da8ap-2, 0x1.c18f9c18f9c18p-2, 0x1.da895da895da8p-2,
0x1.f3831f3831f38p-2, 0x1.f3831f3831f38p-2, 0x1.063e7063e7064p-1,
0x1.12bb512bb512cp-1, 0x1.1f3831f3831f4p-1, 0x1.1f3831f3831f4p-1,
0x1.2bb512bb512bcp-1, 0x1.2bb512bb512bcp-1, 0x1.3831f3831f383p-1,
0x1.3831f3831f383p-1, 0x1.512bb512bb512p-1, 0x1.512bb512bb512p-1,
0x1.512bb512bb512p-1, 0x1.512bb512bb512p-1, 0x1.5da895da895dap-1,
0x1.6a2576a2576a2p-1, 0x1.6a2576a2576a2p-1, 0x1.76a2576a2576ap-1,
0x1.831f3831f3832p-1, 0x1.8f9c18f9c18fap-1, 0x1.9c18f9c18f9c2p-1,
0x1.b512bb512bb51p-1, 0x1.c18f9c18f9c19p-1, 0x1.ce0c7ce0c7ce1p-1,
0x1.da895da895da9p-1, 0x1.e7063e7063e7p-1, 0x1.f3831f3831f38p-1,
0x1p+0
), `1-accuracy` = c(
0x1.463ae71463ae7p-1, 0x1.4ac2d4f4ac2d5p-1,
0x1.341b2f9341b3p-1, 0x1.268365f268366p-1, 0x1.1d738a31d738ap-1,
0x1.0fdbc090fdbcp-1, 0x1.f268365f26836p-2, 0x1.ce28c75ce28c8p-2,
0x1.a0d97c9a0d97cp-2, 0x1.85a9e9585a9eap-2, 0x1.8eb9c518eb9c6p-2,
0x1.85a9e9585a9eap-2, 0x1.6a7a5616a7a56p-2, 0x1.463ae71463ae8p-2,
0x1.341b2f9341b3p-2, 0x1.21fb78121fb78p-2, 0x1.18eb9c518eb9cp-2,
0x1.06cbe4d06cbe4p-2, 0x1.0fdbc090fdbcp-2, 0x1.18eb9c518eb9cp-2,
0x1.0fdbc090fdbcp-2, 0x1.18eb9c518eb9cp-2, 0x1.21fb78121fb78p-2,
0x1.2b0b53d2b0b54p-2, 0x1.21fb78121fb78p-2, 0x1.2b0b53d2b0b54p-2,
0x1.2b0b53d2b0b54p-2, 0x1.2b0b53d2b0b54p-2, 0x1.21fb78121fb78p-2,
0x1.2b0b53d2b0b54p-2, 0x1.21fb78121fb78p-2, 0x1.2b0b53d2b0b54p-2,
0x1.21fb78121fb78p-2, 0x1.341b2f9341b3p-2, 0x1.2b0b53d2b0b54p-2,
0x1.21fb78121fb78p-2, 0x1.0fdbc090fdbcp-2, 0x1.0fdbc090fdbcp-2,
0x1.18eb9c518eb9cp-2, 0x1.06cbe4d06cbe4p-2, 0x1.0fdbc090fdbcp-2,
0x1.18eb9c518eb9cp-2, 0x1.21fb78121fb78p-2, 0x1.2b0b53d2b0b54p-2,
0x1.3d2b0b53d2b0cp-2, 0x1.463ae71463ae8p-2, 0x1.4f4ac2d4f4ac2p-2,
0x1.585a9e9585a9ep-2, 0x1.616a7a5616a7ap-2, 0x1.6a7a5616a7a56p-2,
0x1.738a31d738a32p-2
), `1-npv` = c(
NaN, 0x1p+0, 0x1.5555555555554p-3,
0x1.c71c71c71c72p-4, 0x1.745d1745d1748p-4, 0x1.9999999999998p-3,
0x1.7b425ed097b44p-3, 0x1.9999999999998p-3, 0x1.a2e8ba2e8ba3p-3,
0x1.a1f58d0fac688p-3, 0x1.c28f5c28f5c28p-3, 0x1.e4129e4129e4p-3,
0x1.ddddddddddddcp-3, 0x1.cp-3, 0x1.c3c3c3c3c3c3cp-3, 0x1.b6db6db6db6dcp-3,
0x1.b0ad12073615cp-3, 0x1.a4d269349a4d4p-3, 0x1.bacf914c1badp-3,
0x1.d0369d0369d04p-3, 0x1.ca1af286bca1cp-3, 0x1.dec0d4c77b034p-3,
0x1.f2df2df2df2ep-3, 0x1.033d91d2a2068p-2, 0x1p-2, 0x1.097b425ed097cp-2,
0x1.0f6bf3a9a3784p-2, 0x1.1515151515152p-2, 0x1.11dc47711dc48p-2,
0x1.1a7b9611a7b96p-2, 0x1.1745d1745d174p-2, 0x1.1fa3f47e8fd2p-2,
0x1.1c71c71c71c72p-2, 0x1.2c8590b21642cp-2, 0x1.294a5294a5294p-2,
0x1.2620ae4c415cap-2, 0x1.2p-2, 0x1.2492492492492p-2, 0x1.2bf5a814afd6ap-2,
0x1.260511be1958cp-2, 0x1.2d2d2d2d2d2d2p-2, 0x1.3431b56fd83bap-2,
0x1.3b13b13b13b14p-2, 0x1.41d41d41d41d4p-2, 0x1.4ef40991f1a52p-2,
0x1.5555555555556p-2, 0x1.5b98a919d5b98p-2, 0x1.61bed61bed61cp-2,
0x1.67c8a60dd67c8p-2, 0x1.6db6db6db6db6p-2, 0x1.738a31d738a32p-2
), `1-ppv` = c(
0x1.463ae71463ae7p-1, 0x1.4924924924924p-1, 0x1.40991f1a51588p-1,
0x1.3b13b13b13b14p-1, 0x1.3737373737374p-1, 0x1.344d1344d1345p-1,
0x1.29aca6b29aca6p-1, 0x1.20d20d20d20d2p-1, 0x1.128cfc4a33f12p-1,
0x1.08p-1, 0x1.0c30c30c30c31p-1, 0x1.08d3dcb08d3dcp-1, 0x1.f656f1826a43ap-2,
0x1.cbc14e5e0a73p-2, 0x1.b05b05b05b05cp-2, 0x1.94d653594d654p-2,
0x1.8618618618618p-2, 0x1.6666666666666p-2, 0x1.6f96f96f96f96p-2,
0x1.79435e50d7944p-2, 0x1.67c8a60dd67c8p-2, 0x1.71c71c71c71c6p-2,
0x1.7c57c57c57c58p-2, 0x1.8787878787878p-2, 0x1.745d1745d1746p-2,
0x1.8p-2, 0x1.7777777777778p-2, 0x1.6db6db6db6db6p-2, 0x1.5555555555556p-2,
0x1.6276276276276p-2, 0x1.47ae147ae147ap-2, 0x1.5555555555556p-2,
0x1.37a6f4de9bd38p-2, 0x1.5555555555554p-2, 0x1.3333333333332p-2,
0x1.0d79435e50d78p-2, 0x1.6969696969694p-3, 0x1.111111111111p-3,
0x1.2492492492494p-3, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0,
0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, 0x0p+0, NaN
), precision = c(
0x1.738a31d738a32p-2,
0x1.6db6db6db6db7p-2, 0x1.7ecdc1cb5d4efp-2, 0x1.89d89d89d89d9p-2,
0x1.9191919191919p-2, 0x1.9765d9765d976p-2, 0x1.aca6b29aca6b3p-2,
0x1.be5be5be5be5cp-2, 0x1.dae6076b981dbp-2, 0x1.fp-2, 0x1.e79e79e79e79ep-2,
0x1.ee58469ee5848p-2, 0x1.04d4873ecade3p-1, 0x1.1a1f58d0fac68p-1,
0x1.27d27d27d27d2p-1, 0x1.3594d653594d6p-1, 0x1.3cf3cf3cf3cf4p-1,
0x1.4cccccccccccdp-1, 0x1.4834834834835p-1, 0x1.435e50d79435ep-1,
0x1.4c1bacf914c1cp-1, 0x1.471c71c71c71dp-1, 0x1.41d41d41d41d4p-1,
0x1.3c3c3c3c3c3c4p-1, 0x1.45d1745d1745dp-1, 0x1.4p-1, 0x1.4444444444444p-1,
0x1.4924924924925p-1, 0x1.5555555555555p-1, 0x1.4ec4ec4ec4ec5p-1,
0x1.5c28f5c28f5c3p-1, 0x1.5555555555555p-1, 0x1.642c8590b2164p-1,
0x1.5555555555556p-1, 0x1.6666666666667p-1, 0x1.79435e50d7944p-1,
0x1.a5a5a5a5a5a5bp-1, 0x1.bbbbbbbbbbbbcp-1, 0x1.b6db6db6db6dbp-1,
0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0, 0x1p+0,
0x1p+0, 0x1p+0, 0x1p+0, NaN
), recall = c(
0x1p+0, 0x1.f3831f3831f38p-1,
0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1,
0x1.ce0c7ce0c7ce1p-1, 0x1.c18f9c18f9c19p-1, 0x1.a895da895da89p-1,
0x1.8f9c18f9c18fap-1, 0x1.831f3831f3832p-1, 0x1.76a2576a2576ap-1,
0x1.5da895da895dbp-1, 0x1.512bb512bb513p-1, 0x1.512bb512bb513p-1,
0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1, 0x1.44aed44aed44bp-1,
0x1.44aed44aed44bp-1, 0x1.3831f3831f383p-1, 0x1.2bb512bb512bbp-1,
0x1.2bb512bb512bbp-1, 0x1.1f3831f3831f4p-1, 0x1.12bb512bb512cp-1,
0x1.063e7063e7064p-1, 0x1.063e7063e7064p-1, 0x1.f3831f3831f38p-2,
0x1.da895da895da9p-2, 0x1.c18f9c18f9c19p-2, 0x1.c18f9c18f9c19p-2,
0x1.a895da895da89p-2, 0x1.a895da895da89p-2, 0x1.8f9c18f9c18fap-2,
0x1.8f9c18f9c18fap-2, 0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2,
0x1.5da895da895dbp-2, 0x1.5da895da895dbp-2, 0x1.44aed44aed44bp-2,
0x1.2bb512bb512bbp-2, 0x1.2bb512bb512bbp-2, 0x1.12bb512bb512cp-2,
0x1.f3831f3831f38p-3, 0x1.c18f9c18f9c19p-3, 0x1.8f9c18f9c18fap-3,
0x1.2bb512bb512bbp-3, 0x1.f3831f3831f38p-4, 0x1.8f9c18f9c18fap-4,
0x1.2bb512bb512bbp-4, 0x1.8f9c18f9c18fap-5, 0x1.8f9c18f9c18fap-6,
0x0p+0
), lr_pos = c(
0x1p+0, 0x1.f3831f3831f38p-1, 0x1.0c65054fddb48p+0,
0x1.18f9c18f9c19p+0, 0x1.220a1220a122p+0, 0x1.29080722c996cp+0,
0x1.43af143af143bp+0, 0x1.5b6355b6355b5p+0, 0x1.84cf3ae52b085p+0,
0x1.a6509a6509a64p+0, 0x1.98b1198b1198ap+0, 0x1.a3971a3971a3bp+0,
0x1.d2da0e68b497cp+0, 0x1.13ddf13ddf13ep+1, 0x1.3398276f67848p+1,
0x1.57c82c131957bp+1, 0x1.6d44aed44aed5p+1, 0x1.a17310f29ec61p+1,
0x1.9164cb5f71485p+1, 0x1.815685cc43ca8p+1, 0x1.9efab77984151p+1,
0x1.8db04529c93eep+1, 0x1.7c65d2da0e68bp+1, 0x1.6b1b608a53927p+1,
0x1.895da895da898p+1, 0x1.76a2576a2576bp+1, 0x1.8441d8441d844p+1,
0x1.949ad949ad94cp+1, 0x1.c18f9c18f9c19p+1, 0x1.a895da895da89p+1,
0x1.dda895da895d6p+1, 0x1.c18f9c18f9c16p+1, 0x1.00e45932d7dc6p+2,
0x1.c18f9c18f9c1bp+1, 0x1.063e7063e7062p+2, 0x1.3ab153ab153adp+2,
0x1.063e7063e7068p+3, 0x1.6d44aed44aed2p+3, 0x1.512bb512bb51p+3,
Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, Inf, NaN
),
lr_neg = c(
NaN, Inf, 0x1.67a6167a6168p-2, 0x1.c18f9c18f9c2p-3,
0x1.67a6167a6168p-3, 0x1.c18f9c18f9c17p-2, 0x1.98b1198b1198ap-2,
0x1.c18f9c18f9c1bp-2, 0x1.ce67d3c1eaf2fp-2, 0x1.cd1692f8cba5cp-2,
0x1.fb326e7813366p-2, 0x1.164cb5f71483fp-1, 0x1.11a553e2ae495p-1,
0x1.f7821f7821f78p-2, 0x1.fcefdc2f9853dp-2, 0x1.ea6e1ea6e1ea7p-2,
0x1.e1ac273f54bd1p-2, 0x1.d11025e4df0edp-2, 0x1.f011397ca9a97p-2,
0x1.0789268a3a221p-1, 0x1.0311ac652c218p-1, 0x1.124ef2c57a054p-1,
0x1.218c3925c7e92p-1, 0x1.30c97f8615cdp-1, 0x1.2bb512bb512bbp-1,
0x1.3ab153ab153abp-1, 0x1.4446037aeee8p-1, 0x1.4d8b94d8b94d9p-1,
0x1.484039164cb6p-1, 0x1.5685cc43ca7b2p-1, 0x1.512bb512bb514p-1,
0x1.5f3831f3831f4p-1, 0x1.59d0ee3a98bc4p-1, 0x1.757b3eba2a12fp-1,
0x1.6fd296fd296fdp-1, 0x1.6a552d92381a1p-1, 0x1.5fd4906c96f07p-1,
0x1.67a6167a6167ap-1, 0x1.747e4e2352991p-1, 0x1.6a2576a2576a2p-1,
0x1.76a2576a2576ap-1, 0x1.831f3831f3832p-1, 0x1.8f9c18f9c18fap-1,
0x1.9c18f9c18f9c2p-1, 0x1.b512bb512bb51p-1, 0x1.c18f9c18f9c19p-1,
0x1.ce0c7ce0c7ce1p-1, 0x1.da895da895da9p-1, 0x1.e7063e7063e7p-1,
0x1.f3831f3831f38p-1, 0x1p+0
), youden = c(
0x1p+0, 0x1.f3831f3831f38p-1,
0x1.0b88ac0de0163p+0, 0x1.163356b88ac0ep+0, 0x1.1d4fc87fa732ap+0,
0x1.1fe9cca947754p+0, 0x1.2f00b19ab5c46p+0, 0x1.37d926283d0d3p+0,
0x1.443fd399528efp+0, 0x1.4c3a46c3a46c4p+0, 0x1.45fbd65fbd66p+0,
0x1.4429a0429a043p+0, 0x1.4c24136cebe18p+0, 0x1.5a5cf6fb24c5p+0,
0x1.5ec93141e8698p+0, 0x1.65e5a30904db4p+0, 0x1.6973dbec93142p+0,
0x1.70904db3af85ep+0, 0x1.6a51dd4fc87fap+0, 0x1.64136cebe1796p+0,
0x1.67a1a5cf6fb24p+0, 0x1.6163356b88ac1p+0, 0x1.5b24c507a1a5dp+0,
0x1.54e654a3ba9f9p+0, 0x1.58748d8748d88p+0, 0x1.52361d2361d24p+0,
0x1.4f85e5a30904ep+0, 0x1.4cd5ae22b0378p+0, 0x1.5063e7063e706p+0,
0x1.4a2576a2576a2p+0, 0x1.4db3af85e5a3p+0, 0x1.47753f21fe9ccp+0,
0x1.4b0378058cd5bp+0, 0x1.3e86973dbec93p+0, 0x1.4214d0214d021p+0,
0x1.45a30904db3bp+0, 0x1.4cbf7acbf7accp+0, 0x1.4a0f434b9edf6p+0,
0x1.43d0d2e7b7d92p+0, 0x1.4aed44aed44afp+0, 0x1.44aed44aed44bp+0,
0x1.3e7063e7063e7p+0, 0x1.3831f3831f383p+0, 0x1.31f3831f3831fp+0,
0x1.2576a2576a257p+0, 0x1.1f3831f3831f4p+0, 0x1.18f9c18f9c19p+0,
0x1.12bb512bb512cp+0, 0x1.0c7ce0c7ce0c8p+0, 0x1.063e7063e7064p+0,
0x1p+0
), closest.topleft = c(
0x1p+0, 0x1.0026fc7f508fcp+0,
0x1.bba9a08035aa9p-1, 0x1.94d908cc0fbd8p-1, 0x1.7bf57a932c2f6p-1,
0x1.3a9a08035aa96p-1, 0x1.fd0e6285bdb01p-2, 0x1.9c44c669e0a2dp-2,
0x1.3fc3061228843p-2, 0x1.1406f8b4fd12ap-2, 0x1.20d1d27b6c3eap-2,
0x1.18b9dca282bb8p-2, 0x1.f9da593c0e914p-3, 0x1.ae00464589d39p-3,
0x1.a0bd65809f12ep-3, 0x1.844b9e642d4bep-3, 0x1.77422321ce7b3p-3,
0x1.5f8dfd34c4ffep-3, 0x1.8552988ad044ep-3, 0x1.ad86fbd5e4862p-3,
0x1.a2dc512b39db8p-3, 0x1.cd807c6b5718cp-3, 0x1.fa946fa07d526p-3,
0x1.150c156556441p-2, 0x1.101be2d3f44a6p-2, 0x1.2915a46390636p-2,
0x1.3ebc3a20425c7p-2, 0x1.55ffd69b6c2f4p-2, 0x1.523f0c55e4489p-2,
0x1.6ee079d50ddbep-2, 0x1.6b84d2537950dp-2, 0x1.895e23cd27621p-2,
0x1.86679f0f8632ap-2, 0x1.c5c1edf26fcf8p-2, 0x1.c3308bf8c1fbdp-2,
0x1.c1044cc30783bp-2, 0x1.bddb36a36ca67p-2, 0x1.de5f5d22c7cdp-2,
0x1.008c1f4343eb6p-1, 0x1.0026fc7f508fcp-1, 0x1.121f5f2e72d3bp-1,
0x1.24b3b3dad756bp-1, 0x1.37e3fa847e18bp-1, 0x1.4bb0332b6719cp-1,
0x1.751c7a70ffd9p-1, 0x1.8abc890faf974p-1, 0x1.a0f889aba1948p-1,
0x1.b7d07c44d5d0dp-1, 0x1.cf4460db4c4c2p-1, 0x1.e754376f05068p-1,
0x1p+0
)
), class = "data.frame", row.names = c(NA, -51L))
r.s100b.reversed <- roc(aSAH$outcome, aSAH$s100b, direction = ">", quiet = TRUE)
# expected.coords.reverse <- coords(r.s100b.reversed, c(0.05, 0.055, 0.205, 0.52), ret="all")
# dump("expected.coords.reverse", "", control = c("all", "hexNumeric"))
expected.coords.reverse <-
structure(list(threshold = c(
0x1.999999999999ap-5, 0x1.c28f5c28f5c29p-5,
0x1.a3d70a3d70a3dp-3, 0x1.0a3d70a3d70a4p-1
), specificity = c(
0x1.c71c71c71c71cp-1,
0x1.c71c71c71c71cp-1, 0x1.8e38e38e38e39p-3, 0x0p+0
), sensitivity = c(
0x1.8f9c18f9c18fap-6,
0x1.8f9c18f9c18fap-6, 0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-1
), accuracy = c(
0x1.268365f268366p-1, 0x1.268365f268366p-1, 0x1.06cbe4d06cbe5p-2,
0x1.0fdbc090fdbc1p-2
), tn = c(0x1p+6, 0x1p+6, 0x1.cp+3, 0x0p+0), tp = c(0x1p+0, 0x1p+0, 0x1.ep+3, 0x1.ep+4), fn = c(
0x1.4p+5,
0x1.4p+5, 0x1.ap+4, 0x1.6p+3
), fp = c(
0x1p+3, 0x1p+3, 0x1.dp+5,
0x1.2p+6
), npv = c(
0x1.3b13b13b13b14p-1, 0x1.3b13b13b13b14p-1,
0x1.6666666666666p-2, 0x0p+0
), ppv = c(
0x1.c71c71c71c71cp-4,
0x1.c71c71c71c71cp-4, 0x1.a4d269349a4d2p-3, 0x1.2d2d2d2d2d2d3p-2
), fdr = c(
0x1.c71c71c71c71cp-1, 0x1.c71c71c71c71cp-1, 0x1.96cb65b2d96cbp-1,
0x1.6969696969697p-1
), fpr = c(
0x1.c71c71c71c72p-4, 0x1.c71c71c71c72p-4,
0x1.9c71c71c71c72p-1, 0x1p+0
), tpr = c(
0x1.8f9c18f9c18fap-6,
0x1.8f9c18f9c18fap-6, 0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-1
), tnr = c(
0x1.c71c71c71c71cp-1, 0x1.c71c71c71c71cp-1, 0x1.8e38e38e38e39p-3,
0x0p+0
), fnr = c(
0x1.f3831f3831f38p-1, 0x1.f3831f3831f38p-1,
0x1.44aed44aed44bp-1, 0x1.12bb512bb512cp-2
), `1-specificity` = c(
0x1.c71c71c71c72p-4,
0x1.c71c71c71c72p-4, 0x1.9c71c71c71c72p-1, 0x1p+0
), `1-sensitivity` = c(
0x1.f3831f3831f38p-1,
0x1.f3831f3831f38p-1, 0x1.44aed44aed44bp-1, 0x1.12bb512bb512cp-2
), `1-accuracy` = c(
0x1.b2f9341b2f934p-2, 0x1.b2f9341b2f934p-2,
0x1.7c9a0d97c9a0ep-1, 0x1.78121fb78122p-1
), `1-npv` = c(
0x1.89d89d89d89d8p-2,
0x1.89d89d89d89d8p-2, 0x1.4cccccccccccdp-1, 0x1p+0
), `1-ppv` = c(
0x1.c71c71c71c71cp-1,
0x1.c71c71c71c71cp-1, 0x1.96cb65b2d96ccp-1, 0x1.6969696969696p-1
), precision = c(
0x1.c71c71c71c71cp-4, 0x1.c71c71c71c71cp-4,
0x1.a4d269349a4d2p-3, 0x1.2d2d2d2d2d2d3p-2
), recall = c(
0x1.8f9c18f9c18fap-6,
0x1.8f9c18f9c18fap-6, 0x1.76a2576a2576ap-2, 0x1.76a2576a2576ap-1
), lr_pos = c(
0x1.c18f9c18f9c16p-3, 0x1.c18f9c18f9c16p-3, 0x1.d11025e4df0edp-2,
0x1.76a2576a2576ap-1
), lr_neg = c(
0x1.18f9c18f9c19p+0, 0x1.18f9c18f9c19p+0,
0x1.a17310f29ec6p+1, Inf
), youden = c(
0x1.d399528eea7e4p-1, 0x1.d399528eea7e4p-1,
0x1.1edf6498a0f43p-1, 0x1.76a2576a2576ap-1
), closest.topleft = c(
0x1.eda663ae3ac1p-1,
0x1.eda663ae3ac1p-1, 0x1.0d125b0df7abdp+0, 0x1.126d582d13f33p+0
)), class = "data.frame", row.names = c(NA, -4L))
pROC/tests/testthat/test-roc.test-venkatraman.R 0000644 0001762 0000144 00000004101 15040443562 021224 0 ustar ligges users library(pROC)
data(aSAH)
test_that("paired venkatraman works as expected", {
skip_slow()
ht <- roc.test(r.s100b, r.wfns, method = "venkatraman", boot.n = 12)
expect_venkatraman_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Venkatraman's test for two paired ROC curves")
expect_equal(unname(ht$parameter), 12)
# Test output
ht$statistic <- c(E = 42)
ht$p.value <- 0
expect_known_output(print(ht), "print_output/roc.test-venkatraman.paired")
})
test_that("unpaired venkatraman works as expected", {
skip_slow()
expect_warning(ht <- roc.test(r.s100b, r.wfns, method = "venkatraman", boot.n = 12, paired = FALSE), "paired")
expect_venkatraman_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Venkatraman's test for two unpaired ROC curves")
expect_equal(unname(ht$parameter), 12)
# Test output
ht$statistic <- c(E = 41)
ht$p.value <- 0.548347196932
expect_known_output(print(ht), "print_output/roc.test-venkatraman.unpaired")
})
test_that("non stratified venkatraman works as expected", {
skip_slow()
ht <- roc.test(r.s100b, r.wfns, method = "venkatraman", boot.n = 12, boot.stratified = FALSE)
expect_venkatraman_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Venkatraman's test for two paired ROC curves")
expect_equal(unname(ht$parameter), 12)
# Test output
ht$statistic <- c(E = 43)
ht$p.value <- 0.05
expect_known_output(print(ht), "print_output/roc.test-venkatraman.unstratified")
})
test_that("non stratified, unpaired venkatraman works as expected", {
skip_slow()
expect_warning(ht <- roc.test(r.s100b, r.wfns, method = "venkatraman", boot.n = 12, boot.stratified = FALSE, paired = FALSE), "paired")
expect_venkatraman_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Venkatraman's test for two unpaired ROC curves")
expect_equal(unname(ht$parameter), 12)
# Test output
ht$statistic <- c(E = 43)
ht$p.value <- 0.05
expect_known_output(print(ht), "print_output/roc.test-venkatraman.unpaired.unstratified")
})
pROC/tests/testthat/print_output/ 0000755 0001762 0000144 00000000000 14520415670 016637 5 ustar ligges users pROC/tests/testthat/print_output/smooth.s100b.logcondens 0000644 0001762 0000144 00000000305 13607143106 023044 0 ustar ligges users
Call:
smooth.roc(roc = roc(outcome ~ s100b, aSAH), method = "logcondens")
Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Smoothing: logcondens
Area under the curve: 0.7542
pROC/tests/testthat/print_output/mv_multiclass_partial_se 0000644 0001762 0000144 00000000430 13607143106 023641 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor, partial.auc = c(1, 0.9), partial.auc.focus = "se")
Data: multivariate predictor predictor with 3 levels of responses: X1, X2, X3.
Multi-class partial area under the curve (sensitivity 1-0.9): 0.01667
pROC/tests/testthat/print_output/r.ndka.partial1 0000644 0001762 0000144 00000000402 13607143106 021444 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$ndka, quiet = TRUE, partial.auc = c(0.9, 0.99))
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 0.99-0.9): 0.01046
pROC/tests/testthat/print_output/r.ndka.formula 0000644 0001762 0000144 00000000233 13607143106 021376 0 ustar ligges users
Call:
roc.formula(formula = outcome ~ ndka, data = aSAH)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/smooth.s100b.binormal 0000644 0001762 0000144 00000000321 13607143106 022512 0 ustar ligges users
Call:
smooth.roc(roc = roc(aSAH$outcome, aSAH$ndka), method = "binormal")
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Smoothing: binormal
Area under the curve: 0.6006
pROC/tests/testthat/print_output/roc.test-venkatraman.unpaired.unstratified 0000644 0001762 0000144 00000000317 14114130125 027123 0 ustar ligges users
Venkatraman's test for two unpaired ROC curves
data: r.s100b and r.wfns
E = 43, boot.n = 12, p-value = 0.05
alternative hypothesis: true difference in at least one ROC operating point is not equal to 0
pROC/tests/testthat/print_output/smooth.s100b.logcondens.smooth 0000644 0001762 0000144 00000000323 13607143106 024354 0 ustar ligges users
Call:
smooth.roc(roc = roc(outcome ~ s100b, aSAH), method = "logcondens.smooth")
Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Smoothing: logcondens.smooth
Area under the curve: 0.7149
pROC/tests/testthat/print_output/smooth.s100b.density 0000644 0001762 0000144 00000000333 13607143106 022371 0 ustar ligges users
Call:
smooth.roc(roc = roc(outcome ~ s100b, aSAH), method = "density")
Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Smoothing: density (bandwidth: nrd0; adjust: 1)
Area under the curve: 0.7244
pROC/tests/testthat/print_output/r.wfns 0000644 0001762 0000144 00000000302 13607143106 017767 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$wfns, quiet = TRUE)
Data: aSAH$wfns in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 0.8237
pROC/tests/testthat/print_output/r.ndka.percent 0000644 0001762 0000144 00000000325 13607143106 021373 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$ndka, percent = TRUE, quiet = TRUE)
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 61.2%
pROC/tests/testthat/print_output/r.s100b 0000644 0001762 0000144 00000000310 13607143106 017636 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$s100b, quiet = TRUE)
Data: aSAH$s100b in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 0.7314
pROC/tests/testthat/print_output/multiclass_partial_correct 0000644 0001762 0000144 00000000414 13607143106 024173 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$wfns, partial.auc = c(1, 0.9), partial.auc.correct = TRUE)
Data: aSAH$wfns with 4 levels of aSAH$gos6: 1, 3, 4, 5.
Multi-class corrected partial area under the curve (specificity 1-0.9): 0.6013
pROC/tests/testthat/print_output/r.ndka.ci.sp 0000644 0001762 0000144 00000000670 14520415670 020755 0 ustar ligges users 95% CI (3 stratified bootstrap replicates):
se sp.low sp.median sp.high
0.0 1.0000000 1.00000 1.00000
0.1 0.9042000 0.93060 0.95690
0.2 0.8764000 0.90280 0.91600
0.3 0.7608000 0.86110 0.87430
0.4 0.6417000 0.69440 0.78680
0.5 0.5750000 0.68060 0.74650
0.6 0.3840000 0.55560 0.55560
0.7 0.2785000 0.55560 0.55560
0.8 0.2125000 0.29170 0.43680
0.9 0.0013890 0.02778 0.29170
1.0 0.0006944 0.01389 0.01389
pROC/tests/testthat/print_output/r.wfns.percent 0000644 0001762 0000144 00000000326 13607143106 021434 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$wfns, percent = TRUE, quiet = TRUE)
Data: aSAH$wfns in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 82.37%
pROC/tests/testthat/print_output/r.ndka.percent.partial1 0000644 0001762 0000144 00000000415 13607143106 023107 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$ndka, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 99%-90%): 1.046%
pROC/tests/testthat/print_output/roc.test-venkatraman.unstratified 0000644 0001762 0000144 00000000315 14114130125 025313 0 ustar ligges users
Venkatraman's test for two paired ROC curves
data: r.s100b and r.wfns
E = 43, boot.n = 12, p-value = 0.05
alternative hypothesis: true difference in at least one ROC operating point is not equal to 0
pROC/tests/testthat/print_output/ndka_formula_attached 0000644 0001762 0000144 00000000216 14427235226 023063 0 ustar ligges users
Call:
roc.formula(formula = outcome ~ ndka)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/mv_multiclass_partial_correct 0000644 0001762 0000144 00000000443 13607143106 024677 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor, partial.auc = c(1, 0.9), partial.auc.correct = TRUE)
Data: multivariate predictor predictor with 3 levels of responses: X1, X2, X3.
Multi-class corrected partial area under the curve (specificity 1-0.9): 0.7533
pROC/tests/testthat/print_output/mv_multiclass.ndka.formula 0000644 0001762 0000144 00000000232 13607143106 024016 0 ustar ligges users
Call:
multiclass.roc.formula(formula = gos6 ~ ndka, data = aSAH)
Data: ndka with 4 levels of gos6: 1, 3, 4, 5.
Multi-class area under the curve: 0.6087
pROC/tests/testthat/print_output/ndka_formula_var_attached 0000644 0001762 0000144 00000000201 14427235226 023725 0 ustar ligges users
Call:
roc.formula(formula = x)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/r.s100b.percent 0000644 0001762 0000144 00000000330 13607143106 021277 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$s100b, percent = TRUE, quiet = TRUE)
Data: aSAH$s100b in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 73.14%
pROC/tests/testthat/print_output/r.ndka.formula.ci 0000644 0001762 0000144 00000000305 13607143106 021770 0 ustar ligges users
Call:
roc.formula(formula = outcome ~ ndka, data = aSAH, ci = TRUE)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
95% CI: 0.5012-0.7227 (DeLong)
pROC/tests/testthat/print_output/multiclass 0000644 0001762 0000144 00000000255 13607143106 020741 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$ndka)
Data: aSAH$ndka with 4 levels of aSAH$gos6: 1, 3, 4, 5.
Multi-class area under the curve: 0.6087
pROC/tests/testthat/print_output/multiclass_percent 0000644 0001762 0000144 00000000301 13607143106 022451 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$ndka, percent = TRUE)
Data: aSAH$ndka with 4 levels of aSAH$gos6: 1, 3, 4, 5.
Multi-class area under the curve: 60.87%
pROC/tests/testthat/print_output/r.s100b.partial2 0000644 0001762 0000144 00000000436 13607143106 021364 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$s100b, quiet = TRUE, partial.auc = c(0.9, 0.99), partial.auc.focus = "se")
Data: aSAH$s100b in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (sensitivity 0.99-0.9): 0.01376
pROC/tests/testthat/print_output/r.ndka.ci.se 0000644 0001762 0000144 00000000640 14520415670 020737 0 ustar ligges users 95% CI (3 stratified bootstrap replicates):
sp se.low se.median se.high
0.0 1.00000 1.00000 1.00000
0.1 0.83170 0.87800 0.92440
0.2 0.80730 0.85370 0.90000
0.3 0.65070 0.78050 0.89630
0.4 0.59390 0.75610 0.82560
0.5 0.54510 0.70730 0.75370
0.6 0.44510 0.56100 0.58410
0.7 0.31830 0.34150 0.55000
0.8 0.27200 0.34150 0.38780
0.9 0.19630 0.21950 0.21950
1.0 0.00122 0.02439 0.04756
pROC/tests/testthat/print_output/mv_multiclass 0000644 0001762 0000144 00000000304 13607143106 021436 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor)
Data: multivariate predictor predictor with 3 levels of responses: X1, X2, X3.
Multi-class area under the curve: 0.6668
pROC/tests/testthat/print_output/roc.test-venkatraman.paired 0000644 0001762 0000144 00000000320 14114130125 024052 0 ustar ligges users
Venkatraman's test for two paired ROC curves
data: r.s100b and r.wfns
E = 42, boot.n = 12, p-value < 2.2e-16
alternative hypothesis: true difference in at least one ROC operating point is not equal to 0
pROC/tests/testthat/print_output/r.wfns.partial1 0000644 0001762 0000144 00000000402 13607143106 021504 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$wfns, quiet = TRUE, partial.auc = c(0.9, 0.99))
Data: aSAH$wfns in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 0.99-0.9): 0.03305
pROC/tests/testthat/print_output/smooth.s100b.fitdistr 0000644 0001762 0000144 00000000301 13607143106 022535 0 ustar ligges users
Call:
smooth.roc(roc = roc(outcome ~ s100b, aSAH), method = "fitdistr")
Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Smoothing: fitdistr
Area under the curve: 0.8311
pROC/tests/testthat/print_output/r.ndka 0000644 0001762 0000144 00000000301 13607143106 017726 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$ndka, quiet = TRUE)
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/ndka_formula_var 0000644 0001762 0000144 00000000216 14427235226 022076 0 ustar ligges users
Call:
roc.formula(formula = x, data = aSAH)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/multiclass_partial 0000644 0001762 0000144 00000000350 13607143106 022451 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$ndka, partial.auc = c(1, 0.9))
Data: aSAH$ndka with 4 levels of aSAH$gos6: 1, 3, 4, 5.
Multi-class partial area under the curve (specificity 1-0.9): 0.009568
pROC/tests/testthat/print_output/r.ndka.ci.coords 0000644 0001762 0000144 00000001060 14114130125 021602 0 ustar ligges users 95% CI (3 stratified bootstrap replicates):
threshold threshold.low threshold.median threshold.high specificity.low
0.5 0.5 0.5 0.5 0.5 0
0.2 0.2 0.2 0.2 0.2 0
specificity.median specificity.high sensitivity.low sensitivity.median
0.5 0 0 1 1
0.2 0 0 1 1
sensitivity.high
0.5 1
0.2 1
pROC/tests/testthat/print_output/mv_multiclass_percent 0000644 0001762 0000144 00000000330 13607143106 023155 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor, percent = TRUE)
Data: multivariate predictor predictor with 3 levels of responses: X1, X2, X3.
Multi-class area under the curve: 66.68%
pROC/tests/testthat/print_output/r.ndka.formula.no_auc 0000644 0001762 0000144 00000000257 13607143106 022647 0 ustar ligges users
Call:
roc.formula(formula = outcome ~ ndka, data = aSAH, auc = FALSE)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve not computed.
pROC/tests/testthat/print_output/r.s100b.partial1 0000644 0001762 0000144 00000000404 13607143106 021356 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$s100b, quiet = TRUE, partial.auc = c(0.9, 0.99))
Data: aSAH$s100b in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 0.99-0.9): 0.02983
pROC/tests/testthat/print_output/multiclass_levels 0000644 0001762 0000144 00000000303 13607143106 022305 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$ndka, levels = c(3, 4, 5))
Data: aSAH$ndka with 3 levels of aSAH$gos6: 3, 4, 5.
Multi-class area under the curve: 0.6182
pROC/tests/testthat/print_output/ndka_formula 0000644 0001762 0000144 00000000233 13607143106 021217 0 ustar ligges users
Call:
roc.formula(formula = outcome ~ ndka, data = aSAH)
Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
pROC/tests/testthat/print_output/smooth.s100b.formula 0000644 0001762 0000144 00000000252 13607143106 022357 0 ustar ligges users
Call:
smooth.roc(roc = roc(outcome ~ s100b, aSAH))
Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Smoothing: binormal
Area under the curve: 0.74
pROC/tests/testthat/print_output/r.ndka.ci.auc 0000644 0001762 0000144 00000000072 14520415670 021077 0 ustar ligges users 95% CI: 0.5039-0.6362 (3 stratified bootstrap replicates)
pROC/tests/testthat/print_output/multiclass_partial_se 0000644 0001762 0000144 00000000401 13607143106 023135 0 ustar ligges users
Call:
multiclass.roc.default(response = aSAH$gos6, predictor = aSAH$ndka, partial.auc = c(1, 0.9), partial.auc.focus = "se")
Data: aSAH$ndka with 4 levels of aSAH$gos6: 1, 3, 4, 5.
Multi-class partial area under the curve (sensitivity 1-0.9): 0.02205
pROC/tests/testthat/print_output/r.ndka.ci.thresholds 0000644 0001762 0000144 00000000346 14114130125 022476 0 ustar ligges users 95% CI (3 stratified bootstrap replicates):
thresholds sp.low sp.median sp.high se.low se.median se.high
0.5 0 0 0 1 1 1
0.2 0 0 0 1 1 1
pROC/tests/testthat/print_output/mv_multiclass_partial 0000644 0001762 0000144 00000000376 13607143106 023163 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor, partial.auc = c(1, 0.9))
Data: multivariate predictor predictor with 3 levels of responses: X1, X2, X3.
Multi-class partial area under the curve (specificity 1-0.9): 0.05313
pROC/tests/testthat/print_output/mv_multiclass_levels 0000644 0001762 0000144 00000000334 13607143106 023013 0 ustar ligges users
Call:
multiclass.roc.default(response = responses, predictor = predictor, levels = c("X2", "X3"))
Data: multivariate predictor predictor with 2 levels of responses: X2, X3.
Multi-class area under the curve: 0.5003
pROC/tests/testthat/print_output/r.wfns.percent.partial1 0000644 0001762 0000144 00000000415 13607143106 023147 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$wfns, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
Data: aSAH$wfns in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 99%-90%): 3.305%
pROC/tests/testthat/print_output/r.s100b.percent.partial1 0000644 0001762 0000144 00000000417 13607143106 023021 0 ustar ligges users
Call:
roc.default(response = aSAH$outcome, predictor = aSAH$s100b, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
Data: aSAH$s100b in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Partial area under the curve (specificity 99%-90%): 2.983%
pROC/tests/testthat/print_output/smooth.wfns 0000644 0001762 0000144 00000000274 13607143106 021047 0 ustar ligges users
Call:
smooth.roc(roc = roc(aSAH$outcome, aSAH$ndka))
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Smoothing: binormal
Area under the curve: 0.6006
pROC/tests/testthat/print_output/smooth.ndka 0000644 0001762 0000144 00000000274 13607143106 021007 0 ustar ligges users
Call:
smooth.roc(roc = roc(aSAH$outcome, aSAH$ndka))
Data: aSAH$ndka in 72 controls (aSAH$outcome Good) < 41 cases (aSAH$outcome Poor).
Smoothing: binormal
Area under the curve: 0.6006
pROC/tests/testthat/print_output/roc.test-venkatraman.unpaired 0000644 0001762 0000144 00000000321 14114130125 024416 0 ustar ligges users
Venkatraman's test for two unpaired ROC curves
data: r.s100b and r.wfns
E = 41, boot.n = 12, p-value = 0.5483
alternative hypothesis: true difference in at least one ROC operating point is not equal to 0
pROC/tests/testthat/helper-expectations.R 0000644 0001762 0000144 00000002073 15040443562 020172 0 ustar ligges users # Make sure the value looks like a p value.
expect_p_value <- function(p.value) {
expect_is(p.value, "numeric")
expect_lte(p.value, 1)
expect_gte(p.value, 0)
}
# Make sure we got a htest
expect_htest <- function(ht) {
expect_is(ht, "htest")
expect_p_value(ht$p.value)
}
# Make sure we got a venkatraman test
expect_venkatraman_htest <- function(ht) {
expect_htest(ht)
expect_equal(unname(ht$null.value), 0)
expect_named(ht$null.value, "difference in at least one ROC operating point")
expect_is(ht$statistic, c("numeric", "integer")) # Can be either?
expect_named(ht$statistic, "E")
expect_is(ht$parameter, "numeric")
expect_named(ht$parameter, "boot.n")
}
# Make sure we got a boostrap test
expect_bootstrap_htest <- function(ht) {
expect_htest(ht)
expect_equal(unname(ht$null.value), 0)
expect_named(ht$null.value) # multiple values are possible
expect_is(ht$statistic, c("numeric", "integer")) # Can be either?
expect_named(ht$statistic, "D")
expect_is(ht$parameter, "numeric")
expect_named(ht$parameter, c("boot.n", "boot.stratified"))
}
pROC/tests/testthat/helper-coords-expected-smooth.R 0000644 0001762 0000144 00001046471 15040443562 022076 0 ustar ligges users # expected.coords.smooth <- coords(smooth(r.s100b), "all", ret="all")
# dump("expected.coords.smooth", "tests/testthat/helper-coords-expected-smooth.R_new")
expected.coords.smooth <-
structure(list(specificity = c(
0, 0, 0.0063876682047232314, 0.013341366018777919,
0.020344288637047729, 0.02732113845873314, 0.034245743799787939,
0.041107222765956193, 0.047900945707538618, 0.054625228227432425,
0.061279891780967564, 0.067865563419956337, 0.074383308025182004,
0.080834424386697287, 0.087220327715743048, 0.093542480197314093,
0.099802349355844602, 0.10600138304507721, 0.11214099462234858,
0.11822255447772048, 0.12424738557818887, 0.13021676156515741,
0.13613190647507245, 0.14199399548276545, 0.1478041562755458,
0.15356347080026292, 0.1592729772131363, 0.16493367192005839,
0.17054651163370038, 0.17611241539974154, 0.18163226656209791,
0.1871069146489435, 0.19253717716938082, 0.19792384131606267,
0.20326766557271275, 0.20856938122789367, 0.21382969379791569,
0.21904928436272667, 0.22422881081915638, 0.2293689090561532,
0.23447019405671857, 0.23953326093117808, 0.24455868588628693,
0.24954702713447605, 0.25449882574732063, 0.25941460645706799,
0.2642948784098238, 0.26914013587375307, 0.2739508589054207,
0.27872751397717066, 0.2834705545682315, 0.28818042172203989,
0.29285754457208779, 0.29750234083842347, 0.30211521729678009,
0.30669657022215319, 0.31124678580851739, 0.31576624056624336,
0.32025530169865346, 0.32471432745906287, 0.32914366748953627,
0.3335436631425181, 0.33791464778639035, 0.34225694709595467,
0.34657087932875213, 0.3508567555880755, 0.35511488007346226,
0.35934555031941029, 0.36354905742299998, 0.36772568626106317,
0.37187571569749256, 0.37599941878125076, 0.3800970629355962,
0.38416891013901194, 0.38821521709828732, 0.39223623541418029,
0.39623221174005474, 0.40020338793386645, 0.40415000120384365,
0.4080722842481882, 0.41197046538910875, 0.4158447687014693,
0.41969541413632294, 0.42352261763959054, 0.42732659126611522,
0.43110754328932849, 0.4348656783067289, 0.43860119734138098,
0.44231429793962007, 0.44600517426514108, 0.44967401718963984,
0.45332101438016231, 0.45694635038331693, 0.46055020670648866,
0.46413276189618752, 0.46769419161365966, 0.47123466870788455,
0.47475436328606541, 0.47825344278172693, 0.48173207202051754,
0.48519041328381807, 0.48862862637024584, 0.49204686865514258,
0.49544529514812791, 0.49882405854880113, 0.50218330930066291,
0.50552319564333004, 0.50884386366310885, 0.51214545734199801,
0.51542811860517479, 0.51869198736703026, 0.52193720157580392,
0.52516389725687518, 0.5283722085547633, 0.53156226777387894,
0.53473420541807981, 0.53788815022907199, 0.5410242292237003,
0.54414256773016723, 0.54724328942321909, 0.55032651635833862,
0.55339236900497746, 0.55644096627886341, 0.5594724255734127,
0.56248686279028282, 0.56548439236909231, 0.56846512731633736,
0.57142917923353065, 0.57437665834459195, 0.57730767352251533,
0.58022233231533227, 0.5831207409714011, 0.58600300446403886,
0.58886922651552265, 0.5917195096204747, 0.59455395506865638,
0.59737266296718716, 0.60017573226220922, 0.6029632607600105,
0.60573534514762928, 0.60849208101295216, 0.61123356286432318,
0.61395988414967695, 0.61667113727521417, 0.61936741362362813,
0.62204880357190151, 0.62471539650868135, 0.62736728085124849,
0.63000454406209039, 0.63262727266509189, 0.63523555226135353,
0.63782946754464676, 0.64040910231652048, 0.6429745395010652,
0.64552586115934718, 0.64806314850351843, 0.65058648191061674,
0.65309594093605994, 0.65559160432684582, 0.65807355003446311,
0.66054185522752418, 0.66299659630412677, 0.66543784890394875,
0.66786568792008816, 0.67028018751065133, 0.67268142111009843,
0.67506946144035096, 0.67744438052166922, 0.67980624968330317,
0.68215513957392726, 0.68449112017185976, 0.68681426079507391,
0.68912463011100922, 0.69142229614618278, 0.69370732629561083,
0.69597978733204013, 0.69823974541499945, 0.70048726609967116,
0.70272241434559035, 0.70494525452517343, 0.70715585043208273,
0.70935426528942902, 0.71154056175781777, 0.71371480194324066,
0.71587704740481883, 0.71802735916239957, 0.72016579770401024,
0.72229242299317231, 0.72440729447608088, 0.72651047108865052,
0.72860201126343216, 0.73068197293640202, 0.73275041355362858,
0.73480739007781759, 0.7368529589947399, 0.73888717631954237,
0.74091009760294801, 0.74292177793734482, 0.74492227196276706,
0.74691163387277126, 0.74888991742020916, 0.75085717592290058,
0.75281346226920753, 0.75475882892351132, 0.75669332793159638,
0.75861701092594191, 0.76052992913092365, 0.76243213336792581,
0.76432367406036927, 0.76620460123865319, 0.76807496454501567,
0.76993481323831126, 0.7717841961987123, 0.77362316193233027,
0.77545175857576254, 0.77727003390056415, 0.77907803531764674,
0.7808758098816071, 0.78266340429498582, 0.78444086491245557,
0.78620823774494497, 0.7879655684636957, 0.78971290240425507,
0.79145028457040623, 0.7931777596380355, 0.79489537195894089,
0.79660316556458, 0.79830118416975959, 0.79998947117626984, 0.80166806967646032,
0.80333702245676331, 0.80499637200116236, 0.80664616049460758,
0.8082864298263811, 0.80991722159341029, 0.81153857710353094,
0.81315053737870402, 0.81475314315818148, 0.81634643490162795,
0.81793045279219412, 0.81950523673954656, 0.82107082638285234,
0.82262726109372053, 0.82417457997910082, 0.82571282188413941,
0.82724202539499625, 0.82876222884161865, 0.83027347030047738,
0.83177578759726323, 0.83326921830954548, 0.83475379976939235,
0.8362295690659548, 0.83769656304801488, 0.83915481832649708,
0.84060437127694632, 0.84204525804197006, 0.84347751453364772,
0.84490117643590701, 0.84631627920686747, 0.84772285808115111,
0.84912094807216409, 0.8505105839743442, 0.85189180036538137,
0.85326463160840571, 0.85462911185414769, 0.85598527504306887,
0.8573331549074652, 0.85867278497354105, 0.860004198563457, 0.86132742879735058,
0.86264250859532976, 0.86394947067944194, 0.86524834757561508,
0.86653917161557648, 0.86782197493874436, 0.86909678949409641,
0.87036364704201419, 0.87162257915610353, 0.87287361722499246,
0.87411679245410556, 0.87535213586741711, 0.87657967830918038,
0.8777994504456369, 0.87901148276670371, 0.88021580558763901,
0.8814124490506885, 0.88260144312670974, 0.88378281761677768,
0.88495660215377037, 0.88612282620393445, 0.887281519068432,
0.88843270988486922, 0.8895764276288054, 0.89071270111524437,
0.89184155900010798, 0.89296302978169173, 0.89407714180210296,
0.8951839232486819, 0.89628340215540625, 0.89737560640427838,
0.89846056372669636, 0.89953830170480997, 0.90060884777285888,
0.90167222921849643, 0.9027284731840981, 0.90377760666805396,
0.90481965652604679, 0.90585464947231509, 0.90688261208090193,
0.90790357078688899, 0.90891755188761658, 0.90992458154389055,
0.9109246857811738, 0.9119178904907661, 0.9129042214309695, 0.91388370422824039,
0.91485636437832973, 0.91582222724740936, 0.91678131807318641,
0.9177336619660047, 0.9186792839099347, 0.91961820876385059,
0.92055046126249596, 0.92147606601753718, 0.92239504751860613,
0.92330743013433036, 0.92421323811335276, 0.92511249558533959,
0.92600522656197815, 0.9268914549379631, 0.9277712044919717,
0.92864449888762968, 0.92951136167446569, 0.93037181628885568,
0.93122588605495715, 0.93207359418563374, 0.93291496378336902,
0.93375001784117173, 0.9345787792434701, 0.93540127076699753,
0.93621751508166828, 0.9370275347514444, 0.93783135223519287,
0.93862898988753385, 0.93942046995968032, 0.94020581460026809,
0.94098504585617782, 0.94175818567334779, 0.94252525589757796,
0.94328627827532674, 0.94404127445449715, 0.94479026598521709,
0.94553327432060974, 0.94627032081755624, 0.94700142673745069,
0.94772661324694663, 0.948445901418696, 0.94915931223207983,
0.94986686657393182, 0.95056858523925392, 0.95126448893192372,
0.9519545982653953, 0.95263893376339193, 0.95331751586059132,
0.95399036490330402, 0.95465750115014403, 0.95531894477269186,
0.95597471585615146, 0.95662483439999868, 0.95726932031862366,
0.95790819344196521, 0.95854147351613928, 0.95916918020405906,
0.95979133308604903, 0.96040795166045212, 0.96101905534422882,
0.96162466347355136, 0.96222479530438876, 0.96281947001308654,
0.96340870669693912, 0.96399252437475536, 0.96457094198741689,
0.96514397839843047, 0.96571165239447232, 0.96627398268592701,
0.96683098790741795, 0.96738268661833171, 0.96792909730333621,
0.96847023837289026, 0.9690061281637472, 0.96953678493945172,
0.97006222689082899, 0.97058247213646642, 0.97109753872318938,
0.97160744462652837, 0.97211220775118012, 0.97261184593145977,
0.97310637693174706, 0.97359581844692411, 0.97408018810280539,
0.97455950345656051, 0.9750337819971282, 0.97550304114562336,
0.97596729825573447, 0.97642657061411386, 0.97688087544075852,
0.97733022988938301, 0.97777465104778238, 0.97821415593818695,
0.97864876151760694, 0.97907848467816783, 0.97950334224743574,
0.97992335098873262, 0.9803385276014408, 0.98074888872129673,
0.98115445092067388, 0.98155523070885353, 0.981951244532284,
0.98234250877482743, 0.98272903975799319, 0.98311085374115881,
0.98348796692177631, 0.98386039543556436, 0.98422815535668517,
0.98459126269790587, 0.98494973341074321, 0.98530358338559165,
0.98565282845183233, 0.98599748437792423, 0.98633756687147511,
0.98667309157929162, 0.98700407408740765, 0.98733052992108938,
0.98765247454481619, 0.98796992336223621, 0.98828289171609418,
0.98859139488813152, 0.9888954480989548, 0.98919506650787359,
0.98949026521270289, 0.9897810592495303, 0.99006746359244391,
0.99034949315321963, 0.99062716278096463, 0.99090048726171431,
0.99116948131797933, 0.99143415960823911, 0.99169453672637875,
0.99195062720106486, 0.99220244549505521, 0.99245000600443833,
0.99269332305779756, 0.99293241091529283, 0.99316728376765517,
0.9933979557350856, 0.99362444086605128, 0.99384675313597126,
0.99406490644578094, 0.99427891462036555, 0.9944887914068522,
0.99469455047274657, 0.99489620540390078, 0.99509376970229735,
0.99528725678363095, 0.99547667997466949, 0.99566205251037365,
0.99584338753074819, 0.99602069807740146, 0.99619399708977974,
0.9963632974010439, 0.99652861173354923, 0.99668995269388394,
0.99684733276741755, 0.99700076431230134, 0.99715025955285719,
0.99729583057227922, 0.99743748930456388, 0.99757524752556959,
0.99770911684309094, 0.99783910868581716, 0.99796523429101713,
0.99808750469077223, 0.99820593069654184, 0.99832052288181017,
0.99843129156251398, 0.998538246774892, 0.99864139825032627,
0.99874075538665208, 0.99883632721530369, 0.99892812236351425,
0.99901614901061087, 0.9991004148372028, 0.99918092696575589,
0.9992576918906384, 0.99933071539517937, 0.99940000245254867,
0.99946555710625573, 0.99952738232466198, 0.99958547982189927,
0.99963984983468901, 0.99969049084025274, 0.99973739919394899,
0.99978056865497356, 0.99981998975172415, 0.99985564891007006,
0.99988752721731322, 0.99991559859934254, 0.99993982699459871,
0.99996016167415558, 0.99997652874920029, 0.99998881349177671,
0.99999681366490334, 1, 1
), sensitivity = c(
1, 1, 0.99804305283757333,
0.99608610567514666, 0.9941291585127201, 0.99217221135029354,
0.99021526418786687, 0.9882583170254402, 0.98630136986301364,
0.98434442270058709, 0.98238747553816042, 0.98043052837573375,
0.97847358121330719, 0.97651663405088063, 0.97455968688845396,
0.97260273972602729, 0.97064579256360073, 0.96868884540117417,
0.9667318982387475, 0.96477495107632083, 0.96281800391389427,
0.96086105675146771, 0.95890410958904104, 0.95694716242661437,
0.95499021526418781, 0.95303326810176126, 0.95107632093933459,
0.94911937377690792, 0.94716242661448136, 0.9452054794520548,
0.94324853228962813, 0.94129158512720146, 0.9393346379647749,
0.93737769080234834, 0.93542074363992167, 0.93346379647749489,
0.93150684931506844, 0.92954990215264188, 0.92759295499021521,
0.92563600782778854, 0.92367906066536198, 0.92172211350293543,
0.91976516634050876, 0.91780821917808209, 0.91585127201565553,
0.91389432485322897, 0.9119373776908023, 0.90998043052837563,
0.90802348336594907, 0.90606653620352251, 0.90410958904109584,
0.90215264187866917, 0.90019569471624261, 0.89823874755381605,
0.89628180039138938, 0.89432485322896271, 0.89236790606653615,
0.8904109589041096, 0.88845401174168304, 0.88649706457925626,
0.8845401174168297, 0.88258317025440314, 0.88062622309197647,
0.8786692759295498, 0.87671232876712324, 0.87475538160469657,
0.8727984344422699, 0.87084148727984334, 0.86888454011741678,
0.86692759295499022, 0.86497064579256355, 0.86301369863013688,
0.86105675146771044, 0.85909980430528377, 0.8571428571428571,
0.85518590998043043, 0.85322896281800387, 0.85127201565557742,
0.84931506849315064, 0.84735812133072397, 0.84540117416829741,
0.84344422700587085, 0.84148727984344429, 0.83953033268101751,
0.83757338551859095, 0.83561643835616439, 0.83365949119373772,
0.83170254403131105, 0.82974559686888449, 0.82778864970645794,
0.82583170254403138, 0.8238747553816046, 0.82191780821917804,
0.81996086105675148, 0.81800391389432481, 0.81604696673189814,
0.81409001956947158, 0.81213307240704502, 0.81017612524461835,
0.80821917808219157, 0.80626223091976512, 0.80430528375733856,
0.802348336594912, 0.80039138943248522, 0.79843444227005878,
0.79647749510763211, 0.79452054794520544, 0.79256360078277877,
0.79060665362035221, 0.78864970645792565, 0.78669275929549909,
0.78473581213307231, 0.78277886497064575, 0.78082191780821919,
0.77886497064579252, 0.77690802348336585, 0.77495107632093929,
0.77299412915851273, 0.77103718199608617, 0.76908023483365939,
0.76712328767123283, 0.76516634050880639, 0.76320939334637972,
0.76125244618395294, 0.75929549902152638, 0.75733855185909993,
0.75538160469667315, 0.75342465753424648, 0.75146771037181992,
0.74951076320939336, 0.74755381604696669, 0.74559686888454002,
0.74363992172211346, 0.7416829745596869, 0.73972602739726023,
0.73776908023483356, 0.73581213307240712, 0.73385518590998045,
0.73189823874755378, 0.72994129158512711, 0.72798434442270055,
0.72602739726027399, 0.72407045009784743, 0.72211350293542065,
0.72015655577299409, 0.71819960861056753, 0.71624266144814086,
0.71428571428571419, 0.71232876712328763, 0.71037181996086107,
0.7084148727984344, 0.70645792563600773, 0.70450097847358117,
0.70254403131115462, 0.70058708414872795, 0.69863013698630128,
0.69667318982387472, 0.69471624266144816, 0.69275929549902149,
0.69080234833659482, 0.68884540117416826, 0.6868884540117417,
0.68493150684931503, 0.68297455968688836, 0.6810176125244618,
0.67906066536203524, 0.67710371819960857, 0.6751467710371819,
0.67318982387475523, 0.67123287671232879, 0.669275929549902,
0.66731898238747545, 0.66536203522504889, 0.66340508806262233,
0.66144814090019555, 0.65949119373776899, 0.65753424657534243,
0.65557729941291587, 0.6536203522504892, 0.65166340508806253,
0.64970645792563597, 0.64774951076320941, 0.64579256360078274,
0.64383561643835607, 0.64187866927592951, 0.63992172211350296,
0.63796477495107629, 0.63600782778864962, 0.63405088062622306,
0.6320939334637965, 0.63013698630136983, 0.62818003913894316,
0.6262230919765166, 0.62426614481409004, 0.62230919765166337,
0.6203522504892367, 0.61839530332681014, 0.61643835616438358,
0.61448140900195691, 0.61252446183953024, 0.61056751467710368,
0.60861056751467713, 0.60665362035225046, 0.60469667318982379,
0.60273972602739723, 0.60078277886497067, 0.598825831702544,
0.59686888454011733, 0.59491193737769077, 0.59295499021526421,
0.59099804305283754, 0.58904109589041087, 0.58708414872798431,
0.58512720156555775, 0.58317025440313108, 0.58121330724070441,
0.57925636007827785, 0.5772994129158513, 0.57534246575342463,
0.57338551859099796, 0.5714285714285714, 0.56947162426614484,
0.56751467710371817, 0.5655577299412915, 0.56360078277886494,
0.56164383561643838, 0.55968688845401171, 0.55772994129158504,
0.55577299412915848, 0.55381604696673192, 0.55185909980430525,
0.54990215264187858, 0.54794520547945202, 0.54598825831702547,
0.5440313111545988, 0.54207436399217213, 0.54011741682974557,
0.53816046966731901, 0.53620352250489234, 0.53424657534246567,
0.53228962818003911, 0.53033268101761255, 0.52837573385518588,
0.52641878669275921, 0.52446183953033265, 0.52250489236790609,
0.52054794520547942, 0.51859099804305275, 0.51663405088062619,
0.51467710371819964, 0.51272015655577297, 0.5107632093933463,
0.50880626223091974, 0.50684931506849318, 0.50489236790606651,
0.50293542074363984, 0.50097847358121328, 0.49902152641878667,
0.49706457925636005, 0.49510763209393344, 0.49315068493150682,
0.49119373776908021, 0.48923679060665359, 0.48727984344422698,
0.48532289628180036, 0.48336594911937375, 0.48140900195694714,
0.47945205479452052, 0.47749510763209391, 0.47553816046966729,
0.47358121330724068, 0.47162426614481406, 0.46966731898238745,
0.46771037181996084, 0.46575342465753422, 0.46379647749510761,
0.46183953033268099, 0.45988258317025438, 0.45792563600782776,
0.45596868884540115, 0.45401174168297453, 0.45205479452054792,
0.45009784735812131, 0.44814090019569469, 0.44618395303326808,
0.44422700587084146, 0.44227005870841485, 0.44031311154598823,
0.43835616438356162, 0.43639921722113501, 0.43444227005870839,
0.43248532289628178, 0.43052837573385516, 0.42857142857142855,
0.42661448140900193, 0.42465753424657537, 0.4227005870841487,
0.42074363992172209, 0.41878669275929548, 0.41682974559686886,
0.41487279843444225, 0.41291585127201569, 0.41095890410958907,
0.4090019569471624, 0.40704500978473579, 0.40508806262230923,
0.40313111545988256, 0.40117416829745595, 0.39921722113502939,
0.39726027397260272, 0.39530332681017616, 0.39334637964774949,
0.39138943248532287, 0.38943248532289626, 0.38747553816046965,
0.38551859099804303, 0.38356164383561642, 0.38160469667318986,
0.37964774951076319, 0.37769080234833657, 0.37573385518590996,
0.3737769080234834, 0.37181996086105673, 0.36986301369863012,
0.3679060665362035, 0.36594911937377694, 0.36399217221135027,
0.36203522504892366, 0.36007827788649704, 0.35812133072407043,
0.35616438356164382, 0.3542074363992172, 0.35225048923679059,
0.35029354207436392, 0.34833659491193741, 0.3463796477495108,
0.34442270058708419, 0.34246575342465752, 0.34050880626223096,
0.33855185909980429, 0.33659491193737767, 0.33463796477495111,
0.33268101761252444, 0.33072407045009783, 0.32876712328767127,
0.3268101761252446, 0.32485322896281799, 0.32289628180039132,
0.32093933463796476, 0.31898238747553814, 0.31702544031311153,
0.31506849315068497, 0.31311154598825836, 0.31115459882583163,
0.30919765166340507, 0.30724070450097851, 0.30528375733855184,
0.30332681017612523, 0.30136986301369861, 0.299412915851272,
0.29745596868884538, 0.29549902152641883, 0.29354207436399216,
0.2915851272015656, 0.28962818003913887, 0.28767123287671237,
0.2857142857142857, 0.28375733855185903, 0.28180039138943253,
0.27984344422700586, 0.27788649706457924, 0.27592954990215257,
0.27397260273972601, 0.27201565557729945, 0.27005870841487278,
0.26810176125244617, 0.26614481409001955, 0.264187866927593,
0.26223091976516638, 0.26027397260273977, 0.2583170254403131,
0.25636007827788648, 0.25440313111545987, 0.25244618395303331,
0.2504892367906067, 0.24853228962818005, 0.24657534246575341,
0.2446183953033268, 0.2426614481409001, 0.24070450097847362,
0.23874755381604693, 0.23679060665362034, 0.23483365949119361,
0.23287671232876717, 0.23091976516634047, 0.22896281800391383,
0.22700587084148729, 0.22504892367906071, 0.22309197651663407,
0.2211350293542074, 0.21917808219178078, 0.2172211350293542,
0.21526418786692758, 0.21330724070450094, 0.21135029354207435,
0.20939334637964774, 0.20743639921722107, 0.20547945205479451,
0.20352250489236787, 0.20156555772994122, 0.19960861056751467,
0.19765166340508805, 0.19569471624266147, 0.19373776908023482,
0.19178082191780826, 0.18982387475538162, 0.18786692759295498,
0.18590998043052842, 0.18395303326810175, 0.18199608610567519,
0.18003913894324852, 0.17808219178082194, 0.17612524461839529,
0.17416829745596865, 0.17221135029354201, 0.17025440313111548,
0.16829745596868884, 0.16634050880626222, 0.16438356164383566,
0.16242661448140899, 0.16046966731898241, 0.15851272015655576,
0.15655577299412918, 0.15459882583170251, 0.15264187866927589,
0.15068493150684936, 0.14872798434442261, 0.14677103718199611,
0.14481409001956941, 0.14285714285714282, 0.14090019569471618,
0.13894324853228959, 0.13698630136986298, 0.13502935420743636,
0.13307240704500972, 0.13111545988258316, 0.12915851272015663,
0.12720156555772999, 0.1252446183953034, 0.12328767123287671,
0.12133072407045009, 0.11937377690802352, 0.11741682974559686,
0.11545988258317025, 0.11350293542074361, 0.11154598825831699,
0.10958904109589039, 0.1076320939334638, 0.1056751467710372,
0.10371819960861053, 0.10176125244618392, 0.099804305283757389,
0.097847358121330733, 0.09589041095890416, 0.093933463796477504,
0.091976516634050862, 0.090019569471624289, 0.088062622309197675,
0.086105675146771019, 0.084148727984344446, 0.082191780821917845,
0.080234833659491259, 0.078277886497064589, 0.076320939334637947,
0.074363992172211374, 0.072407045009784773, 0.070450097847358159,
0.068493150684931517, 0.066536203522504889, 0.064579256360078302,
0.062622309197651688, 0.060665362035225066, 0.058708414872798501,
0.056751467710371865, 0.054794520547945209, 0.052837573385518657,
0.050880626223092015, 0.048923679060665401, 0.046966731898238773,
0.045009784735812165, 0.043052837573385544, 0.041095890410958923,
0.039138943248532329, 0.03718199608610568, 0.035225048923679107,
0.033268101761252479, 0.031311154598825837, 0.029354207436399233,
0.027397260273972615, 0.02544031311154599, 0.023483365949119386,
0.021526418786692772, 0.019569471624266147, 0.017612524461839554,
0.015655577299412939, 0.013698630136986308, 0.011741682974559685,
0.0097847358121330927, 0.0078277886497064766, 0.0058708414872798544,
0.0039138943248532305, 0.0019569471624266178, 0, 0
), accuracy = c(
0.36283185840707965,
0.36283185840707965, 0.36619183431044755, 0.36991246624807989,
0.37366446266273418, 0.37739984632204271, 0.3811019414627192,
0.38476381448842384, 0.38838251553386138, 0.39195697135486018,
0.39548706818844465, 0.39897320557205251, 0.40241606201379382,
0.40581646506131241, 0.4091753164421249, 0.41249354781392683,
0.41577209423653488, 0.41901187823622749, 0.42221380035927203,
0.42537873377455782, 0.42850752143450677, 0.43160097486284521,
0.43465987397660089, 0.43768496755973713, 0.4406769741386814,
0.44363658309549681, 0.44656445591025251, 0.44946122746103923,
0.45232750733469174, 0.45516388111783751, 0.45797091164907788,
0.46074914022070079, 0.46349908772346188, 0.46622125573144063,
0.46891612752630185, 0.47158416906181977, 0.47422582987051093,
0.47684154391481981, 0.47943173038564679, 0.48199679445117133,
0.48453712795896975, 0.48705311009438207, 0.48954510799799578,
0.49201347734498796, 0.49445856288892892, 0.49688069897248927,
0.49928021000734696, 0.50165741092543037, 0.50401260760348854,
0.50634609726283808, 0.50865816884599646, 0.51094910337179034,
0.51321917427040942, 0.51546864769976053, 0.51769778284438173,
0.51990683219807521, 0.5220960418313384, 0.52426565164458416,
0.52641589560807134, 0.52854700198939852, 0.53065919356935076,
0.53275268784683039, 0.53482769723354995, 0.5368844292391175,
0.5389230866470992, 0.54094386768260172, 0.54294696617187921,
0.54493257169443465, 0.54690086972805385, 0.54885204178717828,
0.55078626555499621, 0.55270371500960769, 0.55460456054459339,
0.55648896908429635, 0.55835710419410467, 0.5602091261860056,
0.56204519221966454, 0.563865456399266, 0.5656700698663355, 0.56745918088875424,
0.56923293494615945, 0.57099147481191592, 0.57273494063182706,
0.57446346999975428, 0.57617719803028788, 0.57787625742862292,
0.57956077855776744, 0.581230889503214, 0.58288671613519394,
0.58452838216862779, 0.58615600922087929, 0.58776971686741131,
0.58936962269544346, 0.59095584235569909, 0.59252848961232585,
0.59408767639107374, 0.59563351282580557, 0.59716610730341202,
0.59868556650720084, 0.60019199545882407, 0.60168549755880762,
0.60316617462573963, 0.60463412693417395, 0.6060894532513017,
0.60753225087244322, 0.60896261565540399, 0.61038064205374498,
0.61178642314900666, 0.61318005068193193, 0.61456161508272156,
0.61593120550036851, 0.61728890983109597, 0.6186348147459424,
0.61996900571752167, 0.6212915670459892, 0.62260258188424555,
0.62390213226240443, 0.62519029911155266, 0.62646716228682808,
0.62773280058983905, 0.62898729179045065, 0.6302307126479596,
0.63146313893167905, 0.63268464544095382, 0.63389530602462785,
0.63509519359998012, 0.63628438017114952, 0.63746293684706468,
0.63863093385889602, 0.63978844057704631, 0.64093552552769517,
0.64207225640891163, 0.64319870010634916, 0.64431492270853796,
0.64542098952178628, 0.64651696508470302, 0.64760291318235541,
0.64867889686007318, 0.64974497843690682, 0.6508012195187568,
0.6518476810111794, 0.65288442313188066, 0.65391150542290688,
0.65492898676254574, 0.65593692537693782, 0.65693537885141751,
0.6579244041415826, 0.65890405758410775, 0.65987439490730349,
0.66083547124143283, 0.66178734112879001, 0.66273005853354772,
0.66366367685138328, 0.66458824891888524, 0.6655038270227509,
0.66641046290877604, 0.66730820779064848, 0.66819711235854595,
0.66907722678754666, 0.66994860074585594, 0.67081128340285523,
0.67166532343697827, 0.67251076904341789, 0.67334766794167056,
0.67417606738291891, 0.6749960141572614, 0.67580755460078967,
0.67661073460251886, 0.67740559961117519, 0.67819219464184288,
0.67897056428247693, 0.67974075270028156, 0.68050280364796167,
0.68125676046984662, 0.68200266610789384, 0.68274056310757003,
0.68347049362361945, 0.68419249942571569, 0.68490662190400509,
0.68561290207454029, 0.68631138058461083, 0.68700209771796883,
0.68768509339995554, 0.68836040720253022, 0.68902807834920399,
0.68968814571987958, 0.69034064785560056, 0.69098562296321275,
0.69162310891993783, 0.6922531432778628, 0.69287576326834766,
0.69349100580635059, 0.6940989074946764, 0.69469950462814645,
0.69529283319769453, 0.69587892889438707, 0.69645782711337578,
0.69702956295777485, 0.69759417124247314, 0.69815168649787851,
0.69870214297359556, 0.69924557464204073, 0.69978201520199301,
0.70031149808208482, 0.70083405644423202, 0.7013497231870055,
0.70185853094894524, 0.70236051211181827, 0.70285569880382215,
0.7033441229027334, 0.70382581603900407, 0.70430080959880759,
0.70476913472703218, 0.70523082233022694, 0.70568590307949808,
0.70613440741335842, 0.7065763655405306, 0.70701180744270464,
0.70744076287725122, 0.70786326137989131, 0.70827933226732276,
0.70868900463980555, 0.70909230738370632, 0.70948926917400179,
0.70987991847674348, 0.71026428355148419, 0.71064239245366589,
0.71101427303697062, 0.71137995295563661, 0.71173945966673591,
0.71209282043242017, 0.7124400623221302, 0.71278121221477231,
0.71311629680086264, 0.7134453425846381, 0.71376837588613529,
0.71408542284324117, 0.71439650941370936, 0.71470166137714863,
0.71500090433698282, 0.71529426372238003, 0.71558176479015478,
0.71586343262664154, 0.71613929214954319, 0.71640936810974931,
0.71667368509313178, 0.71693226752231154, 0.71718513965840303,
0.71743232560273118, 0.71767384929852618, 0.71790973453259244,
0.71814000493695518, 0.71836468399048481, 0.71858379502049563,
0.71879736120432625, 0.71900540557089443, 0.71920795100223345,
0.71940502023500497, 0.71959663586199307, 0.71978282033357655,
0.71996359595918225, 0.72013898490871753, 0.72030900921398466,
0.72047369077007528, 0.72063305133674738, 0.72078711253978123,
0.72093589587232154, 0.72107942269619729, 0.72121771424322789,
0.72135079161650983, 0.72147867579168679, 0.72160138761820536,
0.72171894782055024, 0.7218313769994682, 0.72193869563317248,
0.72204092407853404, 0.72213808257225609, 0.72223019123203447,
0.72231727005770263, 0.7223993389323633, 0.72247641762350434,
0.72254852578410134, 0.72261568295370648, 0.72267790855952341,
0.72273522191746897, 0.72278764223322189, 0.72283518860325757,
0.72287788001587183, 0.72291573535219023, 0.72294877338716657,
0.7229770127905677, 0.72300047212794816, 0.72301916986161097,
0.72303312435155898, 0.72304235385643245, 0.72304687653443711,
0.72304671044426128, 0.72304187354597971, 0.72303238370195011,
0.72301825867769609, 0.72299951614278113, 0.72297617367167222,
0.72294824874459285, 0.72291575874836644, 0.72287872097724981,
0.72283715263375714, 0.72279107082947391, 0.72274049258586182,
0.72268543483505443, 0.7226259144206435, 0.72256194809845664,
0.72249355253732606, 0.72242074431984737, 0.72234353994313194,
0.72226195581954922, 0.72217600827746087, 0.72208571356194695,
0.72199108783552435, 0.72189214717885586, 0.72178890759145253,
0.72168138499236822, 0.7215695952208856, 0.72145355403719491,
0.72133327712306639, 0.72120878008251321, 0.72108007844244815,
0.72094718765333421, 0.72081012308982595, 0.72066890005140549,
0.72052353376301082, 0.72037403937565803, 0.72022043196705532,
0.72006272654221193, 0.71990093803404021, 0.71973508130395003,
0.71956517114243856, 0.71939122226967267, 0.71921324933606479,
0.71903126692284347, 0.71884528954261773, 0.71865533163993445,
0.71846140759183186, 0.71826353170838397, 0.71806171823324294,
0.71785598134417261, 0.71764633515357823, 0.71743279370902957,
0.71721537099377952, 0.71699408092727579, 0.71676893736566882,
0.71653995410231308, 0.71630714486826286, 0.71607052333276544,
0.71583010310374462, 0.71558589772828363, 0.71533792069309965,
0.71508618542501545, 0.71483070529142378, 0.7145714936007499,
0.7143085636029064, 0.7140419284897449, 0.71377160139550122,
0.713497595397238, 0.71321992351528118, 0.71293859871365117,
0.71265363390049186, 0.71236504192849126, 0.71207283559530199,
0.71177702764395256, 0.71147763076325798, 0.7111746575882234,
0.71086812070044492, 0.71055803262850459, 0.71024440584836102,
0.70992725278373747, 0.70960658580650238, 0.70928241723704866,
0.70895475934466645, 0.70862362434791193, 0.70828902441497299,
0.70795097166402854, 0.70760947816360498, 0.70726455593292792,
0.7069162169422688, 0.70656447311328863, 0.70620933631937588,
0.70585081838598029, 0.70548893109094335, 0.70512368616482313,
0.70475509529121427, 0.70438317010706597, 0.70400792220299213,
0.70362936312357993, 0.70324750436769101, 0.70286235738876113,
0.70247393359509247, 0.70208224435014233, 0.70168730097280785,
0.70128911473770383, 0.70088769687543795, 0.7004830585728794,
0.70007521097342262, 0.69966416517724705, 0.69924993224157006,
0.69883252318089595, 0.69841194896725822, 0.69798822053045706,
0.69756134875829123, 0.6971313444967836, 0.69669821855040082,
0.69626198168226705, 0.69582264461437149, 0.69538021802776873,
0.69493471256277317, 0.69448613881914611, 0.69403450735627592,
0.69357982869335044, 0.69312211330952311, 0.6926613716440686,
0.69219761409653258, 0.69173085102687282, 0.69126109275558933,
0.69078834956384805, 0.69031263169359336, 0.68983394934764997,
0.68935231268981634, 0.68886773184494554, 0.68838021689901496,
0.68788977789918415, 0.68739642485384045, 0.68690016773263074,
0.68640101646647911, 0.68589898094759061, 0.68539407102943872,
0.68488629652673738, 0.68437566721539478, 0.68386219283244964,
0.68334588307598754, 0.6828267476050377, 0.68230479603944671,
0.68178003795973041, 0.6812524829069011, 0.68072214038226719,
0.68018901984720648, 0.67965313072291, 0.67911448239009231, 0.67857308418866935,
0.6780289454174, 0.67748207533348759, 0.67693248315214094, 0.67638017804608863,
0.67582516914504764, 0.67526746553513772, 0.67470707625824022,
0.67414401031129778, 0.67357827664554593, 0.67300988416567653,
0.67243884172892254, 0.67186515814406067, 0.67128884217032203,
0.6707099025162061, 0.67012834783818498, 0.66954418673929184,
0.6689574277675796, 0.66836807941444054, 0.66777615011276981,
0.66718164823495973, 0.66658458209070792, 0.66598495992461726,
0.66538278991356881, 0.66477808016384221, 0.6641708387079539,
0.66356107350118321, 0.66294879241775084, 0.66233400324660519,
0.66171671368677232, 0.66109693134221492, 0.66047466371613461,
0.65984991820464811, 0.65922270208975253, 0.65859302253147745,
0.65796088655911356, 0.65732630106137835, 0.65668927277535916,
0.65604980827404225, 0.65540791395219911, 0.65476359601035639,
0.65411686043651529, 0.65346771298521822, 0.65281615915346303,
0.65216220415285664, 0.65150585287723817, 0.65084710986481642,
0.65018597925359556, 0.64952246472852893, 0.64885656945836157,
0.64818829601948924, 0.64751764630325681, 0.64684462140185506,
0.646169221466115, 0.64549144552577065, 0.64481129125857295,
0.64412875468807984, 0.64344382977928827, 0.64275650788319449,
0.64206677694922998, 0.64137462036380188, 0.64068001514963335,
0.63998292898386888, 0.63928331478691058, 0.6385810994577602,
0.63787615413745602, 0.63716814159292035, 0.63716814159292035
), tn = c(
0, 0, 0.45991211074007265, 0.96057835335201014, 1.4647887818674366,
1.967121969028786, 2.4656935535847317, 2.9597200391488458, 3.4488680909427805,
3.9330164323751347, 4.4121522082296645, 4.8863205662368561, 5.3555981778131043,
5.8200785558422048, 6.2798635955334996, 6.7350585742066151, 7.1857691536208117,
7.6320995792455593, 8.0741516128090982, 8.5120239223958745, 8.9458117616295993,
9.375606832691334, 9.8014972662052173, 10.223567674759112, 10.641899251839298,
11.05656989761893, 11.467654359345813, 11.875224378244205, 12.279348837626427,
12.680093908781391, 13.07752319247105, 13.471697854723931, 13.86267675619542,
14.250516574756512, 14.635271921235319, 15.016995448408345, 15.395737953449929,
15.771548474116321, 16.144474378979261, 16.514561452043029, 16.881853972083736,
17.246394787044821, 17.608225383812659, 17.967385953682275, 18.323915453807086,
18.677851664908896, 19.029231245507312, 19.378089782910223, 19.724461841190291,
20.068381006356287, 20.40987992891267, 20.748990363986874, 21.085743209190319,
21.42016854036649, 21.752295645368168, 22.082153055995029, 22.409768578213253,
22.735169320769522, 23.05838172230305, 23.379431577052525, 23.698344059246612,
24.015143746261302, 24.329854640620105, 24.642500190908734, 24.953103311670155,
25.261686402341436, 25.568271365289284, 25.872879622997541, 26.175532134455999,
26.476249410796548, 26.775051530219464, 27.071958152250055, 27.366988531362928,
27.66016153000886, 27.951495631076689, 28.24100894982098, 28.528719245283941,
28.814643931238386, 29.098800086676743, 29.381204465869551, 29.66187350801583,
29.940823346505791, 30.218069817815252, 30.493628470050517, 30.767514571160294,
31.039743116831652, 31.31032883808448, 31.579286208579429, 31.846629451652646,
32.11237254709016, 32.376529237654069, 32.639113035371686, 32.900137227598819,
33.159614882867182, 33.417558856525503, 33.673981796183497, 33.928896146967688,
34.182314156596711, 34.434247880284339, 34.68470918547726, 34.933709756434901,
35.1812610986577, 35.427374543170266, 35.672061250665209, 35.915332215513679,
36.157198269647729, 36.397670086319764, 36.636758183743837, 36.87447292862386,
37.110824539572583, 37.34582309042618, 37.579478513457886, 37.811800602495012,
38.042799015942961, 38.272483279719282, 38.500862790101749, 38.727946816493187,
38.953744504106425, 39.178264876572044, 39.401516838471778, 39.623509177800379,
39.844250568358376, 40.063749572078166, 40.282014641285713, 40.499054120900361,
40.714876250574648, 40.929489166776293, 41.142900904814205, 41.355119400810622,
41.566152493621104, 41.776007926703926, 41.984693349940876, 42.192216321410797,
42.398584309117631, 42.603804692674181, 42.80788476494326, 43.010831733637474,
43.212652722879064, 43.413354774720759, 43.612944850629304, 43.811429832932554,
44.008816526231271, 44.205111658776744, 44.400321883815423, 44.594453780901226,
44.787513857176911, 44.979508548625056, 45.170444221289891, 45.360327172470505,
45.549163631886614, 45.736959762817456, 45.923721663214565, 46.109455366789476,
46.294166844076692, 46.477862003473, 46.660546692253327, 46.842226697564406,
47.022907747396317, 47.202595511532898, 47.381295602481345, 47.559013576381744,
47.735754933897127, 47.91152512108431, 48.086329530246346, 48.260173500766896,
48.433062319927089, 48.605001223705273, 48.77599539756018, 48.946049977197831,
49.115170049322764, 49.283360652373901, 49.450626777245319, 49.616973367992664,
49.782405322525157, 49.94692749328398, 50.110544687906888, 50.273261669879957,
50.435083159176322, 50.596013832882505, 50.756058325812489, 50.915221231109953,
51.073507100838889, 51.230920446562877, 51.387465739913324, 51.543147413146954,
51.697969859692769, 51.851937434688736, 52.005054455508407, 52.157325202277825,
52.308753918382834, 52.459344810967117, 52.609102051420948, 52.75802977586126,
52.906132085602863, 53.053413047621277, 53.199876695007049, 53.34552702741226,
53.490368011488826, 53.634403581319226, 53.777637638839529, 53.920074054255061,
54.061716666448845, 54.202569283382942, 54.342635682492812, 54.481919611074943,
54.620424786667819, 54.7581548974265, 54.89511360249066, 55.031304532346589,
55.166731289183033, 55.301397447241129, 55.435306553158412, 55.568462126307288,
55.70086765912778, 55.832526617454903, 55.963442440840616, 56.093618542870566,
56.223058311475711, 56.351765109238983, 56.4797422736968, 56.606993117636037,
56.733520929386088, 56.859328973106365, 56.984420489069251, 57.108798693938553,
57.23246678104374, 57.35542792064976, 57.477685260222692, 57.599241924691427,
57.720101016705144, 57.84026561688696, 57.95973878408369, 58.078523555611746,
58.196622947499442, 58.314039954725544, 58.430777551454227, 58.546838691266686,
58.662226307389069, 58.776943312917211, 58.890992601037979, 59.004377045247352,
59.11709949956537, 59.229162798747879, 59.340569758495256, 59.45132317565804,
59.561425828439731, 59.670880476596544, 59.779689861634374, 59.887856707002953,
59.995383718287272, 60.102273583396247, 60.208528972748745, 60.314152539457069,
60.419146919507789, 60.523514731940132, 60.627258579021841, 60.730381046422636,
60.832884703385304, 60.934772102894456, 61.03604578184288, 61.136708261195814,
61.236762046152784, 61.336209626307458, 61.435053475805212, 61.533296053498631,
61.630939803100958, 61.727987153337494, 61.824440518094953, 61.920302296568906,
62.015574873409243, 62.110260618863741, 62.20436188891982, 62.297881025444283,
62.390820356321505, 62.483182195589592, 62.574968843574943, 62.66618258702502,
62.756825699239457, 62.846900440199455, 62.936409056695602, 63.025353782454033,
63.113736838260991, 63.201560432085856, 63.288826759202664, 63.375538002310009,
63.46169633164957, 63.547303905123101, 63.632362868407995, 63.716875355071465,
63.800843486683277, 63.884269372927108, 63.967155111710582, 64.049502789273987,
64.13131448029759, 64.21259224800778, 64.293338144281805, 64.373554209751418,
64.453242473905092, 64.53240495518925, 64.611043661108042, 64.689160588322139,
64.76675772274632, 64.843837039645834, 64.920400503731742, 64.996450069255062,
65.07198768009988, 65.147015269875368, 65.221534762006684, 65.295548069824946,
65.369057096656007, 65.442063735908391, 65.51456987116012, 65.58657737624452,
65.658088115335161, 65.729103943029799, 65.799626704433308, 65.86965823523974,
65.939200361813477, 66.008254901269424, 66.076823661552339, 66.144908441515298,
66.212511030997248, 66.279633210899703, 66.346276753262671, 66.412443421339646,
66.478134969671785, 66.543353144161401, 66.608099682144456, 66.672376312462433,
66.736184755533344, 66.799526723421963, 66.86240391990934, 66.924818040561533,
66.986770772797612, 67.048263795956913, 67.109298781365624, 67.169877392402569,
67.230001284564366, 67.289672105529846, 67.348891495223825, 67.407661085880122,
67.465982502103998, 67.523857360933889, 67.58128727190244, 67.638273837096989,
67.694818651219308, 67.750923301644804, 67.806589368481042, 67.861818424625611,
67.916612035823519, 67.970971760723799, 68.024899150935624, 68.078395751083903,
68.131463098864046, 68.184102725096452, 68.236316153780152, 68.288104902146117,
68.33947048070975, 68.390414393323084, 68.440938137226283, 68.491043203098513,
68.540731075108468, 68.590003230964214, 68.638861141962579, 68.68730627303789,
68.735340082810367, 68.782964023633809, 68.830179541642906, 68.876988076799904,
68.923391062940908, 68.969389927821496, 69.014986093162022, 69.060180974692258,
69.104975982195526, 69.149372519552557, 69.193371984784477, 69.236975770095697,
69.280185261915989, 69.323001840942226, 69.365426882179619, 69.407461754982393,
69.44910782309401, 69.490366444686998, 69.531238972402008, 69.571726753386741,
69.611831129334092, 69.65155343651989, 69.690895005840204, 69.729857162848106,
69.768441227789793, 69.806648515640518, 69.844480336139682, 69.881937993825588,
69.91902278806964, 69.955736013110041, 69.992078958084974, 70.028052907065103,
70.063659139085786, 70.098898928178542, 70.133773543401986, 70.168284248872354,
70.202432303793231, 70.236218962484884, 70.269645474412883, 70.302713084216194,
70.335423031734621, 70.367776552035579, 70.399774875440329, 70.431419227549455,
70.462710829267706, 70.493650896828086, 70.524240641815368, 70.554481271188749,
70.584373987303735, 70.613919987933372, 70.643120466288522, 70.671976611037451,
70.700489606324453, 70.728660631787577, 70.756490862575504, 70.783981469363439,
70.81113361836789, 70.837948471360633, 70.864427185681336, 70.890570914249224,
70.91638080557351, 70.941858003762604, 70.967003648531929, 70.991818875210541,
71.016304814746206, 71.040462593708995, 71.064293334293353, 71.087798154318435,
71.110978167226762, 71.133834482081014, 71.156368203558785, 71.178580431945477,
71.200472263124752, 71.222044788566905, 71.243299095314612, 71.264236265966176,
71.284857378655957, 71.305163507031807, 71.325155720229446, 71.344835082843431,
71.364202654894513, 71.383259491793211, 71.402006644299263, 71.420445158476667,
71.438576075643979, 71.456400432319555, 71.473919260161423, 71.491133585901082,
71.508044431271173, 71.524652812926163, 71.540959742355696, 71.556966225789935,
71.572673264096224, 71.588081852666321, 71.603192981293361, 71.618007634037752,
71.632526789080856, 71.646751418565415, 71.660682488421429, 71.674320958176196,
71.687667780746906, 71.700723902213866, 71.7134902615729, 71.725967790464139,
71.738157412875154, 71.750060044815541, 71.761676593959649, 71.773007959254059,
71.784055030485689, 71.794818687805716, 71.8052998012041, 71.815499229928605,
71.825417821841015, 71.835056412702542, 71.844415825378832, 71.853496868953229,
71.862300337735604, 71.870827010151018, 71.879077647490334, 71.887052992501012,
71.894753767792224, 71.902180674023498, 71.909334387838953, 71.916215559501865,
71.922824810173026, 71.929162728763984, 71.935229868278597, 71.941026741534429,
71.94655381612597, 71.95181150845292, 71.956800176583499, 71.961520111650415,
71.965971527375658, 71.970154547176747, 71.974069188097616, 71.977715340498193,
71.981092741964332, 71.9842009431581, 71.987039262124142, 71.98960672152505,
71.991901959646555, 71.993923099152667, 71.995667543611106, 71.997131640539209,
71.99831006994242, 71.999194571407926, 71.999770583873044, 72,
72
), tp = c(
41, 41, 40.919765166340504, 40.839530332681015, 40.759295499021526,
40.679060665362037, 40.598825831702541, 40.518590998043045, 40.438356164383556,
40.358121330724067, 40.277886497064578, 40.197651663405082, 40.117416829745594,
40.037181996086105, 39.956947162426616, 39.87671232876712, 39.796477495107631,
39.716242661448142, 39.636007827788646, 39.555772994129157, 39.475538160469668,
39.395303326810179, 39.315068493150683, 39.234833659491187, 39.154598825831698,
39.074363992172209, 38.99412915851272, 38.913894324853224, 38.833659491193735,
38.753424657534246, 38.67318982387475, 38.592954990215262, 38.512720156555773,
38.432485322896284, 38.352250489236788, 38.272015655577292, 38.191780821917803,
38.111545988258314, 38.031311154598825, 37.951076320939329, 37.87084148727984,
37.790606653620351, 37.710371819960862, 37.630136986301366, 37.549902152641877,
37.469667318982388, 37.389432485322892, 37.309197651663403, 37.228962818003914,
37.148727984344426, 37.06849315068493, 36.988258317025434, 36.908023483365945,
36.827788649706456, 36.747553816046967, 36.667318982387471, 36.587084148727982,
36.506849315068493, 36.426614481409004, 36.346379647749508, 36.266144814090019,
36.18590998043053, 36.105675146771034, 36.025440313111545, 35.945205479452056,
35.86497064579256, 35.784735812133064, 35.704500978473575, 35.624266144814086,
35.544031311154598, 35.463796477495109, 35.383561643835613, 35.303326810176131,
35.223091976516635, 35.142857142857139, 35.06262230919765, 34.982387475538161,
34.902152641878672, 34.821917808219176, 34.74168297455968, 34.661448140900191,
34.581213307240702, 34.500978473581213, 34.420743639921717, 34.340508806262228,
34.260273972602739, 34.180039138943243, 34.099804305283755, 34.019569471624266,
33.939334637964777, 33.859099804305288, 33.778864970645792, 33.698630136986303,
33.618395303326814, 33.538160469667318, 33.457925636007822, 33.377690802348333,
33.297455968688844, 33.217221135029355, 33.136986301369852, 33.05675146771037,
32.976516634050881, 32.896281800391392, 32.816046966731896, 32.735812133072407,
32.655577299412919, 32.575342465753423, 32.495107632093926, 32.414872798434438,
32.334637964774949, 32.25440313111546, 32.174168297455964, 32.093933463796475,
32.013698630136986, 31.933463796477493, 31.853228962818001, 31.772994129158512,
31.692759295499023, 31.612524461839534, 31.532289628180035, 31.452054794520546,
31.37181996086106, 31.291585127201568, 31.211350293542072, 31.131115459882583,
31.050880626223098, 30.970645792563598, 30.890410958904106, 30.810176125244617,
30.729941291585128, 30.649706457925635, 30.569471624266139, 30.48923679060665,
30.409001956947161, 30.328767123287669, 30.248532289628177, 30.168297455968691,
30.088062622309199, 30.007827788649706, 29.92759295499021, 29.847358121330721,
29.767123287671232, 29.686888454011743, 29.606653620352247, 29.526418786692759,
29.44618395303327, 29.365949119373774, 29.285714285714281, 29.205479452054792,
29.125244618395303, 29.045009784735811, 28.964774951076318, 28.884540117416829,
28.804305283757341, 28.724070450097845, 28.643835616438352, 28.563600782778863,
28.483365949119374, 28.403131115459882, 28.322896281800389, 28.2426614481409,
28.162426614481411, 28.082191780821915, 28.001956947162423, 27.921722113502934,
27.841487279843445, 27.761252446183953, 27.681017612524457, 27.600782778864964,
27.520547945205479, 27.440313111545983, 27.360078277886494, 27.279843444227005,
27.199608610567516, 27.119373776908017, 27.039138943248528, 26.958904109589039,
26.87866927592955, 26.798434442270057, 26.718199608610565, 26.637964774951076,
26.557729941291587, 26.477495107632091, 26.397260273972599, 26.31702544031311,
26.236790606653621, 26.156555772994128, 26.076320939334636, 25.996086105675147,
25.915851272015658, 25.835616438356162, 25.755381604696669, 25.675146771037181,
25.594911937377692, 25.514677103718199, 25.434442270058703, 25.354207436399214,
25.273972602739725, 25.193737769080233, 25.11350293542074, 25.033268101761252,
24.953033268101763, 24.87279843444227, 24.792563600782774, 24.712328767123285,
24.632093933463796, 24.551859099804304, 24.471624266144811, 24.391389432485322,
24.311154598825834, 24.230919765166337, 24.150684931506845, 24.070450097847356,
23.990215264187867, 23.909980430528375, 23.829745596868882, 23.749510763209393,
23.669275929549904, 23.589041095890408, 23.508806262230916, 23.428571428571427,
23.348336594911938, 23.268101761252446, 23.18786692759295, 23.107632093933461,
23.027397260273972, 22.947162426614479, 22.866927592954987, 22.786692759295498,
22.706457925636009, 22.626223091976517, 22.545988258317021, 22.465753424657532,
22.385518590998043, 22.30528375733855, 22.225048923679058, 22.144814090019569,
22.06457925636008, 21.984344422700588, 21.904109589041092, 21.823874755381603,
21.743639921722114, 21.663405088062621, 21.583170254403129, 21.50293542074364,
21.422700587084151, 21.342465753424655, 21.262230919765162, 21.181996086105674,
21.101761252446185, 21.021526418786692, 20.9412915851272, 20.861056751467711,
20.780821917808222, 20.700587084148726, 20.620352250489233, 20.540117416829744,
20.459882583170252, 20.379647749510763, 20.299412915851271, 20.219178082191778,
20.138943248532289, 20.058708414872797, 19.978473581213308, 19.898238747553815,
19.818003913894323, 19.737769080234834, 19.657534246575342, 19.577299412915849,
19.49706457925636, 19.416829745596868, 19.336594911937375, 19.256360078277886,
19.176125244618394, 19.095890410958901, 19.015655577299412, 18.93542074363992,
18.855185909980431, 18.774951076320939, 18.694716242661446, 18.614481409001957,
18.534246575342465, 18.454011741682972, 18.373776908023483, 18.293542074363991,
18.213307240704498, 18.13307240704501, 18.052837573385517, 17.972602739726028,
17.892367906066536, 17.812133072407043, 17.731898238747554, 17.651663405088062,
17.571428571428569, 17.49119373776908, 17.410958904109592, 17.330724070450096,
17.250489236790607, 17.170254403131114, 17.090019569471622, 17.009784735812133,
16.929549902152644, 16.849315068493151, 16.769080234833659, 16.688845401174166,
16.608610567514678, 16.528375733855185, 16.448140900195693, 16.367906066536204,
16.287671232876711, 16.207436399217222, 16.12720156555773, 16.046966731898237,
15.966731898238747, 15.886497064579256, 15.806262230919764, 15.726027397260273,
15.645792563600784, 15.565557729941291, 15.485322896281799, 15.405088062622308,
15.324853228962819, 15.244618395303325, 15.164383561643834, 15.084148727984344,
15.003913894324855, 14.923679060665361, 14.84344422700587, 14.763209393346379,
14.682974559686887, 14.602739726027396, 14.522504892367905, 14.442270058708415,
14.36203522504892, 14.281800391389433, 14.201565557729943, 14.121330724070452,
14.041095890410958, 13.960861056751469, 13.880626223091976, 13.800391389432484,
13.720156555772995, 13.639921722113503, 13.559686888454012, 13.479452054794523,
13.399217221135029, 13.318982387475538, 13.238747553816044, 13.158512720156555,
13.078277886497064, 12.998043052837573, 12.917808219178085, 12.837573385518592,
12.757338551859096, 12.677103718199607, 12.596868884540118, 12.516634050880626,
12.436399217221135, 12.356164383561643, 12.275929549902152, 12.195694716242661,
12.115459882583172, 12.035225048923678, 11.954990215264189, 11.874755381604693,
11.794520547945208, 11.714285714285714, 11.634050880626219, 11.553816046966734,
11.47358121330724, 11.393346379647749, 11.313111545988255, 11.232876712328766,
11.152641878669277, 11.072407045009784, 10.992172211350294, 10.911937377690801,
10.831702544031312, 10.751467710371822, 10.671232876712331, 10.590998043052837,
10.510763209393346, 10.430528375733855, 10.350293542074366, 10.270058708414874,
10.189823874755382, 10.109589041095889, 10.029354207436398, 9.9491193737769041,
9.8688845401174188, 9.7886497064579245, 9.7084148727984338, 9.6281800391389378,
9.5479452054794542, 9.46771037181996, 9.3874755381604675, 9.3072407045009786,
9.2270058708414897, 9.1467710371819972, 9.066536203522503, 8.9863013698630123,
8.9060665362035216, 8.8258317025440309, 8.7455968688845385, 8.6653620352250478,
8.5851272015655571, 8.5048923679060646, 8.4246575342465757, 8.3444227005870832,
8.2641878669275908, 8.1839530332681019, 8.1037181996086094, 8.0234833659491205,
7.943248532289628, 7.8630136986301391, 7.7827788649706466, 7.7025440313111542,
7.6223091976516653, 7.5420743639921719, 7.461839530332683, 7.3816046966731896,
7.3013698630136989, 7.2211350293542074, 7.1409001956947149, 7.0606653620352224,
6.9804305283757344, 6.9001956947162419, 6.8199608610567513, 6.7397260273972623,
6.659491193737769, 6.5792563600782783, 6.4990215264187867, 6.418786692759296,
6.3385518590998027, 6.258317025440312, 6.178082191780824, 6.0978473581213271,
6.0176125244618399, 5.9373776908023457, 5.8571428571428559, 5.7769080234833634,
5.6966731898238736, 5.616438356164382, 5.5362035225048913, 5.4559686888453989,
5.37573385518591, 5.2954990215264219, 5.2152641878669295, 5.1350293542074397,
5.0547945205479445, 4.9745596868884538, 4.894324853228964, 4.8140900195694716,
4.73385518590998, 4.6536203522504875, 4.5733855185909968, 4.4931506849315062,
4.4129158512720164, 4.3326810176125257, 4.2524461839530323, 4.1722113502935407,
4.0919765166340527, 4.0117416829745602, 3.9315068493150704, 3.8512720156555775,
3.7710371819960855, 3.6908023483365957, 3.6105675146771046, 3.5303326810176117,
3.4500978473581223, 3.3698630136986316, 3.2896281800391418, 3.209393346379648,
3.129158512720156, 3.0489236790606662, 2.9686888454011755, 2.8884540117416844,
2.8082191780821923, 2.7279843444227003, 2.6477495107632105, 2.5675146771037194,
2.4872798434442278, 2.4070450097847385, 2.3268101761252464, 2.2465753424657535,
2.1663405088062651, 2.0861056751467726, 2.0058708414872815, 1.9256360078277897,
1.8454011741682987, 1.7651663405088074, 1.6849315068493158, 1.6046966731898256,
1.5244618395303329, 1.4442270058708433, 1.3639921722113517, 1.2837573385518593,
1.2035225048923686, 1.1232876712328772, 1.0430528375733856, 0.96281800391389483,
0.88258317025440369, 0.802348336594912, 0.72211350293542165,
0.64187866927593051, 0.5616438356164386, 0.48140900195694708,
0.40117416829745678, 0.32093933463796553, 0.24070450097847404,
0.16046966731898246, 0.080234833659491328, 0, 0
), fn = c(
0, 0,
0.080234833659496019, 0.16046966731898493, 0.24070450097847385,
0.32093933463796276, 0.40117416829745878, 0.4814090019569548,
0.56164383561644371, 0.64187866927593262, 0.72211350293542154,
0.80234833659491755, 0.88258317025440647, 0.96281800391389538,
1.0430528375733843, 1.1232876712328803, 1.2035225048923692, 1.2837573385518581,
1.3639921722113542, 1.4442270058708431, 1.524461839530332, 1.6046966731898209,
1.6849315068493169, 1.7651663405088129, 1.8454011741683018, 1.9256360078277908,
2.0058708414872797, 2.0861056751467757, 2.1663405088062646, 2.2465753424657535,
2.3268101761252495, 2.4070450097847385, 2.4872798434442274, 2.5675146771037163,
2.6477495107632123, 2.7279843444227083, 2.8082191780821972, 2.8884540117416861,
2.9686888454011751, 3.0489236790606711, 3.12915851272016, 3.2093933463796489,
3.2896281800391378, 3.3698630136986338, 3.4500978473581227, 3.5303326810176117,
3.6105675146771077, 3.6908023483365966, 3.7710371819960855, 3.8512720156555744,
3.9315068493150704, 4.0117416829745665, 4.0919765166340554, 4.1722113502935443,
4.2524461839530332, 4.3326810176125292, 4.4129158512720181, 4.493150684931507,
4.573385518590996, 4.653620352250492, 4.7338551859099809, 4.8140900195694698,
4.8943248532289658, 4.9745596868884547, 5.0547945205479436, 5.1350293542074397,
5.2152641878669357, 5.2954990215264246, 5.3757338551859135, 5.4559686888454024,
5.5362035225048913, 5.6164383561643874, 5.6966731898238692, 5.7769080234833652,
5.8571428571428612, 5.9373776908023501, 6.017612524461839, 6.0978473581213279,
6.178082191780824, 6.25831702544032, 6.3385518590998089, 6.4187866927592978,
6.4990215264187867, 6.5792563600782827, 6.6594911937377717, 6.7397260273972606,
6.8199608610567566, 6.9001956947162455, 6.9804305283757344, 7.0606653620352233,
7.1409001956947122, 7.2211350293542083, 7.3013698630136972, 7.3816046966731861,
7.4618395303326821, 7.5420743639921781, 7.622309197651667, 7.7025440313111559,
7.7827788649706449, 7.863013698630148, 7.9432485322896298, 8.0234833659491187,
8.1037181996086076, 8.1839530332681036, 8.2641878669275926, 8.3444227005870815,
8.4246575342465775, 8.5048923679060735, 8.5851272015655624, 8.6653620352250513,
8.7455968688845402, 8.8258317025440363, 8.9060665362035252, 8.9863013698630141,
9.0665362035225066, 9.146771037181999, 9.2270058708414879, 9.3072407045009768,
9.3874755381604658, 9.4677103718199653, 9.5479452054794542, 9.6281800391389396,
9.7084148727984321, 9.7886497064579281, 9.868884540117417, 9.9491193737769024,
10.029354207436402, 10.109589041095894, 10.189823874755383, 10.270058708414872,
10.350293542074365, 10.430528375733861, 10.51076320939335, 10.590998043052839,
10.671232876712331, 10.751467710371823, 10.831702544031309, 10.911937377690801,
10.992172211350294, 11.07240704500979, 11.152641878669279, 11.232876712328768,
11.313111545988257, 11.393346379647753, 11.473581213307241, 11.55381604696673,
11.634050880626226, 11.714285714285719, 11.794520547945208, 11.874755381604697,
11.954990215264189, 12.035225048923682, 12.115459882583171, 12.195694716242659,
12.275929549902155, 12.356164383561648, 12.436399217221137, 12.516634050880626,
12.596868884540118, 12.677103718199611, 12.7573385518591, 12.837573385518589,
12.917808219178085, 12.998043052837577, 13.078277886497066, 13.158512720156555,
13.238747553816047, 13.318982387475543, 13.399217221135036, 13.479452054794521,
13.559686888454017, 13.639921722113506, 13.720156555772995, 13.800391389432484,
13.880626223091983, 13.960861056751472, 14.041095890410961, 14.12133072407045,
14.201565557729943, 14.281800391389435, 14.362035225048924, 14.442270058708413,
14.522504892367909, 14.602739726027401, 14.68297455968689, 14.763209393346379,
14.843444227005872, 14.923679060665364, 15.003913894324853, 15.084148727984342,
15.164383561643838, 15.244618395303331, 15.324853228962819, 15.405088062622308,
15.485322896281801, 15.565557729941297, 15.645792563600786, 15.726027397260275,
15.806262230919767, 15.88649706457926, 15.966731898238748, 16.046966731898237,
16.12720156555773, 16.207436399217226, 16.287671232876715, 16.367906066536204,
16.448140900195696, 16.528375733855189, 16.608610567514678, 16.688845401174166,
16.769080234833663, 16.849315068493155, 16.929549902152644, 17.009784735812133,
17.090019569471625, 17.170254403131118, 17.250489236790607, 17.330724070450096,
17.410958904109592, 17.491193737769084, 17.571428571428573, 17.651663405088062,
17.731898238747554, 17.81213307240705, 17.892367906066539, 17.972602739726028,
18.052837573385521, 18.133072407045013, 18.213307240704502, 18.293542074363991,
18.373776908023483, 18.454011741682979, 18.534246575342468, 18.614481409001957,
18.69471624266145, 18.774951076320942, 18.855185909980431, 18.93542074363992,
19.015655577299412, 19.095890410958908, 19.176125244618397, 19.256360078277886,
19.336594911937379, 19.416829745596871, 19.49706457925636, 19.577299412915849,
19.657534246575345, 19.737769080234838, 19.818003913894326, 19.898238747553815,
19.978473581213308, 20.0587084148728, 20.138943248532289, 20.219178082191778,
20.299412915851274, 20.379647749510767, 20.459882583170256, 20.540117416829748,
20.620352250489237, 20.700587084148729, 20.780821917808222, 20.861056751467711,
20.941291585127203, 21.021526418786692, 21.101761252446185, 21.181996086105677,
21.262230919765166, 21.342465753424658, 21.422700587084151, 21.50293542074364,
21.583170254403132, 21.663405088062625, 21.743639921722114, 21.823874755381606,
21.904109589041099, 21.984344422700588, 22.06457925636008, 22.144814090019569,
22.225048923679061, 22.305283757338554, 22.385518590998043, 22.465753424657535,
22.545988258317028, 22.626223091976517, 22.706457925636009, 22.786692759295502,
22.86692759295499, 22.947162426614483, 23.027397260273972, 23.107632093933464,
23.187866927592957, 23.268101761252446, 23.348336594911938, 23.428571428571431,
23.50880626223092, 23.589041095890408, 23.669275929549904, 23.749510763209393,
23.829745596868886, 23.909980430528378, 23.990215264187867, 24.070450097847356,
24.150684931506849, 24.230919765166341, 24.311154598825834, 24.391389432485322,
24.471624266144815, 24.551859099804307, 24.632093933463796, 24.712328767123289,
24.792563600782778, 24.87279843444227, 24.953033268101763, 25.033268101761252,
25.113502935420744, 25.193737769080236, 25.273972602739725, 25.354207436399214,
25.43444227005871, 25.514677103718199, 25.594911937377692, 25.675146771037181,
25.755381604696673, 25.835616438356166, 25.915851272015658, 25.996086105675147,
26.076320939334639, 26.156555772994132, 26.236790606653621, 26.317025440313113,
26.397260273972606, 26.477495107632095, 26.557729941291583, 26.63796477495108,
26.718199608610568, 26.798434442270057, 26.878669275929546, 26.958904109589042,
27.039138943248531, 27.119373776908024, 27.199608610567516, 27.279843444227005,
27.360078277886497, 27.44031311154599, 27.520547945205479, 27.600782778864971,
27.681017612524464, 27.761252446183956, 27.841487279843445, 27.921722113502938,
28.001956947162427, 28.082191780821915, 28.162426614481408, 28.242661448140904,
28.322896281800393, 28.403131115459882, 28.483365949119374, 28.563600782778863,
28.643835616438359, 28.724070450097848, 28.804305283757337, 28.884540117416826,
28.964774951076322, 29.045009784735811, 29.125244618395307, 29.205479452054792,
29.285714285714285, 29.365949119373781, 29.446183953033266, 29.526418786692759,
29.606653620352251, 29.686888454011743, 29.767123287671232, 29.847358121330721,
29.927592954990217, 30.007827788649706, 30.088062622309199, 30.168297455968688,
30.24853228962818, 30.328767123287669, 30.409001956947165, 30.489236790606654,
30.569471624266143, 30.649706457925632, 30.729941291585128, 30.810176125244617,
30.890410958904113, 30.970645792563602, 31.050880626223098, 31.131115459882579,
31.211350293542075, 31.291585127201564, 31.37181996086106, 31.452054794520546,
31.532289628180038, 31.612524461839534, 31.692759295499023, 31.772994129158512,
31.853228962818001, 31.933463796477497, 32.013698630136986, 32.093933463796475,
32.174168297455971, 32.25440313111546, 32.334637964774956, 32.414872798434445,
32.495107632093934, 32.575342465753423, 32.655577299412919, 32.735812133072407,
32.816046966731896, 32.896281800391392, 32.976516634050881, 33.05675146771037,
33.136986301369859, 33.217221135029355, 33.297455968688844, 33.377690802348333,
33.457925636007829, 33.538160469667318, 33.618395303326807, 33.698630136986303,
33.778864970645792, 33.859099804305288, 33.939334637964777, 34.019569471624266,
34.099804305283755, 34.180039138943251, 34.260273972602739, 34.340508806262228,
34.420743639921724, 34.500978473581213, 34.581213307240702, 34.661448140900198,
34.741682974559687, 34.821917808219176, 34.902152641878672, 34.982387475538161,
35.062622309197657, 35.142857142857146, 35.223091976516635, 35.303326810176124,
35.38356164383562, 35.463796477495109, 35.544031311154598, 35.624266144814086,
35.704500978473575, 35.784735812133071, 35.86497064579256, 35.945205479452056,
36.025440313111545, 36.105675146771034, 36.18590998043053, 36.266144814090019,
36.346379647749515, 36.426614481409004, 36.506849315068493, 36.587084148727982,
36.667318982387471, 36.747553816046967, 36.827788649706463, 36.908023483365945,
36.988258317025441, 37.06849315068493, 37.148727984344426, 37.228962818003914,
37.309197651663403, 37.389432485322892, 37.469667318982388, 37.549902152641877,
37.630136986301366, 37.710371819960855, 37.790606653620351, 37.870841487279847,
37.951076320939336, 38.031311154598825, 38.111545988258314, 38.19178082191781,
38.272015655577299, 38.352250489236788, 38.432485322896284, 38.512720156555773,
38.592954990215262, 38.67318982387475, 38.753424657534246, 38.833659491193735,
38.913894324853224, 38.99412915851272, 39.074363992172209, 39.154598825831698,
39.234833659491194, 39.315068493150683, 39.395303326810172, 39.475538160469668,
39.555772994129157, 39.636007827788646, 39.716242661448142, 39.796477495107631,
39.87671232876712, 39.956947162426616, 40.037181996086105, 40.117416829745594,
40.19765166340509, 40.277886497064578, 40.358121330724067, 40.438356164383563,
40.518590998043052, 40.598825831702541, 40.679060665362037, 40.759295499021526,
40.839530332681015, 40.919765166340511, 41, 41
), fp = c(
72, 72,
71.540087889259922, 71.039421646647995, 70.535211218132559, 70.032878030971219,
69.534306446415272, 69.040279960851151, 68.551131909057219, 68.06698356762486,
67.587847791770329, 67.113679433763139, 66.644401822186893, 66.179921444157799,
65.720136404466501, 65.264941425793381, 64.814230846379189, 64.367900420754438,
63.925848387190904, 63.487976077604124, 63.054188238370401, 62.624393167308668,
62.198502733794783, 61.77643232524089, 61.358100748160702, 60.943430102381072,
60.532345640654185, 60.124775621755795, 59.720651162373571, 59.319906091218613,
58.922476807528952, 58.528302145276072, 58.13732324380458, 57.74948342524349,
57.364728078764685, 56.983004551591655, 56.604262046550069, 56.228451525883678,
55.855525621020739, 55.485438547956974, 55.118146027916268, 54.753605212955179,
54.391774616187341, 54.032614046317725, 53.676084546192911, 53.3221483350911,
52.970768754492688, 52.621910217089777, 52.275538158809709, 51.93161899364371,
51.590120071087327, 51.251009636013123, 50.914256790809681, 50.57983145963351,
50.247704354631836, 49.917846944004971, 49.590231421786747, 49.264830679230478,
48.941618277696946, 48.620568422947471, 48.301655940753392, 47.984856253738698,
47.670145359379895, 47.357499809091266, 47.046896688329845, 46.738313597658561,
46.431728634710716, 46.127120377002456, 45.824467865544001, 45.523750589203452,
45.224948469780536, 44.928041847749945, 44.633011468637072, 44.339838469991136,
44.048504368923311, 43.75899105017902, 43.471280754716062, 43.185356068761614,
42.901199913323254, 42.618795534130449, 42.33812649198417, 42.059176653494205,
41.781930182184752, 41.506371529949483, 41.232485428839709, 40.960256883168348,
40.68967116191552, 40.420713791420567, 40.153370548347354, 39.88762745290984,
39.623470762345931, 39.360886964628314, 39.099862772401181, 38.840385117132818,
38.582441143474497, 38.326018203816503, 38.071103853032312, 37.817685843403289,
37.565752119715661, 37.31529081452274, 37.066290243565099, 36.8187389013423,
36.572625456829734, 36.327938749334791, 36.084667784486321, 35.842801730352271,
35.602329913680236, 35.363241816256163, 35.12552707137614, 34.889175460427417,
34.65417690957382, 34.420521486542114, 34.188199397504988, 33.957200984057039,
33.727516720280718, 33.499137209898251, 33.272053183506813, 33.046255495893575,
32.821735123427956, 32.598483161528222, 32.376490822199621, 32.155749431641624,
31.936250427921834, 31.717985358714287, 31.500945879099639, 31.285123749425352,
31.070510833223707, 30.857099095185795, 30.644880599189378, 30.433847506378896,
30.223992073296074, 30.015306650059124, 29.807783678589203, 29.601415690882369,
29.396195307325819, 29.19211523505674, 28.989168266362526, 28.787347277120936,
28.586645225279241, 28.387055149370696, 28.188570167067446, 27.991183473768729,
27.794888341223256, 27.599678116184577, 27.405546219098774, 27.212486142823089,
27.020491451374944, 26.829555778710109, 26.639672827529495, 26.450836368113386,
26.263040237182544, 26.076278336785435, 25.890544633210524, 25.705833155923308,
25.522137996527, 25.339453307746673, 25.157773302435594, 24.977092252603683,
24.797404488467102, 24.618704397518655, 24.440986423618256, 24.264245066102873,
24.08847487891569, 23.913670469753654, 23.739826499233104, 23.566937680072911,
23.394998776294727, 23.22400460243982, 23.053950022802169, 22.884829950677236,
22.716639347626099, 22.549373222754681, 22.383026632007336, 22.217594677474843,
22.05307250671602, 21.889455312093112, 21.726738330120043, 21.564916840823678,
21.403986167117495, 21.243941674187511, 21.084778768890047, 20.926492899161111,
20.769079553437123, 20.612534260086676, 20.456852586853046, 20.302030140307231,
20.148062565311264, 19.994945544491593, 19.842674797722175, 19.691246081617166,
19.540655189032883, 19.390897948579052, 19.24197022413874, 19.093867914397137,
18.946586952378723, 18.800123304992951, 18.65447297258774, 18.509631988511174,
18.365596418680774, 18.222362361160471, 18.079925945744939, 17.938283333551155,
17.797430716617058, 17.657364317507188, 17.518080388925057, 17.379575213332181,
17.2418451025735, 17.10488639750934, 16.968695467653411, 16.833268710816967,
16.698602552758871, 16.564693446841588, 16.431537873692712, 16.29913234087222,
16.167473382545097, 16.036557559159384, 15.906381457129434, 15.776941688524289,
15.648234890761017, 15.5202577263032, 15.393006882363963, 15.266479070613912,
15.140671026893635, 15.015579510930749, 14.891201306061447, 14.76753321895626,
14.64457207935024, 14.522314739777308, 14.400758075308573, 14.279898983294856,
14.15973438311304, 14.04026121591631, 13.921476444388254, 13.803377052500558,
13.685960045274456, 13.569222448545773, 13.453161308733314, 13.337773692610931,
13.223056687082789, 13.109007398962021, 12.995622954752648, 12.88290050043463,
12.770837201252121, 12.659430241504744, 12.54867682434196, 12.438574171560269,
12.329119523403456, 12.220310138365626, 12.112143292997047, 12.004616281712728,
11.897726416603753, 11.791471027251255, 11.685847460542931, 11.580853080492211,
11.476485268059868, 11.372741420978159, 11.269618953577364, 11.167115296614696,
11.065227897105544, 10.96395421815712, 10.863291738804186, 10.763237953847216,
10.663790373692542, 10.564946524194788, 10.466703946501369, 10.369060196899042,
10.272012846662506, 10.175559481905047, 10.079697703431094, 9.9844251265907573,
9.8897393811362591, 9.79563811108018, 9.7021189745557166, 9.6091796436784946,
9.5168178044104081, 9.4250311564250566, 9.3338174129749802, 9.2431743007605434,
9.1530995598005447, 9.0635909433043977, 8.9746462175459669, 8.8862631617390093,
8.7984395679141443, 8.7111732407973363, 8.6244619976899912, 8.5383036683504301,
8.4526960948768988, 8.3676371315920051, 8.2831246449285345, 8.1991565133167228,
8.1157306270728924, 8.0328448882894179, 7.950497210726013, 7.8686855197024101,
7.7874077519922196, 7.7066618557181954, 7.6264457902485816, 7.5467575260949076,
7.46759504481075, 7.3889563388919584, 7.3108394116778612, 7.2332422772536802,
7.1561629603541661, 7.0795994962682585, 7.0035499307449385, 6.9280123199001196,
6.8529847301246321, 6.7784652379933164, 6.704451930175054, 6.6309429033439926,
6.5579362640916088, 6.4854301288398801, 6.4134226237554799, 6.3419118846648388,
6.2708960569702015, 6.2003732955666919, 6.13034176476026, 6.0607996381865235,
5.9917450987305756, 5.9231763384476608, 5.8550915584847019, 5.7874889690027516,
5.7203667891002965, 5.6537232467373286, 5.5875565786603545, 5.5218650303282146,
5.4566468558385992, 5.3919003178555442, 5.3276236875375673, 5.2638152444666559,
5.2004732765780375, 5.1375960800906597, 5.0751819594384671, 5.0132292272023875,
4.9517362040430868, 4.8907012186343763, 4.8301226075974313, 4.7699987154356336,
4.7103278944701543, 4.6511085047761753, 4.5923389141198783, 4.5340174978960022,
4.4761426390661114, 4.4187127280975602, 4.3617261629030111, 4.3051813487806925,
4.2490766983551964, 4.1934106315189581, 4.1381815753743894, 4.083387964176481,
4.0290282392762009, 3.9751008490643756, 3.9216042489160969, 3.8685369011359541,
3.8158972749035485, 3.7636838462198483, 3.7118950978538834, 3.6605295192902503,
3.6095856066769159, 3.5590618627737172, 3.5089567969014865, 3.459268924891532,
3.4099967690357857, 3.3611388580374211, 3.3126937269621095, 3.2646599171896327,
3.2170359763661907, 3.1698204583570941, 3.1230119232000959, 3.0766089370590919,
3.0306100721785043, 2.9850139068379775, 2.9398190253077416, 2.8950240178044737,
2.850627480447443, 2.806628015215523, 2.7630242299043033, 2.7198147380840112,
2.6769981590577743, 2.6345731178203806, 2.5925382450176073, 2.5508921769059896,
2.5096335553130018, 2.4687610275979921, 2.4282732466132586, 2.3881688706659077,
2.3484465634801097, 2.3091049941597959, 2.2701428371518944, 2.2315587722102066,
2.1933514843594821, 2.1555196638603178, 2.1180620061744122, 2.0809772119303602,
2.044263986889959, 2.0079210419150257, 1.9719470929348972, 1.9363408609142141,
1.9011010718214578, 1.8662264565980138, 1.8317157511276463, 1.7975676962067695,
1.7637810375151162, 1.7303545255871171, 1.6972869157838062, 1.6645769682653793,
1.6322234479644209, 1.600225124559671, 1.5685807724505452, 1.5372891707322935,
1.5063491031719138, 1.4757593581846322, 1.4455187288112512, 1.415626012696265,
1.3860800120666283, 1.3568795337114778, 1.3280233889625492, 1.299510393675547,
1.2713393682124234, 1.2435091374244962, 1.2160185306365605, 1.1888663816321099,
1.1620515286393669, 1.1355728143186639, 1.1094290857507758, 1.0836191944264897,
1.0581419962373957, 1.0329963514680713, 1.0081811247894592, 0.98369518525379362,
0.95953740629100537, 0.93570666570664685, 0.91220184568156526,
0.88902183277323843, 0.86616551791898644, 0.84363179644121544,
0.8214195680545231, 0.79952773687524825, 0.77795521143309543,
0.75670090468538831, 0.73576373403382433, 0.71514262134404305,
0.69483649296819294, 0.67484427977055361, 0.65516491715656855,
0.63579734510548747, 0.61674050820678872, 0.59799335570073708,
0.5795548415233327, 0.56142392435602062, 0.54359956768044526,
0.52608073983857651, 0.50886641409891809, 0.49195556872882662,
0.47534718707383661, 0.45904025764430401, 0.44303377421006473,
0.42732673590377601, 0.41191814733367949, 0.39680701870663881,
0.3819923659622475, 0.36747321091914387, 0.35324858143458471,
0.33931751157857093, 0.32567904182380403, 0.31233221925309351,
0.29927609778613373, 0.28650973842709959, 0.27403220953586072,
0.2618425871248462, 0.249939955184459, 0.23832340604035096, 0.22699204074594093,
0.21594496951431097, 0.20518131219428426, 0.19470019879589984,
0.18450077007139498, 0.17458217815898536, 0.16494358729745784,
0.15558417462116836, 0.14650313104677082, 0.13769966226439578,
0.12917298984898196, 0.1209223525096661, 0.11294700749898823,
0.10524623220777585, 0.097819325976502114, 0.090665612161046738,
0.083784440498135382, 0.077175189826974133, 0.070837271236015908,
0.06477013172140289, 0.058973258465570666, 0.053446183874029884,
0.048188491547080048, 0.043199823416500749, 0.038479888349584712,
0.034028472624342498, 0.029845452823252572, 0.025930811902384221,
0.022284659501806914, 0.018907258035667951, 0.015799056841899528,
0.012960737875857831, 0.010393278474950307, 0.0080980403534454126,
0.0060769008473329222, 0.0043324563888944567, 0.0028683594607912255,
0.0016899300575801135, 0.00080542859207355377, 0.00022941612695603908,
0, 0
), npv = c(
NaN, NaN, 0.85145739600788517, 0.85685745448893702,
0.85886517208861901, 0.85973307003460131, 0.86006533708012345,
0.8601014387410898, 0.85995707134118915, 0.85969543453700592,
0.85935408419453285, 0.85895675239676628, 0.85851915470078199,
0.85805208800817734, 0.85756319260209701, 0.85705800735303972,
0.85654062894915894, 0.85601413858613173, 0.85548088657261345,
0.85494268713431587, 0.85440095477911415, 0.85385680165121758,
0.85331110825307888, 0.85276457562067576, 0.85221776435162555,
0.85167112416389235, 0.85112501653514905, 0.85057973221970395,
0.85003550492789504, 0.84949252209912474, 0.84895093345170336,
0.84841085781640568, 0.84787238863379932, 0.84733559840306971,
0.84680054230210844, 0.84626726114814677, 0.84573578383032333,
0.84520612931692896, 0.84467830831819801, 0.84415232466871504,
0.84362817648050525, 0.84310585710772268, 0.84258535595591533,
0.84206665916256229, 0.8415497501706084, 0.84103461021273651,
0.8405212187209522, 0.84000955367347685, 0.83949959188886936,
0.8389913092756206, 0.8384846810440717, 0.83797968188638938,
0.83747628612939951, 0.83697446786431151, 0.83647420105673731,
0.83597545963987197, 0.83547821759327534, 0.83498244900931318,
0.83448812814901874, 0.83399522948887161, 0.83350372775977255,
0.83301359797930996, 0.83252481547825508, 0.83203735592209482,
0.8315511953282898, 0.83106631007986076, 0.83058267693581356,
0.83010027303884792, 0.82961907592073381, 0.82913906350568933,
0.82866021411204516, 0.82818250645244595, 0.82770591963280615,
0.82723043315020373, 0.82675602688988048, 0.82628268112148473,
0.82581037649468159, 0.82533909403423844, 0.82486881513467614,
0.82439952155456664, 0.82393119541054871, 0.82346381917111899,
0.82299737565025355, 0.82253184800090384, 0.82206721970840746,
0.82160347458384542, 0.8211405967573765, 0.8206785706715749,
0.82021738107478948, 0.81975701301454496, 0.81929745183100133,
0.81883868315048169, 0.81838069287908255, 0.81792346719637399,
0.81746699254919819, 0.81701125564557098, 0.81655624344869426,
0.81610194317107954, 0.81564834226878857, 0.81519542843579129,
0.81474318959844483, 0.81429161391008964, 0.81384068974577062,
0.81339040569707444, 0.81294075056709103, 0.81249171336549064,
0.81204328330372122, 0.81159544979032183, 0.81114820242635099,
0.81070153100092834, 0.81025542548688867, 0.80980987603654397,
0.80936487297755455, 0.8089204068089042, 0.80847646819697871,
0.8080330479717458, 0.8075901371230334, 0.80714772679690305,
0.80670580829211946, 0.80626437305670995, 0.80582341268461399,
0.80538291891242086, 0.80494288361618993, 0.80450329880835625,
0.80406415663471598, 0.80362544937148861, 0.80318716942245849,
0.80274930931618804, 0.80231186170330515, 0.8018748193538594,
0.8014381751547478, 0.80100192210720644, 0.80056605332436748,
0.80013056202887711, 0.79969544155057803, 0.79926068532424743,
0.79882628688739554, 0.79839223987811947, 0.79795853803301053,
0.79752517518511634, 0.79709214526195349, 0.79665944228356944,
0.79622706036065505, 0.79579499369270268, 0.795363236566211,
0.79493178335293424, 0.79450062850817493, 0.79406976656911887,
0.79363919215321066, 0.79320889995657007, 0.79277888475244584,
0.7923491413897078, 0.79191966479137632, 0.7914904499531854,
0.79106149194218334, 0.79063278589536312, 0.79020432701832932,
0.78977611058399422, 0.78934813193130626, 0.78892038646400819,
0.78849286964942367, 0.78806557701727398, 0.78763850415852077,
0.78721164672423727, 0.78678500042450406, 0.7863585610273317,
0.7859323243576074, 0.78550628629606678, 0.78508044277828781,
0.7846547897937084, 0.78422932338466633, 0.78380403964546086,
0.78337893472143494, 0.78295400480807842, 0.78252924615015151,
0.78210465504082693, 0.78168022782085234, 0.78125596087772897,
0.78083185064491178, 0.78040789360102303, 0.77998408626908711,
0.77956042521577862, 0.77913690705068817, 0.7787135284256046,
0.77829028603381156, 0.77786717660939964, 0.77744419692659228,
0.77702134379908816, 0.77659861407941433, 0.77617600465829684,
0.77575351246404012, 0.77533113446192348, 0.77490886765360734,
0.77448670907655337, 0.77406465580345574, 0.77364270494168419,
0.77322085363273951, 0.77279909905171884, 0.77237743840679174,
0.77195586893868895, 0.77153438792019946, 0.77111299265567768,
0.77069168048056225, 0.77027044876090245, 0.76984929489289611,
0.76942821630243408, 0.76900721044465625, 0.76858627480351538,
0.76816540689134838, 0.76774460424845836, 0.76732386444270184,
0.7669031850690875, 0.76648256374937906, 0.76606199813170872,
0.76564148589019643, 0.76522102472457709, 0.76480061235983454,
0.7643802465458428, 0.76395992505701393, 0.76353964569195321,
0.76311940627311903, 0.76269920464649144, 0.76227903868124547,
0.76185890626943098, 0.76143880532565844, 0.76101873378679019,
0.76059868961163835, 0.76017867078066703, 0.75975867529570129,
0.75933870117963997, 0.75891874647617541, 0.75849880924951718,
0.75807888758412101, 0.75765897958442252, 0.75723908337457635,
0.75681919709819878, 0.7563993189181174, 0.75597944701612152,
0.75555957959272058, 0.75513971486690457, 0.75471985107591033,
0.75429998647499041, 0.75388011933718646, 0.75346024795310829,
0.75304037063071383, 0.75262048569509521, 0.75220059148826823,
0.75178068636896433, 0.75136076871242707, 0.75094083691021263,
0.75052088936999217, 0.75010092451535937, 0.74968094078563996,
0.74926093663570481, 0.74884091053578683, 0.74842086097130023,
0.74800078644266321, 0.74758068546512335, 0.74716055656858671,
0.74674039829744832, 0.74632020921042774, 0.74589998788040468,
0.74547973289425984, 0.7450594428527173, 0.74463911637018843,
0.74421875207462096, 0.74379834860734861, 0.74337790462294306,
0.74295741878907018, 0.74253688978634647, 0.74211631630819941,
0.74169569706072946, 0.74127503076257417, 0.7408543161447747,
0.74043355195064509, 0.74001273693564262, 0.73959186986724057,
0.73917094952480378, 0.73874997469946535, 0.73832894419400574,
0.73790785682273341, 0.73748671141136823, 0.73706550679692562,
0.73664424182760369, 0.73622291536267115, 0.73580152627235795,
0.73538007343774658, 0.73495855575066626, 0.73453697211358804,
0.73411532143952163, 0.73369360265191441, 0.73327181468455138,
0.73284995648145657, 0.7324280269967971, 0.73200602519478741,
0.73158395004959609, 0.73116180054525304, 0.73073957567555925,
0.7303172744439973, 0.72989489586364353, 0.72947243895708092,
0.72904990275631443, 0.72862728630268703, 0.7282045886467966,
0.72778180884841492, 0.72735894597640804, 0.72693599910865636,
0.72651296733197801, 0.72608984974205182, 0.72566664544334192,
0.72524335354902447, 0.72481997318091396, 0.72439650346939122,
0.72397294355333308, 0.72354929258004264, 0.72312554970518039,
0.7227017140926969, 0.72227778491476591, 0.72185376135171919,
0.72142964259198161, 0.72100542783200794, 0.72058111627621968,
0.72015670713694357, 0.71973219963435142, 0.71930759299639946,
0.71888288645876963, 0.71845807926481142, 0.71803317066548522,
0.71760815991930504, 0.71718304629228358, 0.71675782905787755,
0.71633250749693345, 0.71590708089763466, 0.71548154855544888,
0.71505590977307687, 0.71463016386040135, 0.7142043101344373,
0.71377834791928196, 0.71335227654606692, 0.71292609535290963,
0.71249980368486598, 0.71207340089388493, 0.71164688633876061,
0.7112202593850887, 0.71079351940522117, 0.71036666577822172,
0.70993969788982336, 0.70951261513238484, 0.7090854169048485,
0.70865810261269901, 0.70823067166792142, 0.70780312348896135,
0.70737545750068487, 0.70694767313433804, 0.70651976982750953,
0.70609174702409028, 0.7056636041742369, 0.70523534073433303,
0.70480695616695288, 0.70437844994082455, 0.70394982153079322,
0.70352107041778589, 0.70309219608877516, 0.70266319803674571,
0.70223407576065766, 0.70180482876541417, 0.70137545656182554,
0.70094595866657727, 0.70051633460219609, 0.70008658389701672,
0.69965670608514952, 0.69922670070644777, 0.69879656730647577,
0.69836630543647693, 0.69793591465334159, 0.69750539451957594,
0.69707474460327068, 0.69664396447806975, 0.69621305372313946,
0.69578201192313738, 0.69535083866818215, 0.6949195335538223,
0.69448809618100582, 0.69405652615604996, 0.69362482309061035,
0.69319298660165107, 0.69276101631141362, 0.69232891184738643,
0.69189667284227507, 0.69146429893397054, 0.69103178976551904,
0.69059914498509123, 0.69016636424595068, 0.6897334472064226,
0.68930039352986261, 0.68886720288462477, 0.68843387494402908,
0.68800040938632967, 0.68756680589468133, 0.68713306415710607,
0.68669918386646045, 0.68626516472039989, 0.68583100642134465,
0.68539670867644387, 0.68496227119754005, 0.68452769370113153,
0.68409297590833518, 0.68365811754484773, 0.68322311834090677,
0.68278797803124969, 0.68235269635507301, 0.68191727305598926,
0.68148170788198337, 0.68104600058536802, 0.68061015092273658,
0.68017415865491559, 0.6797380235469157, 0.67930174536787946,
0.67886532389102916, 0.67842875889361209, 0.67799205015684316,
0.67755519746584569, 0.67711820060959071, 0.67668105938083234,
0.67624377357604148, 0.6758063429953366, 0.67536876744241103,
0.67493104672445736, 0.67449318065208874, 0.67405516903925577,
0.67361701170316002, 0.67317870846416328, 0.67274025914569235,
0.67230166357413879, 0.67186292157875427, 0.6714240329915393,
0.67098499764712771, 0.67054581538266389, 0.6701064860376732,
0.66966700945392588, 0.6692273854752937, 0.66878761394759667,
0.66834769471844291, 0.66790762763705847, 0.66746741255410635,
0.66702704932149548, 0.66658653779217814, 0.66614587781993351,
0.66570506925913986, 0.66526411196452939, 0.66482300579093001,
0.66438175059298821, 0.6639403462248743, 0.66349879253996824,
0.66305708939052233, 0.66261523662730248, 0.66217323409920292,
0.66173108165283334, 0.66128877913207673, 0.66084632637761387,
0.66040372322641272, 0.659960969511179, 0.65951806505976318,
0.65907500969452215, 0.65863180323162929, 0.65818844548032773,
0.65774493624212338, 0.65730127530990734, 0.65685746246700583,
0.65641349748614475, 0.65596938012832251, 0.65552511014158032,
0.65508068725965785, 0.65463611120052201, 0.65419138166475177,
0.65374649833376397, 0.65330146086785801, 0.65285626890405835,
0.65241092205372619, 0.65196541989991175, 0.6515197619944072,
0.65107394785446349, 0.65062797695911501, 0.65018184874505836,
0.64973556260201226, 0.64928911786747501, 0.64884251382078206,
0.64839574967633651, 0.64794882457587055, 0.64750173757955176,
0.64705448765571294, 0.646607073668925, 0.64615949436606102,
0.6457117483599073, 0.64526383410974886, 0.6448157498981858,
0.64436749380320535, 0.64391906366420304, 0.64347045704018868,
0.6430216711577329, 0.64257270284521451, 0.64212354844840913,
0.64167420372006478, 0.64122466367223441, 0.64077492237355371,
0.64032497266195876, 0.63987480572125133, 0.63942441042499654,
0.63897377225063068, 0.63852287131006302, 0.63807167825235589,
0.63762014345455609, 0.63716814159292035, 0.63716814159292035
), ppv = c(
0.36283185840707965, 0.36283185840707965, 0.3638610940217899,
0.36503318640513022, 0.36622917609588718, 0.36743156288626455,
0.36863407942651477, 0.36983395907069327, 0.37102987525856468,
0.37222118778267033, 0.37340761422168994, 0.37458906950848397,
0.37576558114411096, 0.37693724173725374, 0.37810418128291784,
0.37926655045634061, 0.38042451032066116, 0.38157822589826601,
0.38272786213400795, 0.38387358137166228, 0.38501554180404268,
0.3861538965574281, 0.38728879319255993, 0.38842037348013791,
0.38954877335682397, 0.39067412299888049, 0.39179654697102889,
0.39291616442174965, 0.39403308930544578, 0.3951474306181556,
0.39625929263780185, 0.39736877516294128, 0.3984759737460416,
0.39958097991875002, 0.40068388140761979, 0.40178476233945432,
0.4028837034359119, 0.40398078219734124, 0.40507607307603694,
0.4061696476392519, 0.40726157472239444, 0.40835192057288783,
0.40944074898519756, 0.41052812142753942, 0.4116140971607764,
0.41269873334999513, 0.41378208516923842, 0.41486420589984296,
0.41594514702280921, 0.41702495830560604, 0.41810368788378327,
0.41918138233774555, 0.42025808676501475, 0.42133384484828468,
0.42240869891955213, 0.42348269002058614, 0.4245558579599818,
0.42562824136702243, 0.42669987774256107, 0.42777080350711671,
0.42884105404636491, 0.42991066375419085, 0.43097966607345983,
0.43204809353464935, 0.43311597779247762, 0.43418334966065192,
0.435250239144853, 0.43631667547406222, 0.43738268713033202,
0.43844830187709388, 0.43951354678608745, 0.44057844826299397,
0.44164303207184979, 0.44270732335830731, 0.44377134667181228,
0.44483512598675551, 0.44589868472265831, 0.44696204576344573,
0.44802523147585505, 0.44908826372702754, 0.45015116390132964,
0.45121395291644079, 0.45227665123874905, 0.453339278898091,
0.45440185550186718, 0.45546440024856877, 0.45652693194074229,
0.45758946899742264, 0.45865202946605921, 0.45971463103396271,
0.46077729103929371, 0.46184002648161565, 0.46290285403203468,
0.4639657900429448, 0.4650288505573974, 0.46609205131811132,
0.46715540777614412, 0.46821893509923479, 0.46928264817983756,
0.47034656164285743, 0.47141068985310414, 0.47247504692247294,
0.47353964671686843, 0.47460450286287992, 0.47566962875421992,
0.47673503755793711, 0.47780074222041108, 0.47886675547313973,
0.47993308983832855, 0.48099975763428821, 0.48206677098065009,
0.48313414180340603, 0.48420188183977975, 0.48527000264293885,
0.48633851558654884, 0.48740743186918162, 0.4884767625185783,
0.48954651839577801, 0.49061671019911202, 0.49168734846807199,
0.49275844358705778, 0.49383000578900565, 0.49490204515890601,
0.49597457163721032, 0.49704759502313495, 0.49812112497786465,
0.49919517102765776, 0.50026974256685919, 0.5013448488608222,
0.50242049904874508, 0.50349670214642217, 0.50457346704891604,
0.50565080253314987, 0.50672871726042723, 0.50780721977887622,
0.50888631852582622, 0.50996602183011586, 0.51104633791433562,
0.51212727489700793, 0.51320884079470519, 0.51429104352411026,
0.51537389090401919, 0.51645739065728846, 0.51754155041273031,
0.51862637770695452, 0.51971187998616242, 0.52079806460789058,
0.52188493884271003, 0.52297250987587784, 0.52406078480894636,
0.5251497706613304, 0.52623947437183116, 0.52732990280012315,
0.52842106272819978, 0.52951296086178412, 0.53060560383170063,
0.53169899819521416, 0.53279315043733277, 0.5338880669720798,
0.53498375414373078, 0.53608021822802177, 0.53717746543332634,
0.53827550190180296, 0.53937433371051435, 0.54047396687251914,
0.54157440733793571, 0.54267566099498155, 0.5437777336709857,
0.54488063113337704, 0.5459843590906488, 0.54708892319329971,
0.54819432903475218, 0.54930058215224853, 0.55040768802772566,
0.55151565208867015, 0.55262447970895079, 0.55373417620963261,
0.55484474685977292, 0.55595619687719566, 0.55706853142925083,
0.55818175563355366, 0.55929587455870833, 0.56041089322501347,
0.56152681660515247, 0.56264364962486635, 0.56376139716361362,
0.56488006405521274, 0.56599965508847006, 0.56712017500779466,
0.56824162851379834, 0.56936402026388222, 0.57048735487280955,
0.57161163691326589, 0.57273687091640713, 0.57386306137239484,
0.57499021273091822, 0.57611832940170737, 0.5772474157550318,
0.57837747612218993, 0.5795085147959872, 0.58064053603120269,
0.58177354404504666, 0.58290754301760717, 0.58404253709228704,
0.58517853037623069, 0.58631552694074196, 0.58745353082169383,
0.58859254601992628, 0.58973257650163835, 0.59087362619876982,
0.59201569900937578, 0.59315879879799083, 0.59430292939598861,
0.59544809460193016, 0.59659429818190735, 0.59774154386987688,
0.5988898353679879, 0.60003917634690229, 0.60118957044610921,
0.60234102127423006, 0.60349353240931958, 0.60464710739915906,
0.60580174976154333, 0.6069574629845621, 0.60811425052687429,
0.60927211581797758, 0.61043106225847144, 0.61159109322031402,
0.6127522120470752, 0.61391442205418245, 0.61507772652916193,
0.61624212873187589, 0.61740763189475167, 0.61857423922300991,
0.61974195389488484, 0.62091077906184067, 0.62208071784878471,
0.62325177335427351, 0.62442394865071749, 0.62559724678457818,
0.62677167077656437, 0.62794722362182187, 0.6291239082901201,
0.63030172772603543, 0.63148068484912889, 0.63266078255412295,
0.63384202371107168, 0.63502441116552921, 0.63620794773871503,
0.63739263622767384, 0.63857847940543522, 0.63976548002116673,
0.64095364080032668, 0.64214296444481289, 0.64333345363310723,
0.64452511102042054, 0.64571793923883025, 0.64691194089741955,
0.64810711858241232, 0.64930347485730366, 0.65050101226299217,
0.65169973331790465, 0.65289964051812355, 0.65410073633750887,
0.6553030232278183, 0.6565065036188269, 0.65771117991844363,
0.65891705451282534, 0.66012412976649071, 0.6613324080224301,
0.66254189160221599, 0.66375258280611082, 0.66496448391317153,
0.66617759718135705, 0.66739192484762933, 0.66860746912805658,
0.66982423221791354, 0.67104221629178151, 0.67226142350364615,
0.67348185598699606, 0.67470351585491883, 0.67592640520019642,
0.6771505260954005, 0.67837588059298726, 0.67960247072538982,
0.68083029850511279, 0.68205936592482375, 0.68328967495744608,
0.68452122755625144, 0.68575402565495136, 0.68698807116778859,
0.68822336598962941, 0.68945991199605594, 0.69069771104345723,
0.69193676496912271, 0.69317707559133346, 0.69441864470945747,
0.69566147410404144, 0.69690556553690775, 0.69815092075124685,
0.69939754147171529, 0.70064542940453334, 0.70189458623758194,
0.70314501364050352, 0.70439671326480247, 0.70564968674394757,
0.70690393569347665, 0.70815946171110145, 0.70941626637681732,
0.71067435125300993, 0.71193371788457049, 0.71319436779900869,
0.71445630250656822, 0.71571952350034762, 0.71698403225642271,
0.7182498302339706, 0.7195169188753977, 0.72078529960647242,
0.72205497383645922, 0.72332594295825647, 0.72459820834854127,
0.72587177136791359, 0.72714663336104701, 0.72842279565684642,
0.72970025956860496, 0.73097902639416912, 0.73225909741611084,
0.73354047390190014, 0.7348231571040873, 0.73610714826049028,
0.73739244859438569, 0.7386790593147099, 0.73996698161626429,
0.74125621667992891, 0.74254676567288214, 0.74383862974882975,
0.74513181004824069, 0.7464263076985912, 0.74772212381461833,
0.74901925949858295, 0.75031771584053963, 0.75161749391862032,
0.75291859479932588, 0.7542210195378275, 0.75552476917828215,
0.75682984475415671, 0.75813624728856777, 0.75944397779463069,
0.76075303727582222, 0.76206342672636185, 0.76337514713159871,
0.76468819946842082, 0.76600258470567983, 0.76731830380462396,
0.7686353577193602, 0.76995374739732148, 0.7712734737797643,
0.77259453780227261, 0.77391694039529535, 0.77524068248469669,
0.7765657649923251, 0.77789218883661448, 0.77921995493320173,
0.78054906419557357, 0.78187951753573193, 0.7832113158648969,
0.78454446009422663, 0.78587895113557582, 0.78721478990227634,
0.78855197730995752, 0.78989051427739221, 0.79123040172738546,
0.79257164058769269, 0.79391423179197451, 0.79525817628080409,
0.79660347500269424, 0.79795012891519101, 0.79929813898599389,
0.80064750619413194, 0.80199823153118921, 0.80335031600257734,
0.80470376062886506, 0.80605856644716867, 0.8074147345125865,
0.80877226589971607, 0.81013116170421851, 0.81149142304445698,
0.81285305106320949, 0.81421604692945382, 0.81558041184022145,
0.81694614702255319, 0.81831325373552011, 0.81968173327234473,
0.82105158696261471, 0.82242281617459678, 0.82379542231765635,
0.82516940684477436, 0.82654477125519887, 0.8279215170972013,
0.82929964597096251, 0.83067915953160298, 0.83206005949233697,
0.83344234762778824, 0.83482602577745291, 0.83621109584933229,
0.83759755982373529, 0.8389854197572606, 0.84037467778697927,
0.84176533613481253, 0.84315739711212712, 0.84455086312455163,
0.84594573667704354, 0.84734202037919892, 0.84873971695082717,
0.85013882922781958, 0.85153936016830445, 0.85294131285913166,
0.85434469052268391, 0.85574949652404342, 0.85715573437854387,
0.85856340775972106, 0.85997252050767803, 0.86138307663792557,
0.86279508035067842, 0.86420853604067949, 0.86562344830756621,
0.86703982196681584, 0.86845766206130259, 0.86987697387352969,
0.8712977629385531, 0.87272003505766116, 0.87414379631286188,
0.8755690530822231, 0.87699581205614152, 0.8784240802545954,
0.87985386504544449, 0.88128517416388985, 0.88271801573312036,
0.88415239828629721, 0.88558833078992849, 0.88702582266877239,
0.88846488383237265, 0.88990552470335027, 0.89134775624761386,
0.89279159000662212, 0.89423703813187094, 0.89568411342180188,
0.89713282936132543, 0.89858320016418625, 0.90003524081841146,
0.90148896713512605, 0.90294439580104291, 0.90440154443491738,
0.9058604316484038, 0.90732107711166032, 0.90878350162419952,
0.91024772719147717, 0.91171377710778856, 0.91318167604610501,
0.91465145015555627, 0.91612312716737665, 0.91759673651018636,
0.91907230943563145, 0.92054987915551478, 0.92202948099173121,
0.92351115254046201, 0.92499493385225329, 0.92648086762999604,
0.92796899944684497, 0.92945937798667344, 0.93095205530991121,
0.93244708714804314, 0.93394453323065385, 0.93544445764946449,
0.93694692926451772, 0.93845202215862189, 0.93995981614720103,
0.94147039735190818, 0.94298385884802149, 0.94450030139746444,
0.94601983428155634, 0.94754257625061977, 0.9490686566108919,
0.9505982164737975, 0.95213141019805303, 0.95366840706210776,
0.95520939321350784, 0.95675457395301988, 0.95830417642662213,
0.9598584528176568, 0.96141768415765994, 0.96298218490878718,
0.96455230851777751, 0.96612845420563942, 0.96771107534701128,
0.9693006899195542, 0.97089789368602242, 0.97250337703855683,
0.97411794683490527, 0.97574255516901431, 0.97737833798506024,
0.97902666801295846, 0.98068922914301293, 0.98236812398492779,
0.98406603486354471, 0.98578647507757799, 0.98753420188691543,
0.9893159417746985, 0.99114178102291661, 0.99302818117414282,
0.99500587125666473, 0.99714884401998516, NaN, NaN
), fdr = c(
0.63716814159292035,
0.63716814159292035, 0.6361389059782101, 0.63496681359486984,
0.63377082390411277, 0.63256843711373545, 0.63136592057348517,
0.63016604092930661, 0.62897012474143521, 0.62777881221732956,
0.62659238577831, 0.62541093049151608, 0.62423441885588904, 0.62306275826274626,
0.62189581871708211, 0.62073344954365928, 0.61957548967933873,
0.61842177410173393, 0.61727213786599211, 0.61612641862833761,
0.61498445819595726, 0.61384610344257196, 0.61271120680744018,
0.61157962651986209, 0.61045122664317608, 0.60932587700111951,
0.60820345302897105, 0.60708383557825041, 0.60596691069455411,
0.6048525693818444, 0.6037407073621982, 0.60263122483705878,
0.6015240262539584, 0.60041902008124992, 0.59931611859238021,
0.59821523766054574, 0.59711629656408804, 0.59601921780265865,
0.59492392692396301, 0.59383035236074821, 0.59273842527760567,
0.59164807942711228, 0.59055925101480244, 0.58947187857246053,
0.58838590283922365, 0.58730126665000482, 0.58621791483076158,
0.58513579410015715, 0.58405485297719073, 0.58297504169439385,
0.58189631211621673, 0.5808186176622544, 0.57974191323498525,
0.57866615515171527, 0.57759130108044798, 0.57651730997941375,
0.57544414204001815, 0.57437175863297751, 0.57330012225743898,
0.57222919649288317, 0.57115894595363514, 0.57008933624580904,
0.56902033392654028, 0.56795190646535065, 0.56688402220752243,
0.56581665033934803, 0.56474976085514694, 0.56368332452593772,
0.56261731286966787, 0.56155169812290606, 0.56048645321391266,
0.55942155173700603, 0.55835696792815026, 0.55729267664169257,
0.55622865332818761, 0.55516487401324455, 0.55410131527734174,
0.55303795423655422, 0.55197476852414507, 0.55091173627297241,
0.54984883609867041, 0.54878604708355916, 0.54772334876125095,
0.546660721101909, 0.54559814449813293, 0.54453559975143129,
0.54347306805925766, 0.54241053100257741, 0.54134797053394079,
0.54028536896603729, 0.53922270896070623, 0.5381599735183844,
0.53709714596796543, 0.5360342099570552, 0.5349711494426026,
0.53390794868188862, 0.53284459222385583, 0.53178106490076527,
0.53071735182016244, 0.52965343835714251, 0.5285893101468957,
0.52752495307752711, 0.52646035328313145, 0.52539549713712019,
0.52433037124578008, 0.52326496244206289, 0.52219925777958887,
0.52113324452686038, 0.52006691016167139, 0.51900024236571174,
0.51793322901934979, 0.51686585819659392, 0.51579811816022025,
0.51472999735706115, 0.51366148441345116, 0.51259256813081855,
0.51152323748142159, 0.51045348160422188, 0.50938328980088809,
0.50831265153192795, 0.50724155641294233, 0.50616999421099429,
0.50509795484109388, 0.50402542836278974, 0.502952404976865,
0.50187887502213535, 0.50080482897234213, 0.49973025743314081,
0.4986551511391778, 0.49757950095125492, 0.49650329785357783,
0.49542653295108402, 0.49434919746685008, 0.49327128273957283,
0.49219278022112378, 0.49111368147417367, 0.49003397816988414,
0.48895366208566426, 0.48787272510299201, 0.48679115920529487,
0.4857089564758898, 0.48462610909598081, 0.48354260934271148,
0.48245844958726969, 0.48137362229304542, 0.48028812001383758,
0.47920193539210942, 0.47811506115728991, 0.47702749012412227,
0.4759392151910537, 0.47485022933866966, 0.47376052562816884,
0.47267009719987685, 0.47157893727180028, 0.47048703913821582,
0.46939439616829937, 0.4683010018047859, 0.46720684956266723,
0.46611193302792031, 0.46501624585626922, 0.46391978177197829,
0.46282253456667372, 0.4617244980981971, 0.46062566628948559,
0.45952603312748086, 0.45842559266206417, 0.4573243390050184,
0.45622226632901425, 0.45511936886662291, 0.4540156409093512,
0.45291107680670023, 0.45180567096524782, 0.45069941784775153,
0.44959231197227434, 0.44848434791132979, 0.44737552029104932,
0.44626582379036728, 0.44515525314022719, 0.44404380312280439,
0.44293146857074928, 0.4418182443664464, 0.44070412544129162,
0.43958910677498642, 0.43847318339484759, 0.43735635037513365,
0.43623860283638632, 0.43511993594478732, 0.43400034491152994,
0.43287982499220529, 0.43175837148620166, 0.43063597973611772,
0.42951264512719056, 0.42838836308673417, 0.42726312908359299,
0.42613693862760521, 0.42500978726908178, 0.42388167059829257,
0.42275258424496825, 0.42162252387781002, 0.4204914852040128,
0.41935946396879731, 0.41822645595495339, 0.41709245698239278,
0.41595746290771307, 0.41482146962376937, 0.41368447305925798,
0.41254646917830617, 0.41140745398007378, 0.41026742349836171,
0.40912637380123013, 0.40798430099062427, 0.40684120120200917,
0.40569707060401139, 0.40455190539806984, 0.4034057018180926,
0.40225845613012307, 0.4011101646320121, 0.39996082365309771,
0.39881042955389073, 0.39765897872576983, 0.39650646759068031,
0.39535289260084089, 0.39419825023845673, 0.3930425370154379,
0.39188574947312571, 0.39072788418202242, 0.38956893774152851,
0.38840890677968598, 0.3872477879529248, 0.3860855779458176,
0.38492227347083796, 0.38375787126812422, 0.38259236810524844,
0.3814257607769902, 0.38025804610511516, 0.37908922093815944,
0.3779192821512154, 0.37674822664572638, 0.37557605134928257,
0.37440275321542177, 0.37322832922343557, 0.37205277637817818,
0.37087609170988001, 0.36969827227396462, 0.36851931515087105,
0.367339217445877, 0.36615797628892832, 0.36497558883447068,
0.36379205226128514, 0.36260736377232622, 0.36142152059456478,
0.36023451997883338, 0.3590463591996732, 0.35785703555518728,
0.35666654636689266, 0.35547488897957952, 0.3542820607611698,
0.35308805910258051, 0.35189288141758773, 0.35069652514269634,
0.34949898773700788, 0.34830026668209535, 0.34710035948187645,
0.34589926366249113, 0.3446969767721817, 0.34349349638117316,
0.34228882008155637, 0.3410829454871746, 0.33987587023350935,
0.33866759197756985, 0.33745810839778406, 0.33624741719388923,
0.33503551608682841, 0.33382240281864289, 0.33260807515237062,
0.33139253087194337, 0.33017576778208652, 0.32895778370821854,
0.32773857649635385, 0.32651814401300394, 0.32529648414508117,
0.32407359479980352, 0.32284947390459956, 0.3216241194070128,
0.32039752927461018, 0.31916970149488721, 0.3179406340751762,
0.31671032504255392, 0.31547877244374856, 0.3142459743450487,
0.31301192883221146, 0.31177663401037059, 0.31054008800394406,
0.30930228895654277, 0.30806323503087729, 0.3068229244086666,
0.30558135529054248, 0.30433852589595856, 0.30309443446309231,
0.3018490792487532, 0.30060245852828471, 0.29935457059546666,
0.29810541376241806, 0.29685498635949642, 0.29560328673519753,
0.29435031325605249, 0.29309606430652341, 0.29184053828889861,
0.29058373362318274, 0.28932564874699007, 0.28806628211542951,
0.28680563220099131, 0.28554369749343178, 0.28428047649965238,
0.28301596774357723, 0.28175016976602935, 0.28048308112460224,
0.27921470039352747, 0.27794502616354089, 0.27667405704174347,
0.27540179165145873, 0.27412822863208641, 0.27285336663895288,
0.27157720434315363, 0.2702997404313951, 0.26902097360583099,
0.26774090258388922, 0.26645952609809997, 0.26517684289591265,
0.26389285173950977, 0.26260755140561443, 0.26132094068529016,
0.26003301838373566, 0.25874378332007103, 0.25745323432711797,
0.2561613702511702, 0.25486818995175925, 0.25357369230140875,
0.25227787618538167, 0.25098074050141705, 0.24968228415946034,
0.24838250608137966, 0.24708140520067409, 0.24577898046217261,
0.24447523082171799, 0.24317015524584332, 0.24186375271143234,
0.24055602220536937, 0.23924696272417773, 0.23793657327363826,
0.23662485286840126, 0.23531180053157921, 0.23399741529432022,
0.23268169619537604, 0.2313646422806398, 0.23004625260267847,
0.22872652622023573, 0.22740546219772728, 0.22608305960470459,
0.22475931751530331, 0.2234342350076749, 0.22210781116338552,
0.22078004506679824, 0.21945093580442643, 0.2181204824642681,
0.21678868413510316, 0.21545553990577335, 0.21412104886442415,
0.21278521009772366, 0.21144802269004243, 0.21010948572260776,
0.20876959827261454, 0.20742835941230733, 0.20608576820802546,
0.20474182371919597, 0.20339652499730579, 0.20204987108480899,
0.20070186101400608, 0.19935249380586806, 0.19800176846881079,
0.19664968399742266, 0.19529623937113497, 0.19394143355283133,
0.19258526548741348, 0.19122773410028396, 0.18986883829578149,
0.18850857695554304, 0.18714694893679051, 0.18578395307054618,
0.18441958815977849, 0.18305385297744681, 0.18168674626447984,
0.18031826672765533, 0.17894841303738526, 0.17757718382540316,
0.17620457768234368, 0.17483059315522564, 0.17345522874480115,
0.1720784829027987, 0.17070035402903749, 0.16932084046839696,
0.167939940507663, 0.16655765237221176, 0.16517397422254707,
0.16378890415066769, 0.16240244017626468, 0.1610145802427394,
0.15962532221302073, 0.15823466386518747, 0.15684260288787286,
0.15544913687544837, 0.15405426332295649, 0.15265797962080105,
0.15126028304917286, 0.14986117077218045, 0.14846063983169552,
0.14705868714086837, 0.14565530947731611, 0.14425050347595672,
0.14284426562145619, 0.14143659224027899, 0.140027479492322,
0.13861692336207432, 0.13720491964932149, 0.13579146395932035,
0.13437655169243382, 0.13296017803318419, 0.13154233793869741,
0.13012302612647034, 0.12870223706144684, 0.1272799649423389,
0.12585620368713812, 0.12443094691777684, 0.12300418794385845,
0.12157591974540465, 0.12014613495455552, 0.11871482583611012,
0.11728198426687966, 0.11584760171370283, 0.11441166921007155,
0.11297417733122758, 0.1115351161676273, 0.11009447529664972,
0.10865224375238609, 0.10720840999337786, 0.10576296186812911,
0.10431588657819807, 0.10286717063867452, 0.1014167998358138,
0.09996475918158855, 0.098511032864873962, 0.097055604198957091,
0.095598455565082605, 0.094139568351596231, 0.092678922888339732,
0.091216498375800523, 0.089752272808522784, 0.088286222892211413,
0.086818323953895035, 0.085348549844443775, 0.083876872832623364,
0.08240326348981368, 0.08092769056436859, 0.079450120844485161,
0.077970519008268652, 0.076488847459538004, 0.075005066147746713,
0.073519132370004001, 0.07203100055315502, 0.070540622013326545,
0.069047944690088833, 0.067552912851956859, 0.066055466769346122,
0.064555542350535525, 0.063053070735482261, 0.061547977841378096,
0.060040183852798953, 0.058529602648091768, 0.057016141151978526,
0.055499698602535591, 0.053980165718443704, 0.052457423749380172,
0.050931343389108139, 0.049401783526202454, 0.047868589801946984,
0.046331592937892269, 0.044790606786492194, 0.043245426046980118,
0.041695823573377741, 0.04014154718234323, 0.038582315842340086,
0.037017815091212783, 0.035447691482222494, 0.033871545794360594,
0.032288924652988743, 0.030699310080445782, 0.029102106313977576,
0.027496622961443219, 0.02588205316509477, 0.024257444830985679,
0.022621662014939706, 0.020973331987041554, 0.019310770856987087,
0.017631876015072236, 0.015933965136455269, 0.014213524922422003,
0.012465798113084571, 0.010684058225301494, 0.0088582189770834065,
0.0069718188258572266, 0.004994128743335248, 0.0028511559800148633,
NaN, NaN
), fpr = c(
1, 1, 0.99361233179527675, 0.98665863398122211,
0.97965571136295226, 0.97267886154126681, 0.96575425620021205,
0.95889277723404376, 0.95209905429246133, 0.94537477177256757,
0.9387201082190324, 0.93213443658004369, 0.925616691974818, 0.9191655756133027,
0.91277967228425694, 0.90645751980268585, 0.90019765064415536,
0.89399861695492278, 0.88785900537765139, 0.88177744552227955,
0.87575261442181107, 0.86978323843484262, 0.86386809352492755,
0.85800600451723452, 0.85219584372445423, 0.84643652919973711,
0.84072702278686373, 0.83506632807994163, 0.82945348836629962,
0.82388758460025846, 0.81836773343790203, 0.81289308535105653,
0.80746282283061921, 0.80207615868393733, 0.79673233442728719,
0.7914306187721063, 0.78617030620208428, 0.78095071563727336,
0.77577118918084365, 0.77063109094384674, 0.76552980594328146,
0.7604667390688219, 0.75544131411371307, 0.75045297286552393,
0.74550117425267937, 0.74058539354293207, 0.7357051215901762,
0.73085986412624693, 0.7260491410945793, 0.72127248602282934,
0.71652944543176855, 0.71181957827796016, 0.70714245542791221,
0.70249765916157658, 0.69788478270321996, 0.69330342977784687,
0.68875321419148261, 0.68423375943375664, 0.67974469830134654,
0.67528567254093708, 0.67085633251046373, 0.66645633685748185,
0.66208535221360965, 0.65774305290404533, 0.65342912067124792,
0.6491432444119245, 0.64488511992653774, 0.64065444968058971,
0.63645094257699997, 0.63227431373893683, 0.62812428430250744,
0.62400058121874924, 0.6199029370644038, 0.615831089860988, 0.61178478290171268,
0.60776376458581971, 0.60376778825994526, 0.59979661206613355,
0.5958499987961563, 0.5919277157518118, 0.58802953461089125,
0.58415523129853075, 0.58030458586367706, 0.57647738236040946,
0.57267340873388473, 0.56889245671067146, 0.56513432169327116,
0.56139880265861897, 0.55768570206037993, 0.55399482573485892,
0.55032598281036016, 0.54667898561983774, 0.54305364961668312,
0.53944979329351139, 0.53586723810381254, 0.53230580838634034,
0.52876533129211545, 0.52524563671393465, 0.52174655721827312,
0.5182679279794824, 0.51480958671618193, 0.51137137362975416,
0.50795313134485742, 0.50455470485187215, 0.50117594145119893,
0.49781669069933709, 0.49447680435666996, 0.49115613633689115,
0.48785454265800199, 0.48457188139482521, 0.48130801263296974,
0.47806279842419608, 0.47483610274312482, 0.4716277914452367,
0.46843773222612106, 0.46526579458192019, 0.46211184977092801,
0.4589757707762997, 0.45585743226983277, 0.45275671057678091,
0.44967348364166138, 0.44660763099502254, 0.44355903372113659,
0.4405275744265873, 0.43751313720971718, 0.43451560763090769,
0.43153487268366264, 0.42857082076646935, 0.42562334165540805,
0.42269232647748467, 0.41977766768466773, 0.4168792590285989,
0.41399699553596114, 0.41113077348447735, 0.4082804903795253,
0.40544604493134362, 0.40262733703281284, 0.39982426773779078,
0.3970367392399895, 0.39426465485237072, 0.39150791898704784,
0.38876643713567682, 0.38604011585032305, 0.38332886272478583,
0.38063258637637187, 0.37795119642809849, 0.37528460349131865,
0.37263271914875151, 0.36999545593790961, 0.36737272733490811,
0.36476444773864647, 0.36217053245535324, 0.35959089768347952,
0.3570254604989348, 0.35447413884065282, 0.35193685149648157,
0.34941351808938326, 0.34690405906394006, 0.34440839567315418,
0.34192644996553689, 0.33945814477247582, 0.33700340369587323,
0.33456215109605125, 0.33213431207991184, 0.32971981248934867,
0.32731857888990157, 0.32493053855964904, 0.32255561947833078,
0.32019375031669683, 0.31784486042607274, 0.31550887982814024,
0.31318573920492609, 0.31087536988899078, 0.30857770385381722,
0.30629267370438917, 0.30402021266795987, 0.30176025458500055,
0.29951273390032884, 0.29727758565440965, 0.29505474547482657,
0.29284414956791727, 0.29064573471057098, 0.28845943824218223,
0.28628519805675934, 0.28412295259518117, 0.28197264083760043,
0.27983420229598976, 0.27770757700682769, 0.27559270552391912,
0.27348952891134948, 0.27139798873656784, 0.26931802706359798,
0.26724958644637142, 0.26519260992218241, 0.2631470410052601,
0.26111282368045763, 0.25908990239705199, 0.25707822206265518,
0.25507772803723294, 0.25308836612722874, 0.25111008257979084,
0.24914282407709942, 0.24718653773079247, 0.24524117107648868,
0.24330667206840362, 0.24138298907405809, 0.23947007086907635,
0.23756786663207419, 0.23567632593963073, 0.23379539876134681,
0.23192503545498433, 0.23006518676168874, 0.2282158038012877,
0.22637683806766973, 0.22454824142423746, 0.22272996609943585,
0.22092196468235326, 0.2191241901183929, 0.21733659570501418,
0.21555913508754443, 0.21379176225505503, 0.2120344315363043,
0.21028709759574493, 0.20854971542959377, 0.2068222403619645,
0.20510462804105911, 0.20339683443542, 0.20169881583024041, 0.20001052882373016,
0.19833193032353968, 0.19666297754323669, 0.19500362799883764,
0.19335383950539242, 0.1917135701736189, 0.19008277840658971,
0.18846142289646906, 0.18684946262129598, 0.18524685684181852,
0.18365356509837205, 0.18206954720780588, 0.18049476326045344,
0.17892917361714766, 0.17737273890627947, 0.17582542002089918,
0.17428717811586059, 0.17275797460500375, 0.17123777115838135,
0.16972652969952262, 0.16822421240273677, 0.16673078169045452,
0.16524620023060765, 0.1637704309340452, 0.16230343695198512,
0.16084518167350292, 0.15939562872305368, 0.15795474195802994,
0.15652248546635228, 0.15509882356409299, 0.15368372079313253,
0.15227714191884889, 0.15087905192783591, 0.1494894160256558,
0.14810819963461863, 0.14673536839159429, 0.14537088814585231,
0.14401472495693113, 0.1426668450925348, 0.14132721502645895,
0.139995801436543, 0.13867257120264942, 0.13735749140467024,
0.13605052932055806, 0.13475165242438492, 0.13346082838442352,
0.13217802506125564, 0.13090321050590359, 0.12963635295798581,
0.12837742084389647, 0.12712638277500754, 0.12588320754589444,
0.12464786413258289, 0.12342032169081962, 0.1222005495543631,
0.12098851723329629, 0.11978419441236099, 0.1185875509493115,
0.11739855687329026, 0.11621718238322232, 0.11504339784622963,
0.11387717379606555, 0.112718480931568, 0.11156729011513078,
0.1104235723711946, 0.10928729888475563, 0.10815844099989202,
0.10703697021830827, 0.10592285819789704, 0.1048160767513181,
0.10371659784459375, 0.10262439359572162, 0.10153943627330364,
0.10046169829519003, 0.099391152227141122, 0.098327770781503565,
0.097271526815901899, 0.096222393331946043, 0.095180343473953211,
0.094145350527684912, 0.093117387919098071, 0.092096429213111008,
0.091082448112383418, 0.090075418456109446, 0.089075314218826196,
0.088082109509233897, 0.087095778569030502, 0.08611629577175961,
0.085143635621670266, 0.084177772752590641, 0.083218681926813587,
0.082266338033995301, 0.081320716090065304, 0.080381791236149414,
0.079449538737504044, 0.078523933982462824, 0.077604952481393874,
0.076692569865669635, 0.075786761886647236, 0.074887504414660411,
0.073994773438021855, 0.0731085450620369, 0.072228795508028298,
0.071355501112370323, 0.070488638325534314, 0.06962818371114432,
0.068774113945042847, 0.067926405814366264, 0.067085036216630978,
0.066249982158828269, 0.065421220756529896, 0.064598729233002472,
0.063782484918331717, 0.062972465248555598, 0.062168647764807128,
0.061371010112466151, 0.060579530040319685, 0.059794185399731914,
0.059014954143822185, 0.058241814326652208, 0.057474744102422037,
0.056713721724673261, 0.055958725545502852, 0.055209734014782907,
0.05446672567939026, 0.053729679182443757, 0.052998573262549309,
0.052273386753053375, 0.051554098581303998, 0.050840687767920167,
0.050133133426068177, 0.049431414760746084, 0.048735511068076276,
0.048045401734604698, 0.047361066236608074, 0.046682484139408675,
0.046009635096695978, 0.045342498849855972, 0.044681055227308142,
0.044025284143848542, 0.04337516560000132, 0.042730679681376338,
0.042091806558034794, 0.041458526483860725, 0.040830819795940942,
0.040208666913950974, 0.039592048339547881, 0.038980944655771177,
0.038375336526448645, 0.037775204695611242, 0.037180529986913458,
0.036591293303060879, 0.036007475625244645, 0.035429058012583114,
0.034856021601569531, 0.03428834760552768, 0.033726017314072987,
0.033169012092582051, 0.032617313381668289, 0.032070902696663794,
0.031529761627109743, 0.030993871836252795, 0.030463215060548277,
0.029937773109171006, 0.029417527863533577, 0.02890246127681062,
0.028392555373471628, 0.027887792248819876, 0.027388154068540227,
0.026893623068252936, 0.026404181553075889, 0.025919811897194611,
0.025440496543439495, 0.024966218002871798, 0.024496958854376638,
0.024032701744265528, 0.023573429385886135, 0.023119124559241477,
0.022669770110616994, 0.022225348952217616, 0.021785844061813053,
0.021351238482393065, 0.020921515321832174, 0.020496657752564262,
0.020076649011267378, 0.019661472398559199, 0.01925111127870327,
0.018845549079326118, 0.018444769291146468, 0.018048755467716004,
0.017657491225172572, 0.017270960242006805, 0.016889146258841192,
0.016512033078223687, 0.016139604564435639, 0.015771844643314825,
0.015408737302094133, 0.015050266589256789, 0.014696416614408347,
0.01434717154816767, 0.014002515622075773, 0.013662433128524887,
0.013326908420708383, 0.012995925912592354, 0.012669470078910616,
0.012347525455183805, 0.012030076637763787, 0.011717108283905819,
0.011408605111868475, 0.011104551901045201, 0.010804933492126412,
0.010509734787297109, 0.010218940750469696, 0.0099325364075560918,
0.0096505068467803712, 0.0093728372190353682, 0.0090995127382856866,
0.0088305186820206716, 0.0085658403917608927, 0.0083054632736212497,
0.0080493727989351394, 0.0077975545049447925, 0.0075499939955616657,
0.0073066769422024391, 0.007067589084707171, 0.0068327162323448265,
0.0066020442649143973, 0.0063755591339487161, 0.0061532468640287385,
0.0059350935542190619, 0.0057210853796344496, 0.0055112085931477983,
0.0053054495272534252, 0.0051037945960992204, 0.0049062302977026517,
0.004712743216369053, 0.0045233200253305128, 0.0043379474896263481,
0.0041566124692518081, 0.0039793019225985438, 0.003806002910220263,
0.0036367025989560986, 0.00347138826645077, 0.0033100473061160596,
0.0031526672325824512, 0.0029992356876986648, 0.0028497404471428123,
0.0027041694277207817, 0.0025625106954361154, 0.0024247524744304139,
0.0022908831569090626, 0.0021608913141828445, 0.0020347657089828664,
0.0019124953092277686, 0.0017940693034581567, 0.0016794771181898316,
0.0015687084374860216, 0.0014617532251079979, 0.0013586017496737268,
0.0012592446133479207, 0.0011636727846963124, 0.0010718776364857519,
0.00098385098938913451, 0.00089958516279720069, 0.00081907303424411104,
0.00074230810936160019, 0.00066928460482063024, 0.00059999754745132527,
0.00053444289374426912, 0.00047261767533801624, 0.00041452017810073016,
0.00036015016531099064, 0.00030950915974725657, 0.00026260080605100544,
0.00021943134502644401, 0.00018001024827585255, 0.00014435108992993939,
0.00011247278268677885, 8.4401400657463377e-05, 6.0173005401287227e-05,
3.9838325844421263e-05, 2.3471250799711463e-05, 1.1186508223293146e-05,
3.1863350966609971e-06, 0, 0
), tpr = c(
1, 1, 0.99804305283757333,
0.99608610567514666, 0.9941291585127201, 0.99217221135029354,
0.99021526418786687, 0.9882583170254402, 0.98630136986301364,
0.98434442270058709, 0.98238747553816042, 0.98043052837573375,
0.97847358121330719, 0.97651663405088063, 0.97455968688845396,
0.97260273972602729, 0.97064579256360073, 0.96868884540117417,
0.9667318982387475, 0.96477495107632083, 0.96281800391389427,
0.96086105675146771, 0.95890410958904104, 0.95694716242661437,
0.95499021526418781, 0.95303326810176126, 0.95107632093933459,
0.94911937377690792, 0.94716242661448136, 0.9452054794520548,
0.94324853228962813, 0.94129158512720146, 0.9393346379647749,
0.93737769080234834, 0.93542074363992167, 0.93346379647749489,
0.93150684931506844, 0.92954990215264188, 0.92759295499021521,
0.92563600782778854, 0.92367906066536198, 0.92172211350293543,
0.91976516634050876, 0.91780821917808209, 0.91585127201565553,
0.91389432485322897, 0.9119373776908023, 0.90998043052837563,
0.90802348336594907, 0.90606653620352251, 0.90410958904109584,
0.90215264187866917, 0.90019569471624261, 0.89823874755381605,
0.89628180039138938, 0.89432485322896271, 0.89236790606653615,
0.8904109589041096, 0.88845401174168304, 0.88649706457925626,
0.8845401174168297, 0.88258317025440314, 0.88062622309197647,
0.8786692759295498, 0.87671232876712324, 0.87475538160469657,
0.8727984344422699, 0.87084148727984334, 0.86888454011741678,
0.86692759295499022, 0.86497064579256355, 0.86301369863013688,
0.86105675146771044, 0.85909980430528377, 0.8571428571428571,
0.85518590998043043, 0.85322896281800387, 0.85127201565557742,
0.84931506849315064, 0.84735812133072397, 0.84540117416829741,
0.84344422700587085, 0.84148727984344429, 0.83953033268101751,
0.83757338551859095, 0.83561643835616439, 0.83365949119373772,
0.83170254403131105, 0.82974559686888449, 0.82778864970645794,
0.82583170254403138, 0.8238747553816046, 0.82191780821917804,
0.81996086105675148, 0.81800391389432481, 0.81604696673189814,
0.81409001956947158, 0.81213307240704502, 0.81017612524461835,
0.80821917808219157, 0.80626223091976512, 0.80430528375733856,
0.802348336594912, 0.80039138943248522, 0.79843444227005878,
0.79647749510763211, 0.79452054794520544, 0.79256360078277877,
0.79060665362035221, 0.78864970645792565, 0.78669275929549909,
0.78473581213307231, 0.78277886497064575, 0.78082191780821919,
0.77886497064579252, 0.77690802348336585, 0.77495107632093929,
0.77299412915851273, 0.77103718199608617, 0.76908023483365939,
0.76712328767123283, 0.76516634050880639, 0.76320939334637972,
0.76125244618395294, 0.75929549902152638, 0.75733855185909993,
0.75538160469667315, 0.75342465753424648, 0.75146771037181992,
0.74951076320939336, 0.74755381604696669, 0.74559686888454002,
0.74363992172211346, 0.7416829745596869, 0.73972602739726023,
0.73776908023483356, 0.73581213307240712, 0.73385518590998045,
0.73189823874755378, 0.72994129158512711, 0.72798434442270055,
0.72602739726027399, 0.72407045009784743, 0.72211350293542065,
0.72015655577299409, 0.71819960861056753, 0.71624266144814086,
0.71428571428571419, 0.71232876712328763, 0.71037181996086107,
0.7084148727984344, 0.70645792563600773, 0.70450097847358117,
0.70254403131115462, 0.70058708414872795, 0.69863013698630128,
0.69667318982387472, 0.69471624266144816, 0.69275929549902149,
0.69080234833659482, 0.68884540117416826, 0.6868884540117417,
0.68493150684931503, 0.68297455968688836, 0.6810176125244618,
0.67906066536203524, 0.67710371819960857, 0.6751467710371819,
0.67318982387475523, 0.67123287671232879, 0.669275929549902,
0.66731898238747545, 0.66536203522504889, 0.66340508806262233,
0.66144814090019555, 0.65949119373776899, 0.65753424657534243,
0.65557729941291587, 0.6536203522504892, 0.65166340508806253,
0.64970645792563597, 0.64774951076320941, 0.64579256360078274,
0.64383561643835607, 0.64187866927592951, 0.63992172211350296,
0.63796477495107629, 0.63600782778864962, 0.63405088062622306,
0.6320939334637965, 0.63013698630136983, 0.62818003913894316,
0.6262230919765166, 0.62426614481409004, 0.62230919765166337,
0.6203522504892367, 0.61839530332681014, 0.61643835616438358,
0.61448140900195691, 0.61252446183953024, 0.61056751467710368,
0.60861056751467713, 0.60665362035225046, 0.60469667318982379,
0.60273972602739723, 0.60078277886497067, 0.598825831702544,
0.59686888454011733, 0.59491193737769077, 0.59295499021526421,
0.59099804305283754, 0.58904109589041087, 0.58708414872798431,
0.58512720156555775, 0.58317025440313108, 0.58121330724070441,
0.57925636007827785, 0.5772994129158513, 0.57534246575342463,
0.57338551859099796, 0.5714285714285714, 0.56947162426614484,
0.56751467710371817, 0.5655577299412915, 0.56360078277886494,
0.56164383561643838, 0.55968688845401171, 0.55772994129158504,
0.55577299412915848, 0.55381604696673192, 0.55185909980430525,
0.54990215264187858, 0.54794520547945202, 0.54598825831702547,
0.5440313111545988, 0.54207436399217213, 0.54011741682974557,
0.53816046966731901, 0.53620352250489234, 0.53424657534246567,
0.53228962818003911, 0.53033268101761255, 0.52837573385518588,
0.52641878669275921, 0.52446183953033265, 0.52250489236790609,
0.52054794520547942, 0.51859099804305275, 0.51663405088062619,
0.51467710371819964, 0.51272015655577297, 0.5107632093933463,
0.50880626223091974, 0.50684931506849318, 0.50489236790606651,
0.50293542074363984, 0.50097847358121328, 0.49902152641878667,
0.49706457925636005, 0.49510763209393344, 0.49315068493150682,
0.49119373776908021, 0.48923679060665359, 0.48727984344422698,
0.48532289628180036, 0.48336594911937375, 0.48140900195694714,
0.47945205479452052, 0.47749510763209391, 0.47553816046966729,
0.47358121330724068, 0.47162426614481406, 0.46966731898238745,
0.46771037181996084, 0.46575342465753422, 0.46379647749510761,
0.46183953033268099, 0.45988258317025438, 0.45792563600782776,
0.45596868884540115, 0.45401174168297453, 0.45205479452054792,
0.45009784735812131, 0.44814090019569469, 0.44618395303326808,
0.44422700587084146, 0.44227005870841485, 0.44031311154598823,
0.43835616438356162, 0.43639921722113501, 0.43444227005870839,
0.43248532289628178, 0.43052837573385516, 0.42857142857142855,
0.42661448140900193, 0.42465753424657537, 0.4227005870841487,
0.42074363992172209, 0.41878669275929548, 0.41682974559686886,
0.41487279843444225, 0.41291585127201569, 0.41095890410958907,
0.4090019569471624, 0.40704500978473579, 0.40508806262230923,
0.40313111545988256, 0.40117416829745595, 0.39921722113502939,
0.39726027397260272, 0.39530332681017616, 0.39334637964774949,
0.39138943248532287, 0.38943248532289626, 0.38747553816046965,
0.38551859099804303, 0.38356164383561642, 0.38160469667318986,
0.37964774951076319, 0.37769080234833657, 0.37573385518590996,
0.3737769080234834, 0.37181996086105673, 0.36986301369863012,
0.3679060665362035, 0.36594911937377694, 0.36399217221135027,
0.36203522504892366, 0.36007827788649704, 0.35812133072407043,
0.35616438356164382, 0.3542074363992172, 0.35225048923679059,
0.35029354207436392, 0.34833659491193741, 0.3463796477495108,
0.34442270058708419, 0.34246575342465752, 0.34050880626223096,
0.33855185909980429, 0.33659491193737767, 0.33463796477495111,
0.33268101761252444, 0.33072407045009783, 0.32876712328767127,
0.3268101761252446, 0.32485322896281799, 0.32289628180039132,
0.32093933463796476, 0.31898238747553814, 0.31702544031311153,
0.31506849315068497, 0.31311154598825836, 0.31115459882583163,
0.30919765166340507, 0.30724070450097851, 0.30528375733855184,
0.30332681017612523, 0.30136986301369861, 0.299412915851272,
0.29745596868884538, 0.29549902152641883, 0.29354207436399216,
0.2915851272015656, 0.28962818003913887, 0.28767123287671237,
0.2857142857142857, 0.28375733855185903, 0.28180039138943253,
0.27984344422700586, 0.27788649706457924, 0.27592954990215257,
0.27397260273972601, 0.27201565557729945, 0.27005870841487278,
0.26810176125244617, 0.26614481409001955, 0.264187866927593,
0.26223091976516638, 0.26027397260273977, 0.2583170254403131,
0.25636007827788648, 0.25440313111545987, 0.25244618395303331,
0.2504892367906067, 0.24853228962818005, 0.24657534246575341,
0.2446183953033268, 0.2426614481409001, 0.24070450097847362,
0.23874755381604693, 0.23679060665362034, 0.23483365949119361,
0.23287671232876717, 0.23091976516634047, 0.22896281800391383,
0.22700587084148729, 0.22504892367906071, 0.22309197651663407,
0.2211350293542074, 0.21917808219178078, 0.2172211350293542,
0.21526418786692758, 0.21330724070450094, 0.21135029354207435,
0.20939334637964774, 0.20743639921722107, 0.20547945205479451,
0.20352250489236787, 0.20156555772994122, 0.19960861056751467,
0.19765166340508805, 0.19569471624266147, 0.19373776908023482,
0.19178082191780826, 0.18982387475538162, 0.18786692759295498,
0.18590998043052842, 0.18395303326810175, 0.18199608610567519,
0.18003913894324852, 0.17808219178082194, 0.17612524461839529,
0.17416829745596865, 0.17221135029354201, 0.17025440313111548,
0.16829745596868884, 0.16634050880626222, 0.16438356164383566,
0.16242661448140899, 0.16046966731898241, 0.15851272015655576,
0.15655577299412918, 0.15459882583170251, 0.15264187866927589,
0.15068493150684936, 0.14872798434442261, 0.14677103718199611,
0.14481409001956941, 0.14285714285714282, 0.14090019569471618,
0.13894324853228959, 0.13698630136986298, 0.13502935420743636,
0.13307240704500972, 0.13111545988258316, 0.12915851272015663,
0.12720156555772999, 0.1252446183953034, 0.12328767123287671,
0.12133072407045009, 0.11937377690802352, 0.11741682974559686,
0.11545988258317025, 0.11350293542074361, 0.11154598825831699,
0.10958904109589039, 0.1076320939334638, 0.1056751467710372,
0.10371819960861053, 0.10176125244618392, 0.099804305283757389,
0.097847358121330733, 0.09589041095890416, 0.093933463796477504,
0.091976516634050862, 0.090019569471624289, 0.088062622309197675,
0.086105675146771019, 0.084148727984344446, 0.082191780821917845,
0.080234833659491259, 0.078277886497064589, 0.076320939334637947,
0.074363992172211374, 0.072407045009784773, 0.070450097847358159,
0.068493150684931517, 0.066536203522504889, 0.064579256360078302,
0.062622309197651688, 0.060665362035225066, 0.058708414872798501,
0.056751467710371865, 0.054794520547945209, 0.052837573385518657,
0.050880626223092015, 0.048923679060665401, 0.046966731898238773,
0.045009784735812165, 0.043052837573385544, 0.041095890410958923,
0.039138943248532329, 0.03718199608610568, 0.035225048923679107,
0.033268101761252479, 0.031311154598825837, 0.029354207436399233,
0.027397260273972615, 0.02544031311154599, 0.023483365949119386,
0.021526418786692772, 0.019569471624266147, 0.017612524461839554,
0.015655577299412939, 0.013698630136986308, 0.011741682974559685,
0.0097847358121330927, 0.0078277886497064766, 0.0058708414872798544,
0.0039138943248532305, 0.0019569471624266178, 0, 0
), tnr = c(
0,
0, 0.0063876682047232314, 0.013341366018777919, 0.020344288637047729,
0.02732113845873314, 0.034245743799787939, 0.041107222765956193,
0.047900945707538618, 0.054625228227432425, 0.061279891780967564,
0.067865563419956337, 0.074383308025182004, 0.080834424386697287,
0.087220327715743048, 0.093542480197314093, 0.099802349355844602,
0.10600138304507721, 0.11214099462234858, 0.11822255447772048,
0.12424738557818887, 0.13021676156515741, 0.13613190647507245,
0.14199399548276545, 0.1478041562755458, 0.15356347080026292,
0.1592729772131363, 0.16493367192005839, 0.17054651163370038,
0.17611241539974154, 0.18163226656209791, 0.1871069146489435,
0.19253717716938082, 0.19792384131606267, 0.20326766557271275,
0.20856938122789367, 0.21382969379791569, 0.21904928436272667,
0.22422881081915638, 0.2293689090561532, 0.23447019405671857,
0.23953326093117808, 0.24455868588628693, 0.24954702713447605,
0.25449882574732063, 0.25941460645706799, 0.2642948784098238,
0.26914013587375307, 0.2739508589054207, 0.27872751397717066,
0.2834705545682315, 0.28818042172203989, 0.29285754457208779,
0.29750234083842347, 0.30211521729678009, 0.30669657022215319,
0.31124678580851739, 0.31576624056624336, 0.32025530169865346,
0.32471432745906287, 0.32914366748953627, 0.3335436631425181,
0.33791464778639035, 0.34225694709595467, 0.34657087932875213,
0.3508567555880755, 0.35511488007346226, 0.35934555031941029,
0.36354905742299998, 0.36772568626106317, 0.37187571569749256,
0.37599941878125076, 0.3800970629355962, 0.38416891013901194,
0.38821521709828732, 0.39223623541418029, 0.39623221174005474,
0.40020338793386645, 0.40415000120384365, 0.4080722842481882,
0.41197046538910875, 0.4158447687014693, 0.41969541413632294,
0.42352261763959054, 0.42732659126611522, 0.43110754328932849,
0.4348656783067289, 0.43860119734138098, 0.44231429793962007,
0.44600517426514108, 0.44967401718963984, 0.45332101438016231,
0.45694635038331693, 0.46055020670648866, 0.46413276189618752,
0.46769419161365966, 0.47123466870788455, 0.47475436328606541,
0.47825344278172693, 0.48173207202051754, 0.48519041328381807,
0.48862862637024584, 0.49204686865514258, 0.49544529514812791,
0.49882405854880113, 0.50218330930066291, 0.50552319564333004,
0.50884386366310885, 0.51214545734199801, 0.51542811860517479,
0.51869198736703026, 0.52193720157580392, 0.52516389725687518,
0.5283722085547633, 0.53156226777387894, 0.53473420541807981,
0.53788815022907199, 0.5410242292237003, 0.54414256773016723,
0.54724328942321909, 0.55032651635833862, 0.55339236900497746,
0.55644096627886341, 0.5594724255734127, 0.56248686279028282,
0.56548439236909231, 0.56846512731633736, 0.57142917923353065,
0.57437665834459195, 0.57730767352251533, 0.58022233231533227,
0.5831207409714011, 0.58600300446403886, 0.58886922651552265,
0.5917195096204747, 0.59455395506865638, 0.59737266296718716,
0.60017573226220922, 0.6029632607600105, 0.60573534514762928,
0.60849208101295216, 0.61123356286432318, 0.61395988414967695,
0.61667113727521417, 0.61936741362362813, 0.62204880357190151,
0.62471539650868135, 0.62736728085124849, 0.63000454406209039,
0.63262727266509189, 0.63523555226135353, 0.63782946754464676,
0.64040910231652048, 0.6429745395010652, 0.64552586115934718,
0.64806314850351843, 0.65058648191061674, 0.65309594093605994,
0.65559160432684582, 0.65807355003446311, 0.66054185522752418,
0.66299659630412677, 0.66543784890394875, 0.66786568792008816,
0.67028018751065133, 0.67268142111009843, 0.67506946144035096,
0.67744438052166922, 0.67980624968330317, 0.68215513957392726,
0.68449112017185976, 0.68681426079507391, 0.68912463011100922,
0.69142229614618278, 0.69370732629561083, 0.69597978733204013,
0.69823974541499945, 0.70048726609967116, 0.70272241434559035,
0.70494525452517343, 0.70715585043208273, 0.70935426528942902,
0.71154056175781777, 0.71371480194324066, 0.71587704740481883,
0.71802735916239957, 0.72016579770401024, 0.72229242299317231,
0.72440729447608088, 0.72651047108865052, 0.72860201126343216,
0.73068197293640202, 0.73275041355362858, 0.73480739007781759,
0.7368529589947399, 0.73888717631954237, 0.74091009760294801,
0.74292177793734482, 0.74492227196276706, 0.74691163387277126,
0.74888991742020916, 0.75085717592290058, 0.75281346226920753,
0.75475882892351132, 0.75669332793159638, 0.75861701092594191,
0.76052992913092365, 0.76243213336792581, 0.76432367406036927,
0.76620460123865319, 0.76807496454501567, 0.76993481323831126,
0.7717841961987123, 0.77362316193233027, 0.77545175857576254,
0.77727003390056415, 0.77907803531764674, 0.7808758098816071,
0.78266340429498582, 0.78444086491245557, 0.78620823774494497,
0.7879655684636957, 0.78971290240425507, 0.79145028457040623,
0.7931777596380355, 0.79489537195894089, 0.79660316556458, 0.79830118416975959,
0.79998947117626984, 0.80166806967646032, 0.80333702245676331,
0.80499637200116236, 0.80664616049460758, 0.8082864298263811,
0.80991722159341029, 0.81153857710353094, 0.81315053737870402,
0.81475314315818148, 0.81634643490162795, 0.81793045279219412,
0.81950523673954656, 0.82107082638285234, 0.82262726109372053,
0.82417457997910082, 0.82571282188413941, 0.82724202539499625,
0.82876222884161865, 0.83027347030047738, 0.83177578759726323,
0.83326921830954548, 0.83475379976939235, 0.8362295690659548,
0.83769656304801488, 0.83915481832649708, 0.84060437127694632,
0.84204525804197006, 0.84347751453364772, 0.84490117643590701,
0.84631627920686747, 0.84772285808115111, 0.84912094807216409,
0.8505105839743442, 0.85189180036538137, 0.85326463160840571,
0.85462911185414769, 0.85598527504306887, 0.8573331549074652,
0.85867278497354105, 0.860004198563457, 0.86132742879735058,
0.86264250859532976, 0.86394947067944194, 0.86524834757561508,
0.86653917161557648, 0.86782197493874436, 0.86909678949409641,
0.87036364704201419, 0.87162257915610353, 0.87287361722499246,
0.87411679245410556, 0.87535213586741711, 0.87657967830918038,
0.8777994504456369, 0.87901148276670371, 0.88021580558763901,
0.8814124490506885, 0.88260144312670974, 0.88378281761677768,
0.88495660215377037, 0.88612282620393445, 0.887281519068432,
0.88843270988486922, 0.8895764276288054, 0.89071270111524437,
0.89184155900010798, 0.89296302978169173, 0.89407714180210296,
0.8951839232486819, 0.89628340215540625, 0.89737560640427838,
0.89846056372669636, 0.89953830170480997, 0.90060884777285888,
0.90167222921849643, 0.9027284731840981, 0.90377760666805396,
0.90481965652604679, 0.90585464947231509, 0.90688261208090193,
0.90790357078688899, 0.90891755188761658, 0.90992458154389055,
0.9109246857811738, 0.9119178904907661, 0.9129042214309695, 0.91388370422824039,
0.91485636437832973, 0.91582222724740936, 0.91678131807318641,
0.9177336619660047, 0.9186792839099347, 0.91961820876385059,
0.92055046126249596, 0.92147606601753718, 0.92239504751860613,
0.92330743013433036, 0.92421323811335276, 0.92511249558533959,
0.92600522656197815, 0.9268914549379631, 0.9277712044919717,
0.92864449888762968, 0.92951136167446569, 0.93037181628885568,
0.93122588605495715, 0.93207359418563374, 0.93291496378336902,
0.93375001784117173, 0.9345787792434701, 0.93540127076699753,
0.93621751508166828, 0.9370275347514444, 0.93783135223519287,
0.93862898988753385, 0.93942046995968032, 0.94020581460026809,
0.94098504585617782, 0.94175818567334779, 0.94252525589757796,
0.94328627827532674, 0.94404127445449715, 0.94479026598521709,
0.94553327432060974, 0.94627032081755624, 0.94700142673745069,
0.94772661324694663, 0.948445901418696, 0.94915931223207983,
0.94986686657393182, 0.95056858523925392, 0.95126448893192372,
0.9519545982653953, 0.95263893376339193, 0.95331751586059132,
0.95399036490330402, 0.95465750115014403, 0.95531894477269186,
0.95597471585615146, 0.95662483439999868, 0.95726932031862366,
0.95790819344196521, 0.95854147351613928, 0.95916918020405906,
0.95979133308604903, 0.96040795166045212, 0.96101905534422882,
0.96162466347355136, 0.96222479530438876, 0.96281947001308654,
0.96340870669693912, 0.96399252437475536, 0.96457094198741689,
0.96514397839843047, 0.96571165239447232, 0.96627398268592701,
0.96683098790741795, 0.96738268661833171, 0.96792909730333621,
0.96847023837289026, 0.9690061281637472, 0.96953678493945172,
0.97006222689082899, 0.97058247213646642, 0.97109753872318938,
0.97160744462652837, 0.97211220775118012, 0.97261184593145977,
0.97310637693174706, 0.97359581844692411, 0.97408018810280539,
0.97455950345656051, 0.9750337819971282, 0.97550304114562336,
0.97596729825573447, 0.97642657061411386, 0.97688087544075852,
0.97733022988938301, 0.97777465104778238, 0.97821415593818695,
0.97864876151760694, 0.97907848467816783, 0.97950334224743574,
0.97992335098873262, 0.9803385276014408, 0.98074888872129673,
0.98115445092067388, 0.98155523070885353, 0.981951244532284,
0.98234250877482743, 0.98272903975799319, 0.98311085374115881,
0.98348796692177631, 0.98386039543556436, 0.98422815535668517,
0.98459126269790587, 0.98494973341074321, 0.98530358338559165,
0.98565282845183233, 0.98599748437792423, 0.98633756687147511,
0.98667309157929162, 0.98700407408740765, 0.98733052992108938,
0.98765247454481619, 0.98796992336223621, 0.98828289171609418,
0.98859139488813152, 0.9888954480989548, 0.98919506650787359,
0.98949026521270289, 0.9897810592495303, 0.99006746359244391,
0.99034949315321963, 0.99062716278096463, 0.99090048726171431,
0.99116948131797933, 0.99143415960823911, 0.99169453672637875,
0.99195062720106486, 0.99220244549505521, 0.99245000600443833,
0.99269332305779756, 0.99293241091529283, 0.99316728376765517,
0.9933979557350856, 0.99362444086605128, 0.99384675313597126,
0.99406490644578094, 0.99427891462036555, 0.9944887914068522,
0.99469455047274657, 0.99489620540390078, 0.99509376970229735,
0.99528725678363095, 0.99547667997466949, 0.99566205251037365,
0.99584338753074819, 0.99602069807740146, 0.99619399708977974,
0.9963632974010439, 0.99652861173354923, 0.99668995269388394,
0.99684733276741755, 0.99700076431230134, 0.99715025955285719,
0.99729583057227922, 0.99743748930456388, 0.99757524752556959,
0.99770911684309094, 0.99783910868581716, 0.99796523429101713,
0.99808750469077223, 0.99820593069654184, 0.99832052288181017,
0.99843129156251398, 0.998538246774892, 0.99864139825032627,
0.99874075538665208, 0.99883632721530369, 0.99892812236351425,
0.99901614901061087, 0.9991004148372028, 0.99918092696575589,
0.9992576918906384, 0.99933071539517937, 0.99940000245254867,
0.99946555710625573, 0.99952738232466198, 0.99958547982189927,
0.99963984983468901, 0.99969049084025274, 0.99973739919394899,
0.99978056865497356, 0.99981998975172415, 0.99985564891007006,
0.99988752721731322, 0.99991559859934254, 0.99993982699459871,
0.99996016167415558, 0.99997652874920029, 0.99998881349177671,
0.99999681366490334, 1, 1
), fnr = c(
0, 0, 0.0019569471624267323,
0.0039138943248532912, 0.0058708414872798501, 0.0078277886497064089,
0.0097847358121331413, 0.011741682974559874, 0.013698630136986432,
0.015655577299412991, 0.01761252446183955, 0.019569471624266283,
0.021526418786692841, 0.0234833659491194, 0.025440313111545959,
0.027397260273972691, 0.02935420743639925, 0.031311154598825809,
0.033268101761252541, 0.0352250489236791, 0.037181996086105659,
0.039138943248532218, 0.04109589041095895, 0.043052837573385683,
0.045009784735812242, 0.0469667318982388, 0.048923679060665359,
0.050880626223092092, 0.052837573385518651, 0.054794520547945209,
0.056751467710371942, 0.058708414872798501, 0.060665362035225059,
0.062622309197651618, 0.064579256360078344, 0.066536203522505083,
0.068493150684931642, 0.070450097847358201, 0.07240704500978476,
0.074363992172211485, 0.076320939334638044, 0.078277886497064603,
0.080234833659491162, 0.082191780821917901, 0.08414872798434446,
0.086105675146771019, 0.088062622309197744, 0.090019569471624303,
0.091976516634050862, 0.093933463796477421, 0.09589041095890416,
0.097847358121330885, 0.099804305283757444, 0.101761252446184,
0.10371819960861056, 0.1056751467710373, 0.10763209393346386,
0.10958904109589042, 0.11154598825831698, 0.1135029354207437,
0.11545988258317026, 0.11741682974559682, 0.11937377690802356,
0.12133072407045012, 0.12328767123287668, 0.1252446183953034,
0.12720156555773013, 0.12915851272015669, 0.13111545988258325,
0.13307240704500981, 0.13502935420743636, 0.13698630136986312,
0.13894324853228948, 0.14090019569471623, 0.14285714285714296,
0.14481409001956952, 0.14677103718199608, 0.14872798434442264,
0.15068493150684936, 0.15264187866927609, 0.15459882583170265,
0.15655577299412921, 0.15851272015655576, 0.16046966731898252,
0.16242661448140908, 0.16438356164383564, 0.16634050880626236,
0.16829745596868892, 0.17025440313111548, 0.17221135029354204,
0.1741682974559686, 0.17612524461839532, 0.17808219178082188,
0.18003913894324844, 0.18199608610567516, 0.18395303326810192,
0.18590998043052848, 0.18786692759295504, 0.18982387475538159,
0.19178082191780849, 0.19373776908023488, 0.19569471624266144,
0.197651663405088, 0.19960861056751472, 0.20156555772994128,
0.20352250489236784, 0.20547945205479456, 0.20743639921722132,
0.20939334637964788, 0.21135029354207444, 0.21330724070450099,
0.21526418786692772, 0.21722113502935428, 0.21917808219178084,
0.22113502935420748, 0.22309197651663412, 0.22504892367906068,
0.22700587084148724, 0.2289628180039138, 0.23091976516634061,
0.23287671232876717, 0.23483365949119364, 0.23679060665362028,
0.23874755381604704, 0.2407045009784736, 0.24266144814090007,
0.24461839530332688, 0.24657534246575352, 0.24853228962818008,
0.25048923679060664, 0.25244618395303331, 0.25440313111546003,
0.25636007827788659, 0.25831702544031315, 0.26027397260273977,
0.26223091976516644, 0.26418786692759288, 0.26614481409001955,
0.26810176125244617, 0.27005870841487289, 0.27201565557729945,
0.27397260273972601, 0.27592954990215257, 0.27788649706457935,
0.27984344422700591, 0.28180039138943247, 0.2837573385518592,
0.28571428571428581, 0.28767123287671237, 0.28962818003913893,
0.2915851272015656, 0.29354207436399221, 0.29549902152641877,
0.29745596868884533, 0.29941291585127211, 0.30136986301369872,
0.30332681017612528, 0.30528375733855184, 0.30724070450097851,
0.30919765166340513, 0.31115459882583169, 0.31311154598825824,
0.31506849315068497, 0.31702544031311164, 0.3189823874755382,
0.32093933463796476, 0.32289628180039137, 0.32485322896281815,
0.32681017612524477, 0.32876712328767127, 0.330724070450098,
0.33268101761252455, 0.33463796477495111, 0.33659491193737767,
0.33855185909980445, 0.34050880626223101, 0.34246575342465757,
0.34442270058708413, 0.3463796477495108, 0.34833659491193747,
0.35029354207436403, 0.35225048923679059, 0.35420743639921731,
0.35616438356164393, 0.35812133072407049, 0.36007827788649704,
0.36203522504892371, 0.36399217221135033, 0.36594911937377689,
0.36790606653620345, 0.36986301369863017, 0.37181996086105684,
0.3737769080234834, 0.37573385518590996, 0.37769080234833663,
0.37964774951076335, 0.38160469667318991, 0.38356164383561647,
0.38551859099804309, 0.38747553816046976, 0.38943248532289632,
0.39138943248532287, 0.39334637964774949, 0.39530332681017621,
0.39726027397260277, 0.39921722113502933, 0.401174168297456,
0.40313111545988267, 0.40508806262230923, 0.40704500978473579,
0.40900195694716251, 0.41095890410958913, 0.41291585127201569,
0.41487279843444225, 0.41682974559686892, 0.41878669275929553,
0.42074363992172209, 0.42270058708414865, 0.42465753424657543,
0.42661448140900204, 0.4285714285714286, 0.43052837573385516,
0.43248532289628183, 0.43444227005870856, 0.43639921722113512,
0.43835616438356168, 0.44031311154598829, 0.44227005870841496,
0.44422700587084152, 0.44618395303326808, 0.44814090019569469,
0.45009784735812147, 0.45205479452054803, 0.45401174168297459,
0.4559686888454012, 0.45792563600782787, 0.45988258317025443,
0.46183953033268099, 0.46379647749510761, 0.46575342465753433,
0.46771037181996089, 0.46966731898238745, 0.47162426614481412,
0.47358121330724079, 0.47553816046966735, 0.47749510763209391,
0.47945205479452063, 0.48140900195694725, 0.48336594911937381,
0.48532289628180036, 0.48727984344422703, 0.48923679060665365,
0.49119373776908021, 0.49315068493150677, 0.49510763209393349,
0.49706457925636016, 0.49902152641878672, 0.50097847358121339,
0.50293542074363995, 0.50489236790606662, 0.50684931506849318,
0.50880626223091974, 0.51076320939334641, 0.51272015655577297,
0.51467710371819964, 0.51663405088062631, 0.51859099804305286,
0.52054794520547942, 0.52250489236790609, 0.52446183953033265,
0.52641878669275932, 0.52837573385518599, 0.53033268101761255,
0.53228962818003922, 0.53424657534246578, 0.53620352250489234,
0.53816046966731901, 0.54011741682974557, 0.54207436399217224,
0.54403131115459891, 0.54598825831702547, 0.54794520547945202,
0.54990215264187869, 0.55185909980430525, 0.55381604696673192,
0.55577299412915859, 0.55772994129158515, 0.55968688845401182,
0.56164383561643838, 0.56360078277886494, 0.56555772994129161,
0.56751467710371817, 0.56947162426614484, 0.57142857142857151,
0.57338551859099807, 0.57534246575342463, 0.5772994129158513,
0.57925636007827785, 0.58121330724070452, 0.58317025440313119,
0.58512720156555775, 0.58708414872798431, 0.58904109589041098,
0.59099804305283754, 0.59295499021526421, 0.59491193737769077,
0.59686888454011744, 0.59882583170254411, 0.60078277886497067,
0.60273972602739734, 0.6046966731898239, 0.60665362035225046,
0.60861056751467713, 0.61056751467710368, 0.61252446183953035,
0.61448140900195702, 0.61643835616438358, 0.61839530332681014,
0.62035225048923681, 0.62230919765166337, 0.62426614481409004,
0.6262230919765166, 0.62818003913894327, 0.63013698630136994,
0.6320939334637965, 0.63405088062622306, 0.63600782778864973,
0.6379647749510764, 0.63992172211350296, 0.64187866927592963,
0.64383561643835618, 0.64579256360078274, 0.6477495107632093,
0.64970645792563608, 0.65166340508806264, 0.6536203522504892,
0.65557729941291576, 0.65753424657534254, 0.6594911937377691,
0.66144814090019566, 0.66340508806262233, 0.66536203522504889,
0.66731898238747556, 0.66927592954990223, 0.67123287671232879,
0.67318982387475534, 0.67514677103718201, 0.67710371819960868,
0.67906066536203524, 0.68101761252446191, 0.68297455968688847,
0.68493150684931503, 0.6868884540117417, 0.68884540117416837,
0.69080234833659493, 0.69275929549902149, 0.69471624266144816,
0.69667318982387472, 0.6986301369863015, 0.70058708414872806,
0.70254403131115462, 0.70450097847358117, 0.70645792563600784,
0.7084148727984344, 0.71037181996086118, 0.71232876712328763,
0.7142857142857143, 0.71624266144814097, 0.71819960861056742,
0.72015655577299409, 0.72211350293542076, 0.72407045009784743,
0.72602739726027399, 0.72798434442270055, 0.72994129158512722,
0.73189823874755378, 0.73385518590998045, 0.735812133072407,
0.73776908023483367, 0.73972602739726023, 0.7416829745596869,
0.74363992172211346, 0.74559686888454002, 0.74755381604696658,
0.74951076320939336, 0.75146771037181992, 0.7534246575342467,
0.75538160469667326, 0.75733855185909993, 0.75929549902152638,
0.76125244618395305, 0.76320939334637961, 0.76516634050880639,
0.76712328767123283, 0.7690802348336595, 0.77103718199608617,
0.77299412915851273, 0.77495107632093929, 0.77690802348336585,
0.77886497064579263, 0.78082191780821919, 0.78277886497064575,
0.78473581213307242, 0.78669275929549898, 0.78864970645792576,
0.79060665362035232, 0.79256360078277888, 0.79452054794520544,
0.79647749510763211, 0.79843444227005866, 0.80039138943248522,
0.802348336594912, 0.80430528375733856, 0.80626223091976512,
0.80821917808219168, 0.81017612524461846, 0.81213307240704502,
0.81409001956947158, 0.81604696673189825, 0.81800391389432481,
0.81996086105675137, 0.82191780821917815, 0.82387475538160471,
0.82583170254403138, 0.82778864970645794, 0.82974559686888449,
0.83170254403131105, 0.83365949119373783, 0.83561643835616439,
0.83757338551859095, 0.83953033268101762, 0.84148727984344418,
0.84344422700587074, 0.84540117416829752, 0.84735812133072408,
0.84931506849315064, 0.85127201565557742, 0.85322896281800398,
0.85518590998043065, 0.85714285714285721, 0.85909980430528377,
0.86105675146771032, 0.8630136986301371, 0.86497064579256366,
0.86692759295499022, 0.86888454011741678, 0.87084148727984334,
0.87279843444227001, 0.87475538160469657, 0.87671232876712335,
0.87866927592954991, 0.88062622309197647, 0.88258317025440314,
0.8845401174168297, 0.88649706457925648, 0.88845401174168304,
0.8904109589041096, 0.89236790606653615, 0.89432485322896271,
0.89628180039138938, 0.89823874755381616, 0.9001956947162425,
0.90215264187866928, 0.90410958904109584, 0.90606653620352262,
0.90802348336594918, 0.90998043052837574, 0.9119373776908023,
0.91389432485322897, 0.91585127201565553, 0.91780821917808209,
0.91976516634050864, 0.92172211350293543, 0.92367906066536209,
0.92563600782778865, 0.92759295499021521, 0.92954990215264177,
0.93150684931506855, 0.93346379647749511, 0.93542074363992167,
0.93737769080234834, 0.9393346379647749, 0.94129158512720146,
0.94324853228962802, 0.9452054794520548, 0.94716242661448136,
0.94911937377690792, 0.9510763209393347, 0.95303326810176126,
0.95499021526418781, 0.95694716242661448, 0.95890410958904104,
0.9608610567514676, 0.96281800391389438, 0.96477495107632094,
0.9667318982387475, 0.96868884540117417, 0.97064579256360073,
0.97260273972602729, 0.97455968688845407, 0.97651663405088063,
0.97847358121330719, 0.98043052837573386, 0.98238747553816042,
0.98434442270058697, 0.98630136986301375, 0.98825831702544031,
0.99021526418786687, 0.99217221135029354, 0.9941291585127201,
0.99608610567514666, 0.99804305283757344, 1, 1
), `1-specificity` = c(
1,
1, 0.99361233179527675, 0.98665863398122211, 0.97965571136295226,
0.97267886154126681, 0.96575425620021205, 0.95889277723404376,
0.95209905429246133, 0.94537477177256757, 0.9387201082190324,
0.93213443658004369, 0.925616691974818, 0.9191655756133027, 0.91277967228425694,
0.90645751980268585, 0.90019765064415536, 0.89399861695492278,
0.88785900537765139, 0.88177744552227955, 0.87575261442181107,
0.86978323843484262, 0.86386809352492755, 0.85800600451723452,
0.85219584372445423, 0.84643652919973711, 0.84072702278686373,
0.83506632807994163, 0.82945348836629962, 0.82388758460025846,
0.81836773343790203, 0.81289308535105653, 0.80746282283061921,
0.80207615868393733, 0.79673233442728719, 0.7914306187721063,
0.78617030620208428, 0.78095071563727336, 0.77577118918084365,
0.77063109094384674, 0.76552980594328146, 0.7604667390688219,
0.75544131411371307, 0.75045297286552393, 0.74550117425267937,
0.74058539354293207, 0.7357051215901762, 0.73085986412624693,
0.7260491410945793, 0.72127248602282934, 0.71652944543176855,
0.71181957827796016, 0.70714245542791221, 0.70249765916157658,
0.69788478270321996, 0.69330342977784687, 0.68875321419148261,
0.68423375943375664, 0.67974469830134654, 0.67528567254093708,
0.67085633251046373, 0.66645633685748185, 0.66208535221360965,
0.65774305290404533, 0.65342912067124792, 0.6491432444119245,
0.64488511992653774, 0.64065444968058971, 0.63645094257699997,
0.63227431373893683, 0.62812428430250744, 0.62400058121874924,
0.6199029370644038, 0.615831089860988, 0.61178478290171268, 0.60776376458581971,
0.60376778825994526, 0.59979661206613355, 0.5958499987961563,
0.5919277157518118, 0.58802953461089125, 0.58415523129853075,
0.58030458586367706, 0.57647738236040946, 0.57267340873388473,
0.56889245671067146, 0.56513432169327116, 0.56139880265861897,
0.55768570206037993, 0.55399482573485892, 0.55032598281036016,
0.54667898561983774, 0.54305364961668312, 0.53944979329351139,
0.53586723810381254, 0.53230580838634034, 0.52876533129211545,
0.52524563671393465, 0.52174655721827312, 0.5182679279794824,
0.51480958671618193, 0.51137137362975416, 0.50795313134485742,
0.50455470485187215, 0.50117594145119893, 0.49781669069933709,
0.49447680435666996, 0.49115613633689115, 0.48785454265800199,
0.48457188139482521, 0.48130801263296974, 0.47806279842419608,
0.47483610274312482, 0.4716277914452367, 0.46843773222612106,
0.46526579458192019, 0.46211184977092801, 0.4589757707762997,
0.45585743226983277, 0.45275671057678091, 0.44967348364166138,
0.44660763099502254, 0.44355903372113659, 0.4405275744265873,
0.43751313720971718, 0.43451560763090769, 0.43153487268366264,
0.42857082076646935, 0.42562334165540805, 0.42269232647748467,
0.41977766768466773, 0.4168792590285989, 0.41399699553596114,
0.41113077348447735, 0.4082804903795253, 0.40544604493134362,
0.40262733703281284, 0.39982426773779078, 0.3970367392399895,
0.39426465485237072, 0.39150791898704784, 0.38876643713567682,
0.38604011585032305, 0.38332886272478583, 0.38063258637637187,
0.37795119642809849, 0.37528460349131865, 0.37263271914875151,
0.36999545593790961, 0.36737272733490811, 0.36476444773864647,
0.36217053245535324, 0.35959089768347952, 0.3570254604989348,
0.35447413884065282, 0.35193685149648157, 0.34941351808938326,
0.34690405906394006, 0.34440839567315418, 0.34192644996553689,
0.33945814477247582, 0.33700340369587323, 0.33456215109605125,
0.33213431207991184, 0.32971981248934867, 0.32731857888990157,
0.32493053855964904, 0.32255561947833078, 0.32019375031669683,
0.31784486042607274, 0.31550887982814024, 0.31318573920492609,
0.31087536988899078, 0.30857770385381722, 0.30629267370438917,
0.30402021266795987, 0.30176025458500055, 0.29951273390032884,
0.29727758565440965, 0.29505474547482657, 0.29284414956791727,
0.29064573471057098, 0.28845943824218223, 0.28628519805675934,
0.28412295259518117, 0.28197264083760043, 0.27983420229598976,
0.27770757700682769, 0.27559270552391912, 0.27348952891134948,
0.27139798873656784, 0.26931802706359798, 0.26724958644637142,
0.26519260992218241, 0.2631470410052601, 0.26111282368045763,
0.25908990239705199, 0.25707822206265518, 0.25507772803723294,
0.25308836612722874, 0.25111008257979084, 0.24914282407709942,
0.24718653773079247, 0.24524117107648868, 0.24330667206840362,
0.24138298907405809, 0.23947007086907635, 0.23756786663207419,
0.23567632593963073, 0.23379539876134681, 0.23192503545498433,
0.23006518676168874, 0.2282158038012877, 0.22637683806766973,
0.22454824142423746, 0.22272996609943585, 0.22092196468235326,
0.2191241901183929, 0.21733659570501418, 0.21555913508754443,
0.21379176225505503, 0.2120344315363043, 0.21028709759574493,
0.20854971542959377, 0.2068222403619645, 0.20510462804105911,
0.20339683443542, 0.20169881583024041, 0.20001052882373016, 0.19833193032353968,
0.19666297754323669, 0.19500362799883764, 0.19335383950539242,
0.1917135701736189, 0.19008277840658971, 0.18846142289646906,
0.18684946262129598, 0.18524685684181852, 0.18365356509837205,
0.18206954720780588, 0.18049476326045344, 0.17892917361714766,
0.17737273890627947, 0.17582542002089918, 0.17428717811586059,
0.17275797460500375, 0.17123777115838135, 0.16972652969952262,
0.16822421240273677, 0.16673078169045452, 0.16524620023060765,
0.1637704309340452, 0.16230343695198512, 0.16084518167350292,
0.15939562872305368, 0.15795474195802994, 0.15652248546635228,
0.15509882356409299, 0.15368372079313253, 0.15227714191884889,
0.15087905192783591, 0.1494894160256558, 0.14810819963461863,
0.14673536839159429, 0.14537088814585231, 0.14401472495693113,
0.1426668450925348, 0.14132721502645895, 0.139995801436543, 0.13867257120264942,
0.13735749140467024, 0.13605052932055806, 0.13475165242438492,
0.13346082838442352, 0.13217802506125564, 0.13090321050590359,
0.12963635295798581, 0.12837742084389647, 0.12712638277500754,
0.12588320754589444, 0.12464786413258289, 0.12342032169081962,
0.1222005495543631, 0.12098851723329629, 0.11978419441236099,
0.1185875509493115, 0.11739855687329026, 0.11621718238322232,
0.11504339784622963, 0.11387717379606555, 0.112718480931568,
0.11156729011513078, 0.1104235723711946, 0.10928729888475563,
0.10815844099989202, 0.10703697021830827, 0.10592285819789704,
0.1048160767513181, 0.10371659784459375, 0.10262439359572162,
0.10153943627330364, 0.10046169829519003, 0.099391152227141122,
0.098327770781503565, 0.097271526815901899, 0.096222393331946043,
0.095180343473953211, 0.094145350527684912, 0.093117387919098071,
0.092096429213111008, 0.091082448112383418, 0.090075418456109446,
0.089075314218826196, 0.088082109509233897, 0.087095778569030502,
0.08611629577175961, 0.085143635621670266, 0.084177772752590641,
0.083218681926813587, 0.082266338033995301, 0.081320716090065304,
0.080381791236149414, 0.079449538737504044, 0.078523933982462824,
0.077604952481393874, 0.076692569865669635, 0.075786761886647236,
0.074887504414660411, 0.073994773438021855, 0.0731085450620369,
0.072228795508028298, 0.071355501112370323, 0.070488638325534314,
0.06962818371114432, 0.068774113945042847, 0.067926405814366264,
0.067085036216630978, 0.066249982158828269, 0.065421220756529896,
0.064598729233002472, 0.063782484918331717, 0.062972465248555598,
0.062168647764807128, 0.061371010112466151, 0.060579530040319685,
0.059794185399731914, 0.059014954143822185, 0.058241814326652208,
0.057474744102422037, 0.056713721724673261, 0.055958725545502852,
0.055209734014782907, 0.05446672567939026, 0.053729679182443757,
0.052998573262549309, 0.052273386753053375, 0.051554098581303998,
0.050840687767920167, 0.050133133426068177, 0.049431414760746084,
0.048735511068076276, 0.048045401734604698, 0.047361066236608074,
0.046682484139408675, 0.046009635096695978, 0.045342498849855972,
0.044681055227308142, 0.044025284143848542, 0.04337516560000132,
0.042730679681376338, 0.042091806558034794, 0.041458526483860725,
0.040830819795940942, 0.040208666913950974, 0.039592048339547881,
0.038980944655771177, 0.038375336526448645, 0.037775204695611242,
0.037180529986913458, 0.036591293303060879, 0.036007475625244645,
0.035429058012583114, 0.034856021601569531, 0.03428834760552768,
0.033726017314072987, 0.033169012092582051, 0.032617313381668289,
0.032070902696663794, 0.031529761627109743, 0.030993871836252795,
0.030463215060548277, 0.029937773109171006, 0.029417527863533577,
0.02890246127681062, 0.028392555373471628, 0.027887792248819876,
0.027388154068540227, 0.026893623068252936, 0.026404181553075889,
0.025919811897194611, 0.025440496543439495, 0.024966218002871798,
0.024496958854376638, 0.024032701744265528, 0.023573429385886135,
0.023119124559241477, 0.022669770110616994, 0.022225348952217616,
0.021785844061813053, 0.021351238482393065, 0.020921515321832174,
0.020496657752564262, 0.020076649011267378, 0.019661472398559199,
0.01925111127870327, 0.018845549079326118, 0.018444769291146468,
0.018048755467716004, 0.017657491225172572, 0.017270960242006805,
0.016889146258841192, 0.016512033078223687, 0.016139604564435639,
0.015771844643314825, 0.015408737302094133, 0.015050266589256789,
0.014696416614408347, 0.01434717154816767, 0.014002515622075773,
0.013662433128524887, 0.013326908420708383, 0.012995925912592354,
0.012669470078910616, 0.012347525455183805, 0.012030076637763787,
0.011717108283905819, 0.011408605111868475, 0.011104551901045201,
0.010804933492126412, 0.010509734787297109, 0.010218940750469696,
0.0099325364075560918, 0.0096505068467803712, 0.0093728372190353682,
0.0090995127382856866, 0.0088305186820206716, 0.0085658403917608927,
0.0083054632736212497, 0.0080493727989351394, 0.0077975545049447925,
0.0075499939955616657, 0.0073066769422024391, 0.007067589084707171,
0.0068327162323448265, 0.0066020442649143973, 0.0063755591339487161,
0.0061532468640287385, 0.0059350935542190619, 0.0057210853796344496,
0.0055112085931477983, 0.0053054495272534252, 0.0051037945960992204,
0.0049062302977026517, 0.004712743216369053, 0.0045233200253305128,
0.0043379474896263481, 0.0041566124692518081, 0.0039793019225985438,
0.003806002910220263, 0.0036367025989560986, 0.00347138826645077,
0.0033100473061160596, 0.0031526672325824512, 0.0029992356876986648,
0.0028497404471428123, 0.0027041694277207817, 0.0025625106954361154,
0.0024247524744304139, 0.0022908831569090626, 0.0021608913141828445,
0.0020347657089828664, 0.0019124953092277686, 0.0017940693034581567,
0.0016794771181898316, 0.0015687084374860216, 0.0014617532251079979,
0.0013586017496737268, 0.0012592446133479207, 0.0011636727846963124,
0.0010718776364857519, 0.00098385098938913451, 0.00089958516279720069,
0.00081907303424411104, 0.00074230810936160019, 0.00066928460482063024,
0.00059999754745132527, 0.00053444289374426912, 0.00047261767533801624,
0.00041452017810073016, 0.00036015016531099064, 0.00030950915974725657,
0.00026260080605100544, 0.00021943134502644401, 0.00018001024827585255,
0.00014435108992993939, 0.00011247278268677885, 8.4401400657463377e-05,
6.0173005401287227e-05, 3.9838325844421263e-05, 2.3471250799711463e-05,
1.1186508223293146e-05, 3.1863350966609971e-06, 0, 0
), `1-sensitivity` = c(
0,
0, 0.0019569471624266699, 0.0039138943248533398, 0.0058708414872798986,
0.0078277886497064575, 0.0097847358121331274, 0.011741682974559797,
0.013698630136986356, 0.015655577299412915, 0.017612524461839585,
0.019569471624266255, 0.021526418786692814, 0.023483365949119372,
0.025440313111546042, 0.027397260273972712, 0.029354207436399271,
0.03131115459882583, 0.0332681017612525, 0.03522504892367917,
0.037181996086105729, 0.039138943248532287, 0.041095890410958957,
0.043052837573385627, 0.045009784735812186, 0.046966731898238745,
0.048923679060665415, 0.050880626223092085, 0.052837573385518644,
0.054794520547945202, 0.056751467710371872, 0.058708414872798542,
0.060665362035225101, 0.06262230919765166, 0.06457925636007833,
0.066536203522505111, 0.068493150684931559, 0.070450097847358117,
0.072407045009784787, 0.074363992172211457, 0.076320939334638016,
0.078277886497064575, 0.080234833659491245, 0.082191780821917915,
0.084148727984344474, 0.086105675146771032, 0.088062622309197702,
0.090019569471624372, 0.091976516634050931, 0.09393346379647749,
0.09589041095890416, 0.09784735812133083, 0.099804305283757389,
0.10176125244618395, 0.10371819960861062, 0.10567514677103729,
0.10763209393346385, 0.1095890410958904, 0.11154598825831696,
0.11350293542074374, 0.1154598825831703, 0.11741682974559686,
0.11937377690802353, 0.1213307240704502, 0.12328767123287676,
0.12524461839530343, 0.1272015655577301, 0.12915851272015666,
0.13111545988258322, 0.13307240704500978, 0.13502935420743645,
0.13698630136986312, 0.13894324853228956, 0.14090019569471623,
0.1428571428571429, 0.14481409001956957, 0.14677103718199613,
0.14872798434442258, 0.15068493150684936, 0.15264187866927603,
0.15459882583170259, 0.15655577299412915, 0.15851272015655571,
0.16046966731898249, 0.16242661448140905, 0.16438356164383561,
0.16634050880626228, 0.16829745596868895, 0.17025440313111551,
0.17221135029354206, 0.17416829745596862, 0.1761252446183954,
0.17808219178082196, 0.18003913894324852, 0.18199608610567519,
0.18395303326810186, 0.18590998043052842, 0.18786692759295498,
0.18982387475538165, 0.19178082191780843, 0.19373776908023488,
0.19569471624266144, 0.197651663405088, 0.19960861056751478,
0.20156555772994122, 0.20352250489236789, 0.20547945205479456,
0.20743639921722123, 0.20939334637964779, 0.21135029354207435,
0.21330724070450091, 0.21526418786692769, 0.21722113502935425,
0.21917808219178081, 0.22113502935420748, 0.22309197651663415,
0.22504892367906071, 0.22700587084148727, 0.22896281800391383,
0.23091976516634061, 0.23287671232876717, 0.23483365949119361,
0.23679060665362028, 0.23874755381604706, 0.24070450097847362,
0.24266144814090007, 0.24461839530332685, 0.24657534246575352,
0.24853228962818008, 0.25048923679060664, 0.25244618395303331,
0.25440313111545998, 0.25636007827788654, 0.2583170254403131,
0.26027397260273977, 0.26223091976516644, 0.26418786692759288,
0.26614481409001955, 0.26810176125244622, 0.27005870841487289,
0.27201565557729945, 0.27397260273972601, 0.27592954990215257,
0.27788649706457935, 0.27984344422700591, 0.28180039138943247,
0.28375733855185914, 0.28571428571428581, 0.28767123287671237,
0.28962818003913893, 0.2915851272015656, 0.29354207436399227,
0.29549902152641883, 0.29745596868884538, 0.29941291585127205,
0.30136986301369872, 0.30332681017612528, 0.30528375733855184,
0.30724070450097851, 0.30919765166340518, 0.31115459882583174,
0.3131115459882583, 0.31506849315068497, 0.31702544031311164,
0.3189823874755382, 0.32093933463796476, 0.32289628180039143,
0.3248532289628181, 0.32681017612524477, 0.32876712328767121,
0.330724070450098, 0.33268101761252455, 0.33463796477495111,
0.33659491193737767, 0.33855185909980445, 0.34050880626223101,
0.34246575342465757, 0.34442270058708413, 0.3463796477495108,
0.34833659491193747, 0.35029354207436403, 0.35225048923679059,
0.35420743639921726, 0.35616438356164393, 0.35812133072407049,
0.36007827788649704, 0.36203522504892371, 0.36399217221135038,
0.36594911937377694, 0.3679060665362035, 0.36986301369863017,
0.37181996086105684, 0.3737769080234834, 0.37573385518590996,
0.37769080234833663, 0.3796477495107633, 0.38160469667318986,
0.38356164383561642, 0.38551859099804309, 0.38747553816046976,
0.38943248532289632, 0.39138943248532287, 0.39334637964774954,
0.39530332681017621, 0.39726027397260277, 0.39921722113502933,
0.401174168297456, 0.40313111545988267, 0.40508806262230923,
0.40704500978473579, 0.40900195694716246, 0.41095890410958913,
0.41291585127201569, 0.41487279843444225, 0.41682974559686892,
0.41878669275929559, 0.42074363992172215, 0.4227005870841487,
0.42465753424657537, 0.42661448140900204, 0.4285714285714286,
0.43052837573385516, 0.43248532289628183, 0.4344422700587085,
0.43639921722113506, 0.43835616438356162, 0.44031311154598829,
0.44227005870841496, 0.44422700587084152, 0.44618395303326808,
0.44814090019569475, 0.45009784735812142, 0.45205479452054798,
0.45401174168297453, 0.4559686888454012, 0.45792563600782787,
0.45988258317025443, 0.46183953033268099, 0.46379647749510766,
0.46575342465753433, 0.46771037181996089, 0.46966731898238745,
0.47162426614481412, 0.47358121330724079, 0.47553816046966735,
0.47749510763209391, 0.47945205479452058, 0.48140900195694725,
0.48336594911937381, 0.48532289628180036, 0.48727984344422703,
0.4892367906066537, 0.49119373776908026, 0.49315068493150682,
0.49510763209393349, 0.49706457925636016, 0.49902152641878672,
0.50097847358121328, 0.50293542074363995, 0.50489236790606662,
0.50684931506849318, 0.50880626223091974, 0.51076320939334641,
0.51272015655577308, 0.51467710371819964, 0.51663405088062619,
0.51859099804305286, 0.52054794520547953, 0.52250489236790609,
0.52446183953033265, 0.52641878669275932, 0.52837573385518599,
0.53033268101761255, 0.53228962818003911, 0.53424657534246578,
0.53620352250489245, 0.53816046966731901, 0.54011741682974557,
0.54207436399217224, 0.54403131115459891, 0.54598825831702547,
0.54794520547945202, 0.54990215264187869, 0.55185909980430536,
0.55381604696673192, 0.55577299412915848, 0.55772994129158515,
0.55968688845401182, 0.56164383561643838, 0.56360078277886494,
0.56555772994129161, 0.56751467710371828, 0.56947162426614484,
0.5714285714285714, 0.57338551859099807, 0.57534246575342463,
0.5772994129158513, 0.57925636007827785, 0.58121330724070452,
0.58317025440313119, 0.58512720156555775, 0.58708414872798431,
0.58904109589041087, 0.59099804305283765, 0.59295499021526421,
0.59491193737769077, 0.59686888454011744, 0.59882583170254411,
0.60078277886497067, 0.60273972602739723, 0.60469667318982379,
0.60665362035225057, 0.60861056751467713, 0.61056751467710368,
0.61252446183953035, 0.61448140900195702, 0.61643835616438358,
0.61839530332681014, 0.62035225048923681, 0.62230919765166348,
0.62426614481409004, 0.6262230919765166, 0.62818003913894327,
0.63013698630136994, 0.6320939334637965, 0.63405088062622306,
0.63600782778864973, 0.6379647749510764, 0.63992172211350296,
0.64187866927592951, 0.64383561643835618, 0.64579256360078285,
0.64774951076320941, 0.64970645792563608, 0.65166340508806253,
0.6536203522504892, 0.65557729941291587, 0.65753424657534243,
0.65949119373776899, 0.66144814090019577, 0.66340508806262233,
0.66536203522504889, 0.66731898238747556, 0.66927592954990223,
0.67123287671232879, 0.67318982387475534, 0.67514677103718201,
0.67710371819960868, 0.67906066536203524, 0.6810176125244618,
0.68297455968688847, 0.68493150684931503, 0.6868884540117417,
0.68884540117416837, 0.69080234833659493, 0.69275929549902149,
0.69471624266144816, 0.69667318982387472, 0.69863013698630139,
0.70058708414872806, 0.70254403131115462, 0.70450097847358117,
0.70645792563600784, 0.7084148727984344, 0.71037181996086107,
0.71232876712328763, 0.7142857142857143, 0.71624266144814097,
0.71819960861056753, 0.72015655577299409, 0.72211350293542076,
0.72407045009784743, 0.72602739726027399, 0.72798434442270055,
0.72994129158512722, 0.73189823874755389, 0.73385518590998045,
0.735812133072407, 0.73776908023483356, 0.73972602739726023,
0.7416829745596869, 0.74363992172211346, 0.74559686888454013,
0.74755381604696669, 0.74951076320939336, 0.75146771037181992,
0.75342465753424659, 0.75538160469667326, 0.75733855185909993,
0.75929549902152638, 0.76125244618395305, 0.76320939334637972,
0.76516634050880639, 0.76712328767123283, 0.7690802348336595,
0.77103718199608617, 0.77299412915851273, 0.77495107632093929,
0.77690802348336596, 0.77886497064579263, 0.78082191780821919,
0.78277886497064575, 0.78473581213307242, 0.78669275929549909,
0.78864970645792565, 0.79060665362035221, 0.79256360078277899,
0.79452054794520555, 0.79647749510763211, 0.79843444227005878,
0.80039138943248533, 0.802348336594912, 0.80430528375733856,
0.80626223091976512, 0.80821917808219168, 0.81017612524461835,
0.81213307240704502, 0.81409001956947158, 0.81604696673189825,
0.81800391389432481, 0.81996086105675148, 0.82191780821917804,
0.82387475538160471, 0.82583170254403138, 0.82778864970645794,
0.82974559686888449, 0.83170254403131116, 0.83365949119373783,
0.83561643835616439, 0.83757338551859095, 0.83953033268101762,
0.84148727984344429, 0.84344422700587085, 0.84540117416829752,
0.84735812133072408, 0.84931506849315064, 0.85127201565557742,
0.85322896281800387, 0.85518590998043065, 0.85714285714285721,
0.85909980430528377, 0.86105675146771044, 0.86301369863013699,
0.86497064579256366, 0.86692759295499022, 0.86888454011741678,
0.87084148727984334, 0.87279843444227001, 0.87475538160469657,
0.87671232876712324, 0.87866927592954991, 0.88062622309197647,
0.88258317025440314, 0.8845401174168297, 0.88649706457925637,
0.88845401174168304, 0.8904109589041096, 0.89236790606653615,
0.89432485322896282, 0.89628180039138949, 0.89823874755381605,
0.90019569471624261, 0.90215264187866928, 0.90410958904109584,
0.90606653620352251, 0.90802348336594918, 0.90998043052837574,
0.9119373776908023, 0.91389432485322897, 0.91585127201565553,
0.9178082191780822, 0.91976516634050876, 0.92172211350293543,
0.92367906066536209, 0.92563600782778865, 0.92759295499021521,
0.92954990215264188, 0.93150684931506844, 0.93346379647749511,
0.93542074363992167, 0.93737769080234834, 0.9393346379647749,
0.94129158512720146, 0.94324853228962813, 0.9452054794520548,
0.94716242661448136, 0.94911937377690803, 0.95107632093933459,
0.95303326810176126, 0.95499021526418781, 0.95694716242661448,
0.95890410958904104, 0.96086105675146771, 0.96281800391389427,
0.96477495107632094, 0.9667318982387475, 0.96868884540117417,
0.97064579256360073, 0.9726027397260274, 0.97455968688845396,
0.97651663405088063, 0.97847358121330719, 0.98043052837573386,
0.98238747553816042, 0.98434442270058709, 0.98630136986301364,
0.98825831702544031, 0.99021526418786687, 0.99217221135029354,
0.9941291585127201, 0.99608610567514677, 0.99804305283757333,
1, 1
), `1-accuracy` = c(
0.63716814159292035, 0.63716814159292035,
0.63380816568955245, 0.63008753375192006, 0.62633553733726588,
0.62260015367795729, 0.61889805853728075, 0.61523618551157622,
0.61161748446613862, 0.60804302864513982, 0.60451293181155541,
0.60102679442794749, 0.59758393798620624, 0.59418353493868759,
0.5908246835578751, 0.58750645218607311, 0.58422790576346517,
0.58098812176377246, 0.57778619964072797, 0.57462126622544218,
0.57149247856549323, 0.56839902513715479, 0.56534012602339911,
0.56231503244026282, 0.55932302586131866, 0.55636341690450319,
0.55343554408974749, 0.55053877253896077, 0.54767249266530826,
0.54483611888216243, 0.54202908835092212, 0.53925085977929921,
0.53650091227653807, 0.53377874426855931, 0.53108387247369815,
0.52841583093818023, 0.52577417012948913, 0.52315845608518019,
0.52056826961435321, 0.51800320554882862, 0.51546287204103025,
0.51294688990561799, 0.51045489200200422, 0.50798652265501198,
0.50554143711107113, 0.50311930102751079, 0.50071978999265299,
0.49834258907456963, 0.49598739239651146, 0.49365390273716192,
0.49134183115400354, 0.48905089662820966, 0.48678082572959058,
0.48453135230023947, 0.48230221715561827, 0.48009316780192479,
0.4779039581686616, 0.47573434835541584, 0.47358410439192866,
0.47145299801060148, 0.46934080643064924, 0.46724731215316961,
0.46517230276645005, 0.4631155707608825, 0.4610769133529008,
0.45905613231739828, 0.45705303382812079, 0.45506742830556535,
0.45309913027194615, 0.45114795821282172, 0.44921373444500379,
0.44729628499039231, 0.44539543945540661, 0.44351103091570365,
0.44164289580589533, 0.4397908738139944, 0.43795480778033546,
0.436134543600734, 0.4343299301336645, 0.43254081911124576, 0.43076706505384055,
0.42900852518808408, 0.42726505936817294, 0.42553653000024572,
0.42382280196971212, 0.42212374257137708, 0.42043922144223256,
0.418769110496786, 0.41711328386480606, 0.41547161783137221,
0.41384399077912071, 0.41223028313258869, 0.41063037730455654,
0.40904415764430091, 0.40747151038767415, 0.40591232360892626,
0.40436648717419443, 0.40283389269658798, 0.40131443349279916,
0.39980800454117593, 0.39831450244119238, 0.39683382537426037,
0.39536587306582605, 0.3939105467486983, 0.39246774912755678,
0.39103738434459601, 0.38961935794625502, 0.38821357685099334,
0.38681994931806807, 0.38543838491727844, 0.38406879449963149,
0.38271109016890403, 0.3813651852540576, 0.38003099428247833,
0.3787084329540108, 0.37739741811575445, 0.37609786773759557,
0.37480970088844734, 0.37353283771317192, 0.37226719941016095,
0.37101270820954935, 0.3697692873520404, 0.36853686106832095,
0.36731535455904618, 0.36610469397537215, 0.36490480640001988,
0.36371561982885048, 0.36253706315293532, 0.36136906614110398,
0.36021155942295369, 0.35906447447230483, 0.35792774359108837,
0.35680129989365084, 0.35568507729146204, 0.35457901047821372,
0.35348303491529698, 0.35239708681764459, 0.35132110313992682,
0.35025502156309318, 0.3491987804812432, 0.3481523189888206,
0.34711557686811934, 0.34608849457709312, 0.34507101323745426,
0.34406307462306218, 0.34306462114858249, 0.3420755958584174,
0.34109594241589225, 0.34012560509269651, 0.33916452875856717,
0.33821265887120999, 0.33726994146645228, 0.33633632314861672,
0.33541175108111476, 0.3344961729772491, 0.33358953709122396,
0.33269179220935152, 0.33180288764145405, 0.33092277321245334,
0.33005139925414406, 0.32918871659714477, 0.32833467656302173,
0.32748923095658211, 0.32665233205832944, 0.32582393261708109,
0.3250039858427386, 0.32419244539921033, 0.32338926539748114,
0.32259440038882481, 0.32180780535815712, 0.32102943571752307,
0.32025924729971844, 0.31949719635203833, 0.31874323953015338,
0.31799733389210616, 0.31725943689242997, 0.31652950637638055,
0.31580750057428431, 0.31509337809599491, 0.31438709792545971,
0.31368861941538917, 0.31299790228203117, 0.31231490660004446,
0.31163959279746978, 0.31097192165079601, 0.31031185428012042,
0.30965935214439944, 0.30901437703678725, 0.30837689108006217,
0.3077468567221372, 0.30712423673165234, 0.30650899419364941,
0.3059010925053236, 0.30530049537185355, 0.30470716680230547,
0.30412107110561293, 0.30354217288662422, 0.30297043704222515,
0.30240582875752686, 0.30184831350212149, 0.30129785702640444,
0.30075442535795927, 0.30021798479800699, 0.29968850191791518,
0.29916594355576798, 0.2986502768129945, 0.29814146905105476,
0.29763948788818173, 0.29714430119617785, 0.2966558770972666,
0.29617418396099593, 0.29569919040119241, 0.29523086527296782,
0.29476917766977306, 0.29431409692050192, 0.29386559258664158,
0.2934236344594694, 0.29298819255729536, 0.29255923712274878,
0.29213673862010869, 0.29172066773267724, 0.29131099536019445,
0.29090769261629368, 0.29051073082599821, 0.29012008152325652,
0.28973571644851581, 0.28935760754633411, 0.28898572696302938,
0.28862004704436339, 0.28826054033326409, 0.28790717956757983,
0.2875599376778698, 0.28721878778522769, 0.28688370319913736,
0.2865546574153619, 0.28623162411386471, 0.28591457715675883,
0.28560349058629064, 0.28529833862285137, 0.28499909566301718,
0.28470573627761997, 0.28441823520984522, 0.28413656737335846,
0.28386070785045681, 0.28359063189025069, 0.28332631490686822,
0.28306773247768846, 0.28281486034159697, 0.28256767439726882,
0.28232615070147382, 0.28209026546740756, 0.28185999506304482,
0.28163531600951519, 0.28141620497950437, 0.28120263879567375,
0.28099459442910557, 0.28079204899776655, 0.28059497976499503,
0.28040336413800693, 0.28021717966642345, 0.28003640404081775,
0.27986101509128247, 0.27969099078601534, 0.27952630922992472,
0.27936694866325262, 0.27921288746021877, 0.27906410412767846,
0.27892057730380271, 0.27878228575677211, 0.27864920838349017,
0.27852132420831321, 0.27839861238179464, 0.27828105217944976,
0.2781686230005318, 0.27806130436682752, 0.27795907592146596,
0.27786191742774391, 0.27776980876796553, 0.27768272994229737,
0.2776006610676367, 0.27752358237649566, 0.27745147421589866,
0.27738431704629352, 0.27732209144047659, 0.27726477808253103,
0.27721235776677811, 0.27716481139674243, 0.27712211998412817,
0.27708426464780977, 0.27705122661283343, 0.2770229872094323,
0.27699952787205184, 0.27698083013838903, 0.27696687564844102,
0.27695764614356755, 0.27695312346556289, 0.27695328955573872,
0.27695812645402029, 0.27696761629804989, 0.27698174132230391,
0.27700048385721887, 0.27702382632832778, 0.27705175125540715,
0.27708424125163356, 0.27712127902275019, 0.27716284736624286,
0.27720892917052609, 0.27725950741413818, 0.27731456516494557,
0.2773740855793565, 0.27743805190154336, 0.27750644746267394,
0.27757925568015263, 0.27765646005686806, 0.27773804418045078,
0.27782399172253913, 0.27791428643805305, 0.27800891216447565,
0.27810785282114414, 0.27821109240854747, 0.27831861500763178,
0.2784304047791144, 0.27854644596280509, 0.27866672287693361,
0.27879121991748679, 0.27891992155755185, 0.27905281234666579,
0.27918987691017405, 0.27933109994859451, 0.27947646623698918,
0.27962596062434197, 0.27977956803294468, 0.27993727345778807,
0.28009906196595979, 0.28026491869604997, 0.28043482885756144,
0.28060877773032733, 0.28078675066393521, 0.28096873307715653,
0.28115471045738227, 0.28134466836006555, 0.28153859240816814,
0.28173646829161603, 0.28193828176675706, 0.28214401865582739,
0.28235366484642177, 0.28256720629097043, 0.28278462900622048,
0.28300591907272421, 0.28323106263433118, 0.28346004589768692,
0.28369285513173714, 0.28392947666723456, 0.28416989689625538,
0.28441410227171637, 0.28466207930690035, 0.28491381457498455,
0.28516929470857622, 0.2854285063992501, 0.2856914363970936,
0.2859580715102551, 0.28622839860449878, 0.286502404602762, 0.28678007648471882,
0.28706140128634883, 0.28734636609950814, 0.28763495807150874,
0.28792716440469801, 0.28822297235604744, 0.28852236923674202,
0.2888253424117766, 0.28913187929955508, 0.28944196737149541,
0.28975559415163898, 0.29007274721626253, 0.29039341419349762,
0.29071758276295134, 0.29104524065533355, 0.29137637565208807,
0.29171097558502701, 0.29204902833597146, 0.29239052183639502,
0.29273544406707208, 0.2930837830577312, 0.29343552688671137,
0.29379066368062412, 0.29414918161401971, 0.29451106890905665,
0.29487631383517687, 0.29524490470878573, 0.29561682989293403,
0.29599207779700787, 0.29637063687642007, 0.29675249563230899,
0.29713764261123887, 0.29752606640490753, 0.29791775564985767,
0.29831269902719215, 0.29871088526229617, 0.29911230312456205,
0.2995169414271206, 0.29992478902657738, 0.30033583482275295,
0.30075006775842994, 0.30116747681910405, 0.30158805103274178,
0.30201177946954294, 0.30243865124170877, 0.3028686555032164,
0.30330178144959918, 0.30373801831773295, 0.30417735538562851,
0.30461978197223127, 0.30506528743722683, 0.30551386118085389,
0.30596549264372408, 0.30642017130664956, 0.30687788669047689,
0.3073386283559314, 0.30780238590346742, 0.30826914897312718,
0.30873890724441067, 0.30921165043615195, 0.30968736830640664,
0.31016605065235003, 0.31064768731018366, 0.31113226815505446,
0.31161978310098504, 0.31211022210081585, 0.31260357514615955,
0.31309983226736926, 0.31359898353352089, 0.31410101905240939,
0.31460592897056128, 0.31511370347326262, 0.31562433278460522,
0.31613780716755036, 0.31665411692401246, 0.3171732523949623,
0.31769520396055329, 0.31821996204026959, 0.3187475170930989,
0.31927785961773281, 0.31981098015279352, 0.32034686927709, 0.32088551760990769,
0.32142691581133065, 0.3219710545826, 0.32251792466651241, 0.32306751684785906,
0.32361982195391137, 0.32417483085495236, 0.32473253446486228,
0.32529292374175978, 0.32585598968870222, 0.32642172335445407,
0.32699011583432347, 0.32756115827107746, 0.32813484185593933,
0.32871115782967797, 0.3292900974837939, 0.32987165216181502,
0.33045581326070816, 0.3310425722324204, 0.33163192058555946,
0.33222384988723019, 0.33281835176504027, 0.33341541790929208,
0.33401504007538274, 0.33461721008643119, 0.33522191983615779,
0.3358291612920461, 0.33643892649881679, 0.33705120758224916,
0.33766599675339481, 0.33828328631322768, 0.33890306865778508,
0.33952533628386539, 0.34015008179535189, 0.34077729791024747,
0.34140697746852255, 0.34203911344088644, 0.34267369893862165,
0.34331072722464084, 0.34395019172595775, 0.34459208604780089,
0.34523640398964361, 0.34588313956348471, 0.34653228701478178,
0.34718384084653697, 0.34783779584714336, 0.34849414712276183,
0.34915289013518358, 0.34981402074640444, 0.35047753527147107,
0.35114343054163843, 0.35181170398051076, 0.35248235369674319,
0.35315537859814494, 0.353830778533885, 0.35450855447422935,
0.35518870874142705, 0.35587124531192016, 0.35655617022071173,
0.35724349211680551, 0.35793322305077002, 0.35862537963619812,
0.35931998485036665, 0.36001707101613112, 0.36071668521308942,
0.3614189005422398, 0.36212384586254398, 0.36283185840707965,
0.36283185840707965
), `1-npv` = c(
NaN, NaN, 0.14854260399211483,
0.14314254551106298, 0.14113482791138099, 0.14026692996539869,
0.13993466291987655, 0.1398985612589102, 0.14004292865881085,
0.14030456546299408, 0.14064591580546715, 0.14104324760323372,
0.14148084529921801, 0.14194791199182266, 0.14243680739790299,
0.14294199264696028, 0.14345937105084106, 0.14398586141386827,
0.14451911342738655, 0.14505731286568413, 0.14559904522088585,
0.14614319834878242, 0.14668889174692112, 0.14723542437932424,
0.14778223564837445, 0.14832887583610765, 0.14887498346485095,
0.14942026778029605, 0.14996449507210496, 0.15050747790087526,
0.15104906654829664, 0.15158914218359432, 0.15212761136620068,
0.15266440159693029, 0.15319945769789156, 0.15373273885185323,
0.15426421616967667, 0.15479387068307104, 0.15532169168180199,
0.15584767533128496, 0.15637182351949475, 0.15689414289227732,
0.15741464404408467, 0.15793334083743771, 0.1584502498293916,
0.15896538978726349, 0.1594787812790478, 0.15999044632652315,
0.16050040811113064, 0.1610086907243794, 0.1615153189559283,
0.16202031811361062, 0.16252371387060049, 0.16302553213568849,
0.16352579894326269, 0.16402454036012803, 0.16452178240672466,
0.16501755099068682, 0.16551187185098126, 0.16600477051112839,
0.16649627224022745, 0.16698640202069004, 0.16747518452174492,
0.16796264407790518, 0.1684488046717102, 0.16893368992013924,
0.16941732306418644, 0.16989972696115208, 0.17038092407926619,
0.17086093649431067, 0.17133978588795484, 0.17181749354755405,
0.17229408036719385, 0.17276956684979627, 0.17324397311011952,
0.17371731887851527, 0.17418962350531841, 0.17466090596576156,
0.17513118486532386, 0.17560047844543336, 0.17606880458945129,
0.17653618082888101, 0.17700262434974645, 0.17746815199909616,
0.17793278029159254, 0.17839652541615458, 0.1788594032426235,
0.1793214293284251, 0.17978261892521052, 0.18024298698545504,
0.18070254816899867, 0.18116131684951831, 0.18161930712091745,
0.18207653280362601, 0.18253300745080181, 0.18298874435442902,
0.18344375655130574, 0.18389805682892046, 0.18435165773121143,
0.18480457156420871, 0.18525681040155517, 0.18570838608991036,
0.18615931025422938, 0.18660959430292556, 0.18705924943290897,
0.18750828663450936, 0.18795671669627878, 0.18840455020967817,
0.18885179757364901, 0.18929846899907166, 0.18974457451311133,
0.19019012396345603, 0.19063512702244545, 0.1910795931910958,
0.19152353180302129, 0.1919669520282542, 0.1924098628769666,
0.19285227320309695, 0.19329419170788054, 0.19373562694329005,
0.19417658731538601, 0.19461708108757914, 0.19505711638381007,
0.19549670119164375, 0.19593584336528402, 0.19637455062851139,
0.19681283057754151, 0.19725069068381196, 0.19768813829669485,
0.1981251806461406, 0.1985618248452522, 0.19899807789279356,
0.19943394667563252, 0.19986943797112289, 0.20030455844942197,
0.20073931467575257, 0.20117371311260446, 0.20160776012188053,
0.20204146196698947, 0.20247482481488366, 0.20290785473804651,
0.20334055771643056, 0.20377293963934495, 0.20420500630729732,
0.204636763433789, 0.20506821664706576, 0.20549937149182507,
0.20593023343088113, 0.20636080784678934, 0.20679110004342993,
0.20722111524755416, 0.2076508586102922, 0.20808033520862368,
0.2085095500468146, 0.20893850805781666, 0.20936721410463688,
0.20979567298167068, 0.21022388941600578, 0.21065186806869374,
0.21107961353599181, 0.21150713035057633, 0.21193442298272602,
0.21236149584147923, 0.21278835327576273, 0.21321499957549594,
0.2136414389726683, 0.2140676756423926, 0.21449371370393322,
0.21491955722171219, 0.2153452102062916, 0.21577067661533367,
0.21619596035453914, 0.21662106527856506, 0.21704599519192158,
0.21747075384984849, 0.21789534495917307, 0.21831977217914766,
0.21874403912227103, 0.21916814935508822, 0.21959210639897697,
0.22001591373091289, 0.22043957478422138, 0.22086309294931183,
0.2212864715743954, 0.22170971396618844, 0.22213282339060036,
0.22255580307340772, 0.22297865620091184, 0.22340138592058567,
0.22382399534170316, 0.22424648753595988, 0.22466886553807652,
0.22509113234639266, 0.22551329092344663, 0.22593534419654426,
0.22635729505831581, 0.22677914636726049, 0.22720090094828116,
0.22762256159320826, 0.22804413106131105, 0.22846561207980054,
0.22888700734432232, 0.22930831951943775, 0.22972955123909755,
0.23015070510710389, 0.23057178369756592, 0.23099278955534375,
0.23141372519648462, 0.23183459310865162, 0.23225539575154164,
0.23267613555729816, 0.2330968149309125, 0.23351743625062094,
0.23393800186829128, 0.23435851410980357, 0.23477897527542291,
0.23519938764016546, 0.2356197534541572, 0.23604007494298607,
0.23646035430804679, 0.23688059372688097, 0.23730079535350856,
0.23772096131875453, 0.23814109373056902, 0.23856119467434156,
0.23898126621320981, 0.23940131038836165, 0.23982132921933297,
0.24024132470429871, 0.24066129882036003, 0.24108125352382459,
0.24150119075048282, 0.24192111241587899, 0.24234102041557748,
0.24276091662542365, 0.24318080290180122, 0.2436006810818826,
0.24402055298387848, 0.24444042040727942, 0.24486028513309543,
0.24528014892408967, 0.24570001352500959, 0.24611988066281354,
0.24653975204689171, 0.24695962936928617, 0.24737951430490479,
0.24779940851173177, 0.24821931363103567, 0.24863923128757293,
0.24905916308978737, 0.24947911063000783, 0.24989907548464063,
0.25031905921436004, 0.25073906336429519, 0.25115908946421317,
0.25157913902869977, 0.25199921355733679, 0.25241931453487665,
0.25283944343141329, 0.25325960170255168, 0.25367979078957226,
0.25410001211959532, 0.25452026710574016, 0.2549405571472827,
0.25536088362981157, 0.25578124792537904, 0.25620165139265139,
0.25662209537705694, 0.25704258121092982, 0.25746311021365353,
0.25788368369180059, 0.25830430293927054, 0.25872496923742583,
0.2591456838552253, 0.25956644804935491, 0.25998726306435738,
0.26040813013275943, 0.26082905047519622, 0.26125002530053465,
0.26167105580599426, 0.26209214317726659, 0.26251328858863177,
0.26293449320307438, 0.26335575817239631, 0.26377708463732885,
0.26419847372764205, 0.26461992656225342, 0.26504144424933374,
0.26546302788641196, 0.26588467856047837, 0.26630639734808559,
0.26672818531544862, 0.26715004351854343, 0.2675719730032029,
0.26799397480521259, 0.26841604995040391, 0.26883819945474696,
0.26926042432444075, 0.2696827255560027, 0.27010510413635647,
0.27052756104291908, 0.27095009724368557, 0.27137271369731297,
0.2717954113532034, 0.27221819115158508, 0.27264105402359196,
0.27306400089134364, 0.27348703266802199, 0.27391015025794818,
0.27433335455665808, 0.27475664645097553, 0.27518002681908604,
0.27560349653060878, 0.27602705644666692, 0.27645070741995736,
0.27687445029481961, 0.2772982859073031, 0.27772221508523409,
0.27814623864828081, 0.27857035740801839, 0.27899457216799206,
0.27941888372378032, 0.27984329286305643, 0.28026780036564858,
0.28069240700360054, 0.28111711354123037, 0.28154192073518858,
0.28196682933451478, 0.28239184008069496, 0.28281695370771642,
0.28324217094212245, 0.28366749250306655, 0.28409291910236534,
0.28451845144455112, 0.28494409022692313, 0.28536983613959865,
0.2857956898655627, 0.28622165208071804, 0.28664772345393308,
0.28707390464709037, 0.28750019631513402, 0.28792659910611507,
0.28835311366123939, 0.2887797406149113, 0.28920648059477883,
0.28963333422177828, 0.29006030211017664, 0.29048738486761516,
0.2909145830951515, 0.29134189738730099, 0.29176932833207858,
0.29219687651103865, 0.29262454249931513, 0.29305232686566196,
0.29348023017249047, 0.29390825297590972, 0.2943363958257631,
0.29476465926566697, 0.29519304383304712, 0.29562155005917545,
0.29605017846920678, 0.29647892958221411, 0.29690780391122484,
0.29733680196325429, 0.29776592423934234, 0.29819517123458583,
0.29862454343817446, 0.29905404133342273, 0.29948366539780391,
0.29991341610298328, 0.30034329391485048, 0.30077329929355223,
0.30120343269352423, 0.30163369456352307, 0.30206408534665841,
0.30249460548042406, 0.30292525539672932, 0.30335603552193025,
0.30378694627686054, 0.30421798807686262, 0.30464916133181785,
0.3050804664461777, 0.30551190381899418, 0.30594347384395004,
0.30637517690938965, 0.30680701339834893, 0.30723898368858638,
0.30767108815261357, 0.30810332715772493, 0.30853570106602946,
0.30896821023448096, 0.30940085501490877, 0.30983363575404932,
0.3102665527935774, 0.31069960647013739, 0.31113279711537523,
0.31156612505597092, 0.31199959061367033, 0.31243319410531867,
0.31286693584289393, 0.31330081613353955, 0.31373483527960011,
0.31416899357865535, 0.31460329132355613, 0.31503772880245995,
0.31547230629886847, 0.31590702409166482, 0.31634188245515227,
0.31677688165909323, 0.31721202196875031, 0.31764730364492699,
0.31808272694401074, 0.31851829211801663, 0.31895399941463198,
0.31938984907726342, 0.31982584134508441, 0.3202619764530843,
0.32069825463212054, 0.32113467610897084, 0.32157124110638791,
0.32200794984315684, 0.32244480253415431, 0.32288179939040929,
0.32331894061916766, 0.32375622642395852, 0.3241936570046634,
0.32463123255758897, 0.32506895327554264, 0.32550681934791126,
0.32594483096074423, 0.32638298829683998, 0.32682129153583672,
0.32725974085430765, 0.32769833642586121, 0.32813707842124573,
0.3285759670084607, 0.32901500235287229, 0.32945418461733611,
0.3298935139623268, 0.33033299054607412, 0.3307726145247063,
0.33121238605240333, 0.33165230528155709, 0.33209237236294153,
0.33253258744589365, 0.33297295067850452, 0.33341346220782186,
0.33385412218006649, 0.33429493074086014, 0.33473588803547061,
0.33517699420906999, 0.33561824940701179, 0.3360596537751257,
0.33650120746003176, 0.33694291060947767, 0.33738476337269752,
0.33782676590079708, 0.33826891834716666, 0.33871122086792327,
0.33915367362238613, 0.33959627677358728, 0.340039030488821,
0.34048193494023682, 0.34092499030547785, 0.34136819676837071,
0.34181155451967227, 0.34225506375787662, 0.34269872469009266,
0.34314253753299417, 0.34358650251385525, 0.34403061987167749,
0.34447488985841968, 0.34491931274034215, 0.34536388879947799,
0.34580861833524823, 0.34625350166623603, 0.34669853913214199,
0.34714373109594165, 0.34758907794627381, 0.34803458010008825,
0.3484802380055928, 0.34892605214553651, 0.34937202304088499,
0.34981815125494164, 0.35026443739798774, 0.35071088213252499,
0.35115748617921794, 0.35160425032366349, 0.35205117542412945,
0.35249826242044824, 0.35294551234428706, 0.353392926331075,
0.35384050563393898, 0.3542882516400927, 0.35473616589025114,
0.3551842501018142, 0.35563250619679465, 0.35608093633579696,
0.35652954295981132, 0.3569783288422671, 0.35742729715478549,
0.35787645155159087, 0.35832579627993522, 0.35877533632776559,
0.35922507762644629, 0.35967502733804124, 0.36012519427874867,
0.36057558957500346, 0.36102622774936932, 0.36147712868993698,
0.36192832174764411, 0.36237985654544391, 0.36283185840707965,
0.36283185840707965
), `1-ppv` = c(
0.63716814159292035, 0.63716814159292035,
0.6361389059782101, 0.63496681359486984, 0.63377082390411288,
0.63256843711373545, 0.63136592057348517, 0.63016604092930673,
0.62897012474143532, 0.62777881221732967, 0.62659238577831, 0.62541093049151608,
0.62423441885588904, 0.62306275826274626, 0.62189581871708222,
0.62073344954365939, 0.61957548967933884, 0.61842177410173393,
0.617272137865992, 0.61612641862833772, 0.61498445819595737,
0.61384610344257196, 0.61271120680744007, 0.61157962651986209,
0.61045122664317608, 0.60932587700111951, 0.60820345302897105,
0.60708383557825041, 0.60596691069455422, 0.6048525693818444,
0.60374070736219809, 0.60263122483705867, 0.6015240262539584,
0.60041902008125003, 0.59931611859238021, 0.59821523766054563,
0.59711629656408816, 0.59601921780265876, 0.59492392692396301,
0.5938303523607481, 0.59273842527760556, 0.59164807942711217,
0.59055925101480244, 0.58947187857246064, 0.58838590283922354,
0.58730126665000482, 0.58621791483076158, 0.58513579410015704,
0.58405485297719073, 0.58297504169439396, 0.58189631211621673,
0.58081861766225451, 0.57974191323498525, 0.57866615515171538,
0.57759130108044787, 0.57651730997941386, 0.57544414204001826,
0.57437175863297751, 0.57330012225743898, 0.57222919649288329,
0.57115894595363503, 0.57008933624580915, 0.56902033392654017,
0.56795190646535065, 0.56688402220752243, 0.56581665033934803,
0.56474976085514705, 0.56368332452593783, 0.56261731286966798,
0.56155169812290606, 0.56048645321391255, 0.55942155173700603,
0.55835696792815015, 0.55729267664169269, 0.55622865332818772,
0.55516487401324444, 0.55410131527734174, 0.55303795423655422,
0.55197476852414495, 0.55091173627297252, 0.54984883609867041,
0.54878604708355927, 0.54772334876125095, 0.546660721101909,
0.54559814449813282, 0.54453559975143118, 0.54347306805925766,
0.5424105310025773, 0.54134797053394079, 0.54028536896603729,
0.53922270896070623, 0.5381599735183844, 0.53709714596796532,
0.5360342099570552, 0.5349711494426026, 0.53390794868188873,
0.53284459222385583, 0.53178106490076527, 0.53071735182016244,
0.52965343835714251, 0.52858931014689592, 0.527524953077527,
0.52646035328313157, 0.52539549713712008, 0.52433037124578008,
0.52326496244206289, 0.52219925777958887, 0.52113324452686027,
0.5200669101616715, 0.51900024236571185, 0.51793322901934991,
0.51686585819659392, 0.51579811816022025, 0.51472999735706115,
0.51366148441345116, 0.51259256813081833, 0.5115232374814217,
0.51045348160422199, 0.50938328980088798, 0.50831265153192806,
0.50724155641294222, 0.50616999421099429, 0.50509795484109399,
0.50402542836278963, 0.502952404976865, 0.50187887502213535,
0.50080482897234224, 0.49973025743314081, 0.4986551511391778,
0.49757950095125492, 0.49650329785357783, 0.49542653295108396,
0.49434919746685013, 0.49327128273957277, 0.49219278022112378,
0.49111368147417378, 0.49003397816988414, 0.48895366208566438,
0.48787272510299207, 0.48679115920529481, 0.48570895647588974,
0.48462610909598081, 0.48354260934271154, 0.48245844958726969,
0.48137362229304548, 0.48028812001383758, 0.47920193539210942,
0.47811506115728997, 0.47702749012412216, 0.47593921519105364,
0.4748502293386696, 0.47376052562816884, 0.47267009719987685,
0.47157893727180022, 0.47048703913821588, 0.46939439616829937,
0.46830100180478584, 0.46720684956266723, 0.4661119330279202,
0.46501624585626922, 0.46391978177197823, 0.46282253456667366,
0.46172449809819704, 0.46062566628948565, 0.45952603312748086,
0.45842559266206429, 0.45732433900501845, 0.4562222663290143,
0.45511936886662296, 0.4540156409093512, 0.45291107680670029,
0.45180567096524782, 0.45069941784775147, 0.44959231197227434,
0.44848434791132985, 0.44737552029104921, 0.44626582379036739,
0.44515525314022708, 0.44404380312280434, 0.44293146857074917,
0.44181824436644634, 0.44070412544129167, 0.43958910677498653,
0.43847318339484753, 0.43735635037513365, 0.43623860283638638,
0.43511993594478726, 0.43400034491152994, 0.43287982499220534,
0.43175837148620166, 0.43063597973611778, 0.42951264512719045,
0.42838836308673411, 0.42726312908359287, 0.42613693862760516,
0.42500978726908178, 0.42388167059829263, 0.4227525842449682,
0.42162252387781007, 0.4204914852040128, 0.41935946396879731,
0.41822645595495334, 0.41709245698239283, 0.41595746290771296,
0.41482146962376931, 0.41368447305925804, 0.41254646917830617,
0.41140745398007372, 0.41026742349836165, 0.40912637380123018,
0.40798430099062422, 0.40684120120200917, 0.40569707060401139,
0.40455190539806984, 0.40340570181809265, 0.40225845613012312,
0.4011101646320121, 0.39996082365309771, 0.39881042955389079,
0.39765897872576994, 0.39650646759068042, 0.39535289260084094,
0.39419825023845667, 0.3930425370154379, 0.39188574947312571,
0.39072788418202242, 0.38956893774152856, 0.38840890677968598,
0.3872477879529248, 0.38608557794581755, 0.38492227347083807,
0.38375787126812411, 0.38259236810524833, 0.38142576077699009,
0.38025804610511516, 0.37908922093815933, 0.37791928215121529,
0.37674822664572649, 0.37557605134928251, 0.37440275321542182,
0.37322832922343563, 0.37205277637817813, 0.3708760917098799,
0.36969827227396457, 0.36851931515087111, 0.36733921744587705,
0.36615797628892832, 0.36497558883447079, 0.36379205226128497,
0.36260736377232616, 0.36142152059456478, 0.36023451997883327,
0.35904635919967332, 0.35785703555518711, 0.35666654636689277,
0.35547488897957946, 0.35428206076116975, 0.35308805910258045,
0.35189288141758768, 0.35069652514269634, 0.34949898773700783,
0.34830026668209535, 0.34710035948187645, 0.34589926366249113,
0.3446969767721817, 0.3434934963811731, 0.34228882008155637,
0.34108294548717466, 0.33987587023350929, 0.3386675919775699,
0.33745810839778401, 0.33624741719388918, 0.33503551608682847,
0.33382240281864295, 0.33260807515237067, 0.33139253087194342,
0.33017576778208646, 0.32895778370821849, 0.32773857649635385,
0.32651814401300394, 0.32529648414508117, 0.32407359479980358,
0.3228494739045995, 0.32162411940701274, 0.32039752927461018,
0.31916970149488721, 0.31794063407517625, 0.31671032504255392,
0.31547877244374856, 0.31424597434504864, 0.31301192883221141,
0.31177663401037059, 0.31054008800394406, 0.30930228895654277,
0.30806323503087729, 0.30682292440866654, 0.30558135529054253,
0.30433852589595856, 0.30309443446309225, 0.30184907924875315,
0.30060245852828471, 0.29935457059546666, 0.29810541376241806,
0.29685498635949648, 0.29560328673519753, 0.29435031325605243,
0.29309606430652335, 0.29184053828889855, 0.29058373362318268,
0.28932564874699007, 0.28806628211542951, 0.28680563220099131,
0.28554369749343178, 0.28428047649965238, 0.28301596774357729,
0.2817501697660294, 0.2804830811246023, 0.27921470039352758,
0.27794502616354078, 0.27667405704174353, 0.27540179165145873,
0.27412822863208641, 0.27285336663895299, 0.27157720434315358,
0.27029974043139504, 0.26902097360583088, 0.26774090258388916,
0.26645952609809986, 0.2651768428959127, 0.26389285173950972,
0.26260755140561431, 0.2613209406852901, 0.26003301838373571,
0.25874378332007109, 0.25745323432711786, 0.25616137025117025,
0.25486818995175931, 0.2535736923014088, 0.25227787618538167,
0.25098074050141705, 0.24968228415946037, 0.24838250608137968,
0.24708140520067412, 0.2457789804621725, 0.24447523082171785,
0.24317015524584329, 0.24186375271143223, 0.24055602220536931,
0.23924696272417778, 0.23793657327363815, 0.23662485286840129,
0.23531180053157918, 0.23399741529432017, 0.23268169619537604,
0.2313646422806398, 0.23004625260267852, 0.2287265262202357,
0.22740546219772739, 0.22608305960470465, 0.22475931751530331,
0.2234342350076749, 0.22210781116338552, 0.22078004506679827,
0.21945093580442643, 0.21812048246426807, 0.2167886841351031,
0.21545553990577337, 0.21412104886442418, 0.21278521009772366,
0.21144802269004248, 0.21010948572260779, 0.20876959827261454,
0.20742835941230731, 0.20608576820802549, 0.20474182371919591,
0.20339652499730576, 0.20204987108480899, 0.20070186101400611,
0.19935249380586806, 0.19800176846881079, 0.19664968399742266,
0.19529623937113494, 0.19394143355283133, 0.1925852654874135,
0.19122773410028393, 0.18986883829578149, 0.18850857695554302,
0.18714694893679051, 0.18578395307054618, 0.18441958815977855,
0.18305385297744681, 0.18168674626447989, 0.18031826672765527,
0.17894841303738529, 0.17757718382540322, 0.17620457768234365,
0.17483059315522564, 0.17345522874480113, 0.1720784829027987,
0.17070035402903749, 0.16932084046839702, 0.16793994050766303,
0.16655765237221176, 0.16517397422254709, 0.16378890415066771,
0.16240244017626471, 0.1610145802427394, 0.15962532221302073,
0.15823466386518747, 0.15684260288787288, 0.15544913687544837,
0.15405426332295646, 0.15265797962080108, 0.15126028304917283,
0.14986117077218042, 0.14846063983169555, 0.14705868714086834,
0.14565530947731609, 0.14425050347595658, 0.14284426562145613,
0.14143659224027894, 0.14002747949232197, 0.13861692336207443,
0.13720491964932158, 0.13579146395932051, 0.13437655169243379,
0.13296017803318416, 0.13154233793869741, 0.13012302612647031,
0.1287022370614469, 0.12727996494233884, 0.12585620368713812,
0.1244309469177769, 0.12300418794385848, 0.1215759197454046,
0.12014613495455551, 0.11871482583611015, 0.11728198426687964,
0.11584760171370279, 0.11441166921007151, 0.11297417733122761,
0.11153511616762735, 0.11009447529664973, 0.10865224375238614,
0.10720840999337788, 0.10576296186812906, 0.10431588657819812,
0.10286717063867457, 0.10141679983581375, 0.099964759181588536,
0.098511032864873949, 0.097055604198957091, 0.095598455565082618,
0.094139568351596203, 0.092678922888339677, 0.091216498375800481,
0.089752272808522826, 0.088286222892211441, 0.086818323953894994,
0.085348549844443733, 0.08387687283262335, 0.082403263489813638,
0.080927690564368548, 0.079450120844485217, 0.07797051900826879,
0.07648884745953799, 0.075005066147746713, 0.073519132370003959,
0.072031000553155033, 0.070540622013326559, 0.069047944690088792,
0.067552912851956859, 0.066055466769346149, 0.064555542350535511,
0.063053070735482275, 0.06154797784137811, 0.060040183852798967,
0.058529602648091816, 0.057016141151978506, 0.055499698602535563,
0.053980165718443662, 0.052457423749380228, 0.050931343389108097,
0.049401783526202503, 0.04786858980194697, 0.046331592937892241,
0.04479060678649216, 0.043245426046980118, 0.041695823573377866,
0.040141547182343196, 0.038582315842340065, 0.037017815091212825,
0.035447691482222488, 0.03387154579436058, 0.032288924652988715,
0.030699310080445796, 0.029102106313977583, 0.027496622961443173,
0.025882053165094732, 0.024257444830985686, 0.022621662014939758,
0.020973331987041544, 0.01931077085698707, 0.017631876015072212,
0.015933965136455286, 0.014213524922422005, 0.01246579811308457,
0.010684058225301496, 0.0088582189770833875, 0.0069718188258571789,
0.0049941287433352688, 0.0028511559800148412, NaN, NaN
), precision = c(
0.36283185840707965,
0.36283185840707965, 0.3638610940217899, 0.36503318640513022,
0.36622917609588718, 0.36743156288626455, 0.36863407942651477,
0.36983395907069327, 0.37102987525856468, 0.37222118778267033,
0.37340761422168994, 0.37458906950848397, 0.37576558114411096,
0.37693724173725374, 0.37810418128291784, 0.37926655045634061,
0.38042451032066116, 0.38157822589826601, 0.38272786213400795,
0.38387358137166228, 0.38501554180404268, 0.3861538965574281,
0.38728879319255993, 0.38842037348013791, 0.38954877335682397,
0.39067412299888049, 0.39179654697102889, 0.39291616442174965,
0.39403308930544578, 0.3951474306181556, 0.39625929263780185,
0.39736877516294128, 0.3984759737460416, 0.39958097991875002,
0.40068388140761979, 0.40178476233945432, 0.4028837034359119,
0.40398078219734124, 0.40507607307603694, 0.4061696476392519,
0.40726157472239444, 0.40835192057288783, 0.40944074898519756,
0.41052812142753942, 0.4116140971607764, 0.41269873334999513,
0.41378208516923842, 0.41486420589984296, 0.41594514702280921,
0.41702495830560604, 0.41810368788378327, 0.41918138233774555,
0.42025808676501475, 0.42133384484828468, 0.42240869891955213,
0.42348269002058614, 0.4245558579599818, 0.42562824136702243,
0.42669987774256107, 0.42777080350711671, 0.42884105404636491,
0.42991066375419085, 0.43097966607345983, 0.43204809353464935,
0.43311597779247762, 0.43418334966065192, 0.435250239144853,
0.43631667547406222, 0.43738268713033202, 0.43844830187709388,
0.43951354678608745, 0.44057844826299397, 0.44164303207184979,
0.44270732335830731, 0.44377134667181228, 0.44483512598675551,
0.44589868472265831, 0.44696204576344573, 0.44802523147585505,
0.44908826372702754, 0.45015116390132964, 0.45121395291644079,
0.45227665123874905, 0.453339278898091, 0.45440185550186718,
0.45546440024856877, 0.45652693194074229, 0.45758946899742264,
0.45865202946605921, 0.45971463103396271, 0.46077729103929371,
0.46184002648161565, 0.46290285403203468, 0.4639657900429448,
0.4650288505573974, 0.46609205131811132, 0.46715540777614412,
0.46821893509923479, 0.46928264817983756, 0.47034656164285743,
0.47141068985310414, 0.47247504692247294, 0.47353964671686843,
0.47460450286287992, 0.47566962875421992, 0.47673503755793711,
0.47780074222041108, 0.47886675547313973, 0.47993308983832855,
0.48099975763428821, 0.48206677098065009, 0.48313414180340603,
0.48420188183977975, 0.48527000264293885, 0.48633851558654884,
0.48740743186918162, 0.4884767625185783, 0.48954651839577801,
0.49061671019911202, 0.49168734846807199, 0.49275844358705778,
0.49383000578900565, 0.49490204515890601, 0.49597457163721032,
0.49704759502313495, 0.49812112497786465, 0.49919517102765776,
0.50026974256685919, 0.5013448488608222, 0.50242049904874508,
0.50349670214642217, 0.50457346704891604, 0.50565080253314987,
0.50672871726042723, 0.50780721977887622, 0.50888631852582622,
0.50996602183011586, 0.51104633791433562, 0.51212727489700793,
0.51320884079470519, 0.51429104352411026, 0.51537389090401919,
0.51645739065728846, 0.51754155041273031, 0.51862637770695452,
0.51971187998616242, 0.52079806460789058, 0.52188493884271003,
0.52297250987587784, 0.52406078480894636, 0.5251497706613304,
0.52623947437183116, 0.52732990280012315, 0.52842106272819978,
0.52951296086178412, 0.53060560383170063, 0.53169899819521416,
0.53279315043733277, 0.5338880669720798, 0.53498375414373078,
0.53608021822802177, 0.53717746543332634, 0.53827550190180296,
0.53937433371051435, 0.54047396687251914, 0.54157440733793571,
0.54267566099498155, 0.5437777336709857, 0.54488063113337704,
0.5459843590906488, 0.54708892319329971, 0.54819432903475218,
0.54930058215224853, 0.55040768802772566, 0.55151565208867015,
0.55262447970895079, 0.55373417620963261, 0.55484474685977292,
0.55595619687719566, 0.55706853142925083, 0.55818175563355366,
0.55929587455870833, 0.56041089322501347, 0.56152681660515247,
0.56264364962486635, 0.56376139716361362, 0.56488006405521274,
0.56599965508847006, 0.56712017500779466, 0.56824162851379834,
0.56936402026388222, 0.57048735487280955, 0.57161163691326589,
0.57273687091640713, 0.57386306137239484, 0.57499021273091822,
0.57611832940170737, 0.5772474157550318, 0.57837747612218993,
0.5795085147959872, 0.58064053603120269, 0.58177354404504666,
0.58290754301760717, 0.58404253709228704, 0.58517853037623069,
0.58631552694074196, 0.58745353082169383, 0.58859254601992628,
0.58973257650163835, 0.59087362619876982, 0.59201569900937578,
0.59315879879799083, 0.59430292939598861, 0.59544809460193016,
0.59659429818190735, 0.59774154386987688, 0.5988898353679879,
0.60003917634690229, 0.60118957044610921, 0.60234102127423006,
0.60349353240931958, 0.60464710739915906, 0.60580174976154333,
0.6069574629845621, 0.60811425052687429, 0.60927211581797758,
0.61043106225847144, 0.61159109322031402, 0.6127522120470752,
0.61391442205418245, 0.61507772652916193, 0.61624212873187589,
0.61740763189475167, 0.61857423922300991, 0.61974195389488484,
0.62091077906184067, 0.62208071784878471, 0.62325177335427351,
0.62442394865071749, 0.62559724678457818, 0.62677167077656437,
0.62794722362182187, 0.6291239082901201, 0.63030172772603543,
0.63148068484912889, 0.63266078255412295, 0.63384202371107168,
0.63502441116552921, 0.63620794773871503, 0.63739263622767384,
0.63857847940543522, 0.63976548002116673, 0.64095364080032668,
0.64214296444481289, 0.64333345363310723, 0.64452511102042054,
0.64571793923883025, 0.64691194089741955, 0.64810711858241232,
0.64930347485730366, 0.65050101226299217, 0.65169973331790465,
0.65289964051812355, 0.65410073633750887, 0.6553030232278183,
0.6565065036188269, 0.65771117991844363, 0.65891705451282534,
0.66012412976649071, 0.6613324080224301, 0.66254189160221599,
0.66375258280611082, 0.66496448391317153, 0.66617759718135705,
0.66739192484762933, 0.66860746912805658, 0.66982423221791354,
0.67104221629178151, 0.67226142350364615, 0.67348185598699606,
0.67470351585491883, 0.67592640520019642, 0.6771505260954005,
0.67837588059298726, 0.67960247072538982, 0.68083029850511279,
0.68205936592482375, 0.68328967495744608, 0.68452122755625144,
0.68575402565495136, 0.68698807116778859, 0.68822336598962941,
0.68945991199605594, 0.69069771104345723, 0.69193676496912271,
0.69317707559133346, 0.69441864470945747, 0.69566147410404144,
0.69690556553690775, 0.69815092075124685, 0.69939754147171529,
0.70064542940453334, 0.70189458623758194, 0.70314501364050352,
0.70439671326480247, 0.70564968674394757, 0.70690393569347665,
0.70815946171110145, 0.70941626637681732, 0.71067435125300993,
0.71193371788457049, 0.71319436779900869, 0.71445630250656822,
0.71571952350034762, 0.71698403225642271, 0.7182498302339706,
0.7195169188753977, 0.72078529960647242, 0.72205497383645922,
0.72332594295825647, 0.72459820834854127, 0.72587177136791359,
0.72714663336104701, 0.72842279565684642, 0.72970025956860496,
0.73097902639416912, 0.73225909741611084, 0.73354047390190014,
0.7348231571040873, 0.73610714826049028, 0.73739244859438569,
0.7386790593147099, 0.73996698161626429, 0.74125621667992891,
0.74254676567288214, 0.74383862974882975, 0.74513181004824069,
0.7464263076985912, 0.74772212381461833, 0.74901925949858295,
0.75031771584053963, 0.75161749391862032, 0.75291859479932588,
0.7542210195378275, 0.75552476917828215, 0.75682984475415671,
0.75813624728856777, 0.75944397779463069, 0.76075303727582222,
0.76206342672636185, 0.76337514713159871, 0.76468819946842082,
0.76600258470567983, 0.76731830380462396, 0.7686353577193602,
0.76995374739732148, 0.7712734737797643, 0.77259453780227261,
0.77391694039529535, 0.77524068248469669, 0.7765657649923251,
0.77789218883661448, 0.77921995493320173, 0.78054906419557357,
0.78187951753573193, 0.7832113158648969, 0.78454446009422663,
0.78587895113557582, 0.78721478990227634, 0.78855197730995752,
0.78989051427739221, 0.79123040172738546, 0.79257164058769269,
0.79391423179197451, 0.79525817628080409, 0.79660347500269424,
0.79795012891519101, 0.79929813898599389, 0.80064750619413194,
0.80199823153118921, 0.80335031600257734, 0.80470376062886506,
0.80605856644716867, 0.8074147345125865, 0.80877226589971607,
0.81013116170421851, 0.81149142304445698, 0.81285305106320949,
0.81421604692945382, 0.81558041184022145, 0.81694614702255319,
0.81831325373552011, 0.81968173327234473, 0.82105158696261471,
0.82242281617459678, 0.82379542231765635, 0.82516940684477436,
0.82654477125519887, 0.8279215170972013, 0.82929964597096251,
0.83067915953160298, 0.83206005949233697, 0.83344234762778824,
0.83482602577745291, 0.83621109584933229, 0.83759755982373529,
0.8389854197572606, 0.84037467778697927, 0.84176533613481253,
0.84315739711212712, 0.84455086312455163, 0.84594573667704354,
0.84734202037919892, 0.84873971695082717, 0.85013882922781958,
0.85153936016830445, 0.85294131285913166, 0.85434469052268391,
0.85574949652404342, 0.85715573437854387, 0.85856340775972106,
0.85997252050767803, 0.86138307663792557, 0.86279508035067842,
0.86420853604067949, 0.86562344830756621, 0.86703982196681584,
0.86845766206130259, 0.86987697387352969, 0.8712977629385531,
0.87272003505766116, 0.87414379631286188, 0.8755690530822231,
0.87699581205614152, 0.8784240802545954, 0.87985386504544449,
0.88128517416388985, 0.88271801573312036, 0.88415239828629721,
0.88558833078992849, 0.88702582266877239, 0.88846488383237265,
0.88990552470335027, 0.89134775624761386, 0.89279159000662212,
0.89423703813187094, 0.89568411342180188, 0.89713282936132543,
0.89858320016418625, 0.90003524081841146, 0.90148896713512605,
0.90294439580104291, 0.90440154443491738, 0.9058604316484038,
0.90732107711166032, 0.90878350162419952, 0.91024772719147717,
0.91171377710778856, 0.91318167604610501, 0.91465145015555627,
0.91612312716737665, 0.91759673651018636, 0.91907230943563145,
0.92054987915551478, 0.92202948099173121, 0.92351115254046201,
0.92499493385225329, 0.92648086762999604, 0.92796899944684497,
0.92945937798667344, 0.93095205530991121, 0.93244708714804314,
0.93394453323065385, 0.93544445764946449, 0.93694692926451772,
0.93845202215862189, 0.93995981614720103, 0.94147039735190818,
0.94298385884802149, 0.94450030139746444, 0.94601983428155634,
0.94754257625061977, 0.9490686566108919, 0.9505982164737975,
0.95213141019805303, 0.95366840706210776, 0.95520939321350784,
0.95675457395301988, 0.95830417642662213, 0.9598584528176568,
0.96141768415765994, 0.96298218490878718, 0.96455230851777751,
0.96612845420563942, 0.96771107534701128, 0.9693006899195542,
0.97089789368602242, 0.97250337703855683, 0.97411794683490527,
0.97574255516901431, 0.97737833798506024, 0.97902666801295846,
0.98068922914301293, 0.98236812398492779, 0.98406603486354471,
0.98578647507757799, 0.98753420188691543, 0.9893159417746985,
0.99114178102291661, 0.99302818117414282, 0.99500587125666473,
0.99714884401998516, NaN, NaN
), recall = c(
1, 1, 0.99804305283757333,
0.99608610567514666, 0.9941291585127201, 0.99217221135029354,
0.99021526418786687, 0.9882583170254402, 0.98630136986301364,
0.98434442270058709, 0.98238747553816042, 0.98043052837573375,
0.97847358121330719, 0.97651663405088063, 0.97455968688845396,
0.97260273972602729, 0.97064579256360073, 0.96868884540117417,
0.9667318982387475, 0.96477495107632083, 0.96281800391389427,
0.96086105675146771, 0.95890410958904104, 0.95694716242661437,
0.95499021526418781, 0.95303326810176126, 0.95107632093933459,
0.94911937377690792, 0.94716242661448136, 0.9452054794520548,
0.94324853228962813, 0.94129158512720146, 0.9393346379647749,
0.93737769080234834, 0.93542074363992167, 0.93346379647749489,
0.93150684931506844, 0.92954990215264188, 0.92759295499021521,
0.92563600782778854, 0.92367906066536198, 0.92172211350293543,
0.91976516634050876, 0.91780821917808209, 0.91585127201565553,
0.91389432485322897, 0.9119373776908023, 0.90998043052837563,
0.90802348336594907, 0.90606653620352251, 0.90410958904109584,
0.90215264187866917, 0.90019569471624261, 0.89823874755381605,
0.89628180039138938, 0.89432485322896271, 0.89236790606653615,
0.8904109589041096, 0.88845401174168304, 0.88649706457925626,
0.8845401174168297, 0.88258317025440314, 0.88062622309197647,
0.8786692759295498, 0.87671232876712324, 0.87475538160469657,
0.8727984344422699, 0.87084148727984334, 0.86888454011741678,
0.86692759295499022, 0.86497064579256355, 0.86301369863013688,
0.86105675146771044, 0.85909980430528377, 0.8571428571428571,
0.85518590998043043, 0.85322896281800387, 0.85127201565557742,
0.84931506849315064, 0.84735812133072397, 0.84540117416829741,
0.84344422700587085, 0.84148727984344429, 0.83953033268101751,
0.83757338551859095, 0.83561643835616439, 0.83365949119373772,
0.83170254403131105, 0.82974559686888449, 0.82778864970645794,
0.82583170254403138, 0.8238747553816046, 0.82191780821917804,
0.81996086105675148, 0.81800391389432481, 0.81604696673189814,
0.81409001956947158, 0.81213307240704502, 0.81017612524461835,
0.80821917808219157, 0.80626223091976512, 0.80430528375733856,
0.802348336594912, 0.80039138943248522, 0.79843444227005878,
0.79647749510763211, 0.79452054794520544, 0.79256360078277877,
0.79060665362035221, 0.78864970645792565, 0.78669275929549909,
0.78473581213307231, 0.78277886497064575, 0.78082191780821919,
0.77886497064579252, 0.77690802348336585, 0.77495107632093929,
0.77299412915851273, 0.77103718199608617, 0.76908023483365939,
0.76712328767123283, 0.76516634050880639, 0.76320939334637972,
0.76125244618395294, 0.75929549902152638, 0.75733855185909993,
0.75538160469667315, 0.75342465753424648, 0.75146771037181992,
0.74951076320939336, 0.74755381604696669, 0.74559686888454002,
0.74363992172211346, 0.7416829745596869, 0.73972602739726023,
0.73776908023483356, 0.73581213307240712, 0.73385518590998045,
0.73189823874755378, 0.72994129158512711, 0.72798434442270055,
0.72602739726027399, 0.72407045009784743, 0.72211350293542065,
0.72015655577299409, 0.71819960861056753, 0.71624266144814086,
0.71428571428571419, 0.71232876712328763, 0.71037181996086107,
0.7084148727984344, 0.70645792563600773, 0.70450097847358117,
0.70254403131115462, 0.70058708414872795, 0.69863013698630128,
0.69667318982387472, 0.69471624266144816, 0.69275929549902149,
0.69080234833659482, 0.68884540117416826, 0.6868884540117417,
0.68493150684931503, 0.68297455968688836, 0.6810176125244618,
0.67906066536203524, 0.67710371819960857, 0.6751467710371819,
0.67318982387475523, 0.67123287671232879, 0.669275929549902,
0.66731898238747545, 0.66536203522504889, 0.66340508806262233,
0.66144814090019555, 0.65949119373776899, 0.65753424657534243,
0.65557729941291587, 0.6536203522504892, 0.65166340508806253,
0.64970645792563597, 0.64774951076320941, 0.64579256360078274,
0.64383561643835607, 0.64187866927592951, 0.63992172211350296,
0.63796477495107629, 0.63600782778864962, 0.63405088062622306,
0.6320939334637965, 0.63013698630136983, 0.62818003913894316,
0.6262230919765166, 0.62426614481409004, 0.62230919765166337,
0.6203522504892367, 0.61839530332681014, 0.61643835616438358,
0.61448140900195691, 0.61252446183953024, 0.61056751467710368,
0.60861056751467713, 0.60665362035225046, 0.60469667318982379,
0.60273972602739723, 0.60078277886497067, 0.598825831702544,
0.59686888454011733, 0.59491193737769077, 0.59295499021526421,
0.59099804305283754, 0.58904109589041087, 0.58708414872798431,
0.58512720156555775, 0.58317025440313108, 0.58121330724070441,
0.57925636007827785, 0.5772994129158513, 0.57534246575342463,
0.57338551859099796, 0.5714285714285714, 0.56947162426614484,
0.56751467710371817, 0.5655577299412915, 0.56360078277886494,
0.56164383561643838, 0.55968688845401171, 0.55772994129158504,
0.55577299412915848, 0.55381604696673192, 0.55185909980430525,
0.54990215264187858, 0.54794520547945202, 0.54598825831702547,
0.5440313111545988, 0.54207436399217213, 0.54011741682974557,
0.53816046966731901, 0.53620352250489234, 0.53424657534246567,
0.53228962818003911, 0.53033268101761255, 0.52837573385518588,
0.52641878669275921, 0.52446183953033265, 0.52250489236790609,
0.52054794520547942, 0.51859099804305275, 0.51663405088062619,
0.51467710371819964, 0.51272015655577297, 0.5107632093933463,
0.50880626223091974, 0.50684931506849318, 0.50489236790606651,
0.50293542074363984, 0.50097847358121328, 0.49902152641878667,
0.49706457925636005, 0.49510763209393344, 0.49315068493150682,
0.49119373776908021, 0.48923679060665359, 0.48727984344422698,
0.48532289628180036, 0.48336594911937375, 0.48140900195694714,
0.47945205479452052, 0.47749510763209391, 0.47553816046966729,
0.47358121330724068, 0.47162426614481406, 0.46966731898238745,
0.46771037181996084, 0.46575342465753422, 0.46379647749510761,
0.46183953033268099, 0.45988258317025438, 0.45792563600782776,
0.45596868884540115, 0.45401174168297453, 0.45205479452054792,
0.45009784735812131, 0.44814090019569469, 0.44618395303326808,
0.44422700587084146, 0.44227005870841485, 0.44031311154598823,
0.43835616438356162, 0.43639921722113501, 0.43444227005870839,
0.43248532289628178, 0.43052837573385516, 0.42857142857142855,
0.42661448140900193, 0.42465753424657537, 0.4227005870841487,
0.42074363992172209, 0.41878669275929548, 0.41682974559686886,
0.41487279843444225, 0.41291585127201569, 0.41095890410958907,
0.4090019569471624, 0.40704500978473579, 0.40508806262230923,
0.40313111545988256, 0.40117416829745595, 0.39921722113502939,
0.39726027397260272, 0.39530332681017616, 0.39334637964774949,
0.39138943248532287, 0.38943248532289626, 0.38747553816046965,
0.38551859099804303, 0.38356164383561642, 0.38160469667318986,
0.37964774951076319, 0.37769080234833657, 0.37573385518590996,
0.3737769080234834, 0.37181996086105673, 0.36986301369863012,
0.3679060665362035, 0.36594911937377694, 0.36399217221135027,
0.36203522504892366, 0.36007827788649704, 0.35812133072407043,
0.35616438356164382, 0.3542074363992172, 0.35225048923679059,
0.35029354207436392, 0.34833659491193741, 0.3463796477495108,
0.34442270058708419, 0.34246575342465752, 0.34050880626223096,
0.33855185909980429, 0.33659491193737767, 0.33463796477495111,
0.33268101761252444, 0.33072407045009783, 0.32876712328767127,
0.3268101761252446, 0.32485322896281799, 0.32289628180039132,
0.32093933463796476, 0.31898238747553814, 0.31702544031311153,
0.31506849315068497, 0.31311154598825836, 0.31115459882583163,
0.30919765166340507, 0.30724070450097851, 0.30528375733855184,
0.30332681017612523, 0.30136986301369861, 0.299412915851272,
0.29745596868884538, 0.29549902152641883, 0.29354207436399216,
0.2915851272015656, 0.28962818003913887, 0.28767123287671237,
0.2857142857142857, 0.28375733855185903, 0.28180039138943253,
0.27984344422700586, 0.27788649706457924, 0.27592954990215257,
0.27397260273972601, 0.27201565557729945, 0.27005870841487278,
0.26810176125244617, 0.26614481409001955, 0.264187866927593,
0.26223091976516638, 0.26027397260273977, 0.2583170254403131,
0.25636007827788648, 0.25440313111545987, 0.25244618395303331,
0.2504892367906067, 0.24853228962818005, 0.24657534246575341,
0.2446183953033268, 0.2426614481409001, 0.24070450097847362,
0.23874755381604693, 0.23679060665362034, 0.23483365949119361,
0.23287671232876717, 0.23091976516634047, 0.22896281800391383,
0.22700587084148729, 0.22504892367906071, 0.22309197651663407,
0.2211350293542074, 0.21917808219178078, 0.2172211350293542,
0.21526418786692758, 0.21330724070450094, 0.21135029354207435,
0.20939334637964774, 0.20743639921722107, 0.20547945205479451,
0.20352250489236787, 0.20156555772994122, 0.19960861056751467,
0.19765166340508805, 0.19569471624266147, 0.19373776908023482,
0.19178082191780826, 0.18982387475538162, 0.18786692759295498,
0.18590998043052842, 0.18395303326810175, 0.18199608610567519,
0.18003913894324852, 0.17808219178082194, 0.17612524461839529,
0.17416829745596865, 0.17221135029354201, 0.17025440313111548,
0.16829745596868884, 0.16634050880626222, 0.16438356164383566,
0.16242661448140899, 0.16046966731898241, 0.15851272015655576,
0.15655577299412918, 0.15459882583170251, 0.15264187866927589,
0.15068493150684936, 0.14872798434442261, 0.14677103718199611,
0.14481409001956941, 0.14285714285714282, 0.14090019569471618,
0.13894324853228959, 0.13698630136986298, 0.13502935420743636,
0.13307240704500972, 0.13111545988258316, 0.12915851272015663,
0.12720156555772999, 0.1252446183953034, 0.12328767123287671,
0.12133072407045009, 0.11937377690802352, 0.11741682974559686,
0.11545988258317025, 0.11350293542074361, 0.11154598825831699,
0.10958904109589039, 0.1076320939334638, 0.1056751467710372,
0.10371819960861053, 0.10176125244618392, 0.099804305283757389,
0.097847358121330733, 0.09589041095890416, 0.093933463796477504,
0.091976516634050862, 0.090019569471624289, 0.088062622309197675,
0.086105675146771019, 0.084148727984344446, 0.082191780821917845,
0.080234833659491259, 0.078277886497064589, 0.076320939334637947,
0.074363992172211374, 0.072407045009784773, 0.070450097847358159,
0.068493150684931517, 0.066536203522504889, 0.064579256360078302,
0.062622309197651688, 0.060665362035225066, 0.058708414872798501,
0.056751467710371865, 0.054794520547945209, 0.052837573385518657,
0.050880626223092015, 0.048923679060665401, 0.046966731898238773,
0.045009784735812165, 0.043052837573385544, 0.041095890410958923,
0.039138943248532329, 0.03718199608610568, 0.035225048923679107,
0.033268101761252479, 0.031311154598825837, 0.029354207436399233,
0.027397260273972615, 0.02544031311154599, 0.023483365949119386,
0.021526418786692772, 0.019569471624266147, 0.017612524461839554,
0.015655577299412939, 0.013698630136986308, 0.011741682974559685,
0.0097847358121330927, 0.0078277886497064766, 0.0058708414872798544,
0.0039138943248532305, 0.0019569471624266178, 0, 0
), lr_pos = c(
1,
1, 1.0044592049640639, 1.0095549477491361, 1.0147740139539754,
1.0200408897322375, 1.0253283978099121, 1.030624424845604, 1.035923064324404,
1.0412213781154238, 1.0465179843670069, 1.051812367294235, 1.0571045117236577,
1.06239469792949, 1.0676833813022926, 1.0729711194163183, 1.0782585267458038,
1.0835462460788319, 1.0888349303024161, 1.0941252307773439, 1.0994177899766424,
1.1047132369215551, 1.1100121844717385, 1.1153152278521059, 1.1206229440060151,
1.1259358914989244, 1.1312546107851775, 1.1365796247098205, 1.1419114391573932,
1.147250543787061, 1.1525974128123444, 1.1579525057968658, 1.1633162684467249,
1.1686891333865559, 1.174071520910881, 1.179463839705559, 1.1848664875363857,
1.190279851903469, 1.1957043106610907, 1.2011402326035097, 1.2065879780176683,
1.2120478992040702, 1.2175203409672943, 1.2230056410777215, 1.2285041307060878,
1.234016134832465, 1.2395419726312522, 1.2450819578336947, 1.2506363990693914,
1.256205600188171, 1.2617898605636433, 1.2673894753796522, 1.2730047359007859,
1.2786359297280141, 1.2842833410404637, 1.2899472508242582, 1.2956279370893011,
1.3013256750748117, 1.3070407374443556, 1.312773394471086, 1.3185239142138276,
1.3242925626846263, 1.3300796040083041, 1.3358853005745608, 1.3417099131830905,
1.3475537011821788, 1.3534169226011836, 1.3592998342773046, 1.365202691976996,
1.3711257505123648, 1.3770692638528681, 1.3830334852326032, 1.389018667253471,
1.3950250619844624, 1.4010529210573106, 1.4071024957587337, 1.4131740371194761,
1.4192677960003486, 1.4253840231754471, 1.4315229694127232, 1.4376848855520721,
1.443870022581089, 1.4500786317086305, 1.4563109644363277, 1.4625672726281629,
1.4688478085782459, 1.4751528250768844, 1.4814825754750693, 1.4878373137474645,
1.4942172945540042, 1.5006227733001827, 1.5070540061961146, 1.5135112503144623,
1.5199947636472921, 1.5265048051619354, 1.5330416348559217, 1.5396055138110578,
1.5461967042466995, 1.5528154695722898, 1.559462074439204, 1.566136784791972,
1.5728398679189188, 1.5795715925022717, 1.5863322286677819, 1.5931220480339134,
1.5999413237606273, 1.6067903305978162, 1.6136693449334161, 1.6205786448412491,
1.6275185101286145, 1.634489222383684, 1.6414910650227132, 1.6485243233371214,
1.6555892845404652, 1.6626862378153264, 1.6698154743601601, 1.6769772874361215,
1.6841719724139044, 1.6913998268206167, 1.6986611503867144, 1.7059562450930348,
1.7132854152179371, 1.7206489673845888, 1.7280472106084102, 1.7354804563447115,
1.7429490185365424, 1.7504532136627737, 1.7579933607864353, 1.7655697816033338,
1.7731828004909789, 1.7808327445578185, 1.7885199436928338, 1.796244730615487,
1.804007440926068, 1.8118084131564385, 1.8196479888212105, 1.8275265124693727,
1.8354443317363889, 1.8434017973967811, 1.8513992634172287, 1.8594370870101973,
1.86751562868812, 1.8756352523181472, 1.8837963251774967, 1.8919992180094081,
1.900244305079738, 1.9085319642342042, 1.9168625769563139, 1.9252365284259769,
1.9336542075788457, 1.9421160071663928, 1.9506223238167415, 1.959173558096289,
1.9677701145721249, 1.9764124018752851, 1.9851008327648396, 1.9938358241928671,
2.0026177973703119, 2.0114471778337673, 2.0203243955131915, 2.0292498848005889,
2.0382240846196917, 2.0472474384966346, 2.0563203946316873, 2.0654434059720375,
2.0746169302856692, 2.0838414302363564, 2.0931173734597985, 2.1024452326409167,
2.1118254855923659, 2.121258615334253, 2.1307451101751163, 2.1402854637941897,
2.1498801753249737, 2.159529749440158, 2.1692346964379041, 2.1789955323295453,
2.1888127789287162, 2.1986869639419577, 2.2086186210608196, 2.2186082900555069,
2.2286565168700903, 2.2387638537193362, 2.2489308591871673, 2.2591580983268158,
2.2694461427626944, 2.2797955707940236, 2.2902069675002523, 2.3006809248483275,
2.3112180418018387, 2.3218189244320877, 2.332484186031119, 2.3432144472267682,
2.3540103360997633, 2.3648724883029328, 2.375801547182554, 2.3867981639019153,
2.3978629975671182, 2.4089967153551832, 2.4201999926445108, 2.4314735131477421,
2.4428179690470926, 2.4542340611321993, 2.4657224989405386, 2.4772840009004851,
2.4889192944770691, 2.5006291163204919, 2.5124142124174536, 2.5242753382453844,
2.5362132589296147, 2.548228749403588, 2.5603225945721397, 2.5724955894779789,
2.5847485394713772, 2.5970822603831998, 2.6094975787013177, 2.6219953317504947,
2.6345763678758432, 2.6472415466299259, 2.6599917389635586, 2.6728278274204653,
2.6857507063358272, 2.6987612820388347, 2.7118604730593523, 2.7250492103387618,
2.7383284374451318, 2.7516991107927811, 2.7651621998663485, 2.7787186874495133,
2.7923695698584163, 2.806115857179972, 2.8199585735151369, 2.8338987572272671,
2.8479374611957291, 2.8620757530748433, 2.876314715558312, 2.8906554466493084,
2.9050990599362874, 2.9196466848747571, 2.9342994670750788, 2.9490585685965121,
2.9639251682476231, 2.9789004618932453, 2.9939856627681443, 3.0091820017975563,
3.0244907279248241, 3.039913108446231, 3.0554504293533045, 3.0711039956827362,
3.0868751318741365, 3.1027651821358164, 3.1187755108188275, 3.1349075027994751,
3.1511625638705083, 3.167542121141262, 3.1840476234469395, 3.200680541767329,
3.2174423696551839, 3.2343346236745445, 3.2513588438492285, 3.268516594121869,
3.2858094628236434, 3.30323906315515, 3.3208070336786011, 3.3385150388217362,
3.3563647693937448, 3.3743579431135635, 3.3924963051508419, 3.4107816286799992,
3.4292157154477128, 3.4478003963542001, 3.4665375320487546, 3.4854290135398411,
3.5044767628203051, 3.5236827335080001, 3.543048911502372, 3.5625773156574359,
3.5822699984716109, 3.6021290467949494, 3.6221565825542243, 3.6423547634964737,
3.662725783951454, 3.6832718756136789, 3.7039953083445623, 3.72489839099527,
3.7459834722509764, 3.767252941497079, 3.7887092297081364, 3.810354810360185,
3.8321922003671345, 3.8542239610420288, 3.8764526990839587, 3.8988810675913612,
3.9215117671026043, 3.9443475466646918, 3.967391204930979, 3.9906455912888203,
4.0141136070181247, 4.0377982064818072, 4.0617023983491425, 4.085829246853117,
4.1101818730829232, 4.1347634563126325, 4.1595772353673635, 4.1846265100281359,
4.2099146424766714, 4.2354450587815151, 4.2612212504268534, 4.2872467758854658,
4.3135252622372908, 4.3400604068351933, 4.36685597901955, 4.3939158218832546,
4.4212438540890187, 4.4488440717406723, 4.4767205503103789, 4.5048774466237909,
4.533319000905089, 4.562049538884108, 4.5910734739677075, 4.6203953094777557,
4.6500196409580372, 4.6799511585526634, 4.7101946494585158, 4.7407550004545209,
4.7716372005104626, 4.8028463434783797, 4.834387630869557, 4.8662663747203609,
4.8984880005501878, 4.9310580504150288, 4.9639821860603703, 4.9972661921770847,
5.0309159797643517, 5.0649375896037272, 5.099337195848693, 5.1341211097341368,
5.1692957834105862, 5.2048678139079776, 5.2408439472342359, 5.2772310826139819,
5.3140362768730371, 5.3512667489745676, 5.388929884713086, 5.4270332415727722,
5.4655845537567913, 5.504591737394823, 5.5440628959360865, 5.5840063257356913,
5.6244305218425668, 5.6653441839972247, 5.7067562228487194, 5.7486757663998347,
5.7911121666905805, 5.8340750067303269, 5.8775741076893606, 5.921619536361411,
5.9662216129090337, 6.0113909189045946, 6.0571383056800228, 6.1034749029992428,
6.1504121280681412, 6.1979616948973311, 6.2461356240340615, 6.2949462526803979,
6.3444062452157102, 6.3945286041423435, 6.4453266814748584, 6.4968141905935211,
6.5490052185847238, 6.6019142390916032, 6.6555561256999427, 6.7099461658852624,
6.7651000755491282, 6.8210340141738852, 6.8777646006265618, 6.9353089296452168,
6.9936845890417265, 7.0529096776582954, 7.1130028241162968, 7.1739832063986304,
7.2358705723092243, 7.2986852608561721, 7.3624482246072436, 7.4271810530703863,
7.4929059971539536, 7.5596459947659165, 7.6274246976145594, 7.696266499276553,
7.7661965646036935, 7.8372408605432975, 7.9094261884523052, 7.9827802179902774,
8.057331522682869, 8.1331096172519448, 8.2101449968167639, 8.2884691780758111,
8.36811474258832, 8.449115382281013, 8.5315059473152122, 8.6153224964589636,
8.7006023501183805, 8.7873841461944728, 8.8757078989422578, 8.9656150610234864,
9.0571485889566823, 9.1503530121847962, 9.2452745059956438, 9.3419609685497029,
9.4404621022878281, 9.5408295000132046, 9.6431167359644565, 9.747379462221712,
9.8536755108143375, 9.9620650019288846, 10.07261045864785, 10.185376928684684,
10.300432113619552, 10.417846506181906, 10.537693536171796, 10.660049725663367,
10.784994854187845, 10.912612134655106, 11.042988400839528, 11.176214307329227,
11.312384542918782, 11.451598058515177, 11.593958310724052, 11.739573522394469,
11.888556961518754, 12.041027240018563, 12.197108634096278, 12.356931427994708,
12.520632283191446, 12.688354635257731, 12.860249120836796, 13.036474037452619,
13.217195839138856, 13.402589671199353, 13.592839947760735, 13.788140976180916,
13.988697632821131, 14.194726095196206, 14.406454636084385, 14.62412448582165,
14.847990769731348, 15.078323528464125, 15.315408829960315, 15.559549982810109,
15.811068861999521, 16.070307359419822, 16.337628973102085, 16.613420550957478,
16.898094206898907, 17.192089429623856, 17.495875407123822, 17.809953593205709,
18.134860546040038, 18.471171073099654, 18.81950172192095, 19.180514662037439,
19.554922010387493, 19.943490660670346, 20.347047686757524, 20.766486401681011,
21.202773167264255, 21.656955065582011, 22.130168562754207, 22.623649318698988,
23.138743324378247, 23.676919581788148, 24.239784582908918, 24.829098893810194,
25.446796211337279, 26.095005335229637, 26.776075591836452, 27.49260636173392,
28.247481508817057, 29.04390969126413, 29.885471766311106, 30.776176795782142,
31.720528538038955, 32.723604801461761, 33.79115267229097, 34.929703467240685,
36.146712371108258, 37.45072920398578, 38.85160876773044, 40.360771959185968,
41.991532618761255, 43.759510370688062, 45.683157204565227, 47.784436322765842,
50.089707517923976, 52.630896736552756, 55.447062913121904, 58.586529946094153,
62.109838391899117, 66.093912242107947, 70.638071454384061, 75.87292721254444,
81.973925024859426, 89.182662677056456, 97.841787512284569, 108.45486034785988,
121.79506730206097, 139.11715780893738, 162.61005656738854, 196.48889564978134,
250.12904243484229, 349.8763194670085, 614.16866182007311, NaN,
NaN
), lr_neg = c(
NaN, NaN, 0.30636330812856638, 0.29336533600416548,
0.28857442951280543, 0.28651033929387093, 0.28572122332450894,
0.28563552058505681, 0.28597828152754978, 0.28659975999058229,
0.28741115478454093, 0.28835643053855081, 0.28939851370155761,
0.29051194620721477, 0.29167871501764753, 0.29288575860060823,
0.29412341118080337, 0.29538439687631929, 0.29666315938509163,
0.29795540351242766, 0.29925777442380952, 0.30056762876066517,
0.30188286842573647, 0.3032018179854033, 0.30452313297538208,
0.30584573045582875, 0.3071687358188615, 0.30849144162480896,
0.30981327544830189, 0.31113377454719537, 0.31245256575031077,
0.31376934937412287, 0.3150838862764459, 0.31639598737198465,
0.31770550509410506, 0.31901232640568761, 0.32031636705079169,
0.32161756680610221, 0.32291588554238937, 0.32421129994565195,
0.3255038007780891, 0.32679339058284324, 0.32808008175509351,
0.32936389491679402, 0.33064485754402501, 0.3319230028052455,
0.33319836857619722, 0.33447099660323537, 0.33574093179173081,
0.33700822160015093, 0.33827291552365907, 0.33953506465372596,
0.34079472130242577, 0.34205193868189265, 0.34330677063090137,
0.3445592713817841, 0.34580949536192274, 0.34705749702492389,
0.34830333070731478, 0.34954705050719759, 0.35078871018182617,
0.35202836306149954, 0.35326606197753396, 0.35450185920239069,
0.35573580640030594, 0.35696795458699182, 0.35819835409717565,
0.35942705455891122, 0.36065410487373795, 0.3618795532018842,
0.363103446951825, 0.36432583277358499, 0.36554675655526486,
0.36676626342233509, 0.36798439773929498, 0.36920120311335775,
0.37041672239985429, 0.37163099770909452, 0.37284407041445849,
0.3740559811615134, 0.37526676987798874, 0.37647647578445054,
0.37768513740554849, 0.37889279258171527, 0.38009947848122277,
0.3813052316125054, 0.38251008783667534, 0.38371408238016336,
0.38491724984743042, 0.38611962423369978, 0.38732123893766601,
0.38852212677414938, 0.38972231998665663, 0.39092185025983173,
0.39212074873176528, 0.39331904600614942, 0.39451677216425868,
0.39571395677674881, 0.39691062891525603, 0.39810681716379526,
0.39930254962994416, 0.40049785395581544, 0.40169275732880383,
0.40288728649211603, 0.40408146775507137, 0.4052753270031853,
0.40646888970802009, 0.40766218093682077, 0.40885522536192315,
0.41004804726994659, 0.41124067057076619, 0.41243311880627392,
0.41362541515892542, 0.41481758246008132, 0.41600964319814365,
0.41720161952649087, 0.4183935332712172, 0.4195854059386791,
0.42077725872285243, 0.42196911251250668, 0.42316098789819578,
0.42435290517907631, 0.42554488436955124, 0.42673694520574573,
0.42792910715181931, 0.42912138940611938, 0.4303138109071773,
0.43150639033955168, 0.43269914613952754, 0.43389209650066674,
0.43508525937922171, 0.43627865249940934, 0.43747229335855486,
0.43866619923210376, 0.4398603871785095, 0.4410548740439969,
0.44224967646720781, 0.44344481088373006, 0.44464029353051282,
0.44583614045017372, 0.44703236749519737, 0.44822899033203173,
0.44942602444508223, 0.45062348514060807, 0.45182138755052226,
0.45301974663610084, 0.45421857719159947, 0.45541789384778247,
0.45661771107536775, 0.45781804318838765, 0.45901890434746856,
0.46022030856303281, 0.46142226969842354, 0.46262480147295565,
0.4638279174648936, 0.46503163111435974, 0.46623595572617349,
0.46744090447262487, 0.46864649039618173, 0.46985272641213521,
0.47105962531118378, 0.47226719976195652, 0.47347546231348026,
0.47468442539758765, 0.47589410133127247, 0.47710450231899049,
0.47831564045490821, 0.47952752772510027, 0.48074017600969932,
0.48195359708499524, 0.48316780262549042, 0.48438280420590629,
0.48559861330314835, 0.48681524129822634, 0.48803269947813221,
0.4892509990376776, 0.49047015108129188, 0.49169016662478032,
0.49291105659704415, 0.4941328318417646, 0.49535550311905002,
0.49657908110704907, 0.49780357640352824, 0.49902899952741697,
0.50025536092031975, 0.50148267094799726, 0.50271093990181548,
0.50394017800016588, 0.50517039538985509, 0.50640160214746688,
0.50763380828069538, 0.50886702372965176, 0.51010125836814335,
0.51133652200492841, 0.51257282438494323, 0.51381017519050731,
0.51504858404250131, 0.51628806050152498, 0.51752861406902895,
0.51877025418842548, 0.52001299024617809, 0.52125683157286817,
0.52250178744424225, 0.5237478670822372, 0.52499507965598757,
0.52624343428281217, 0.52749294002918157, 0.5287436059116678,
0.52999544089787509, 0.53124845390735476, 0.53250265381249973,
0.53375804943942518, 0.5350146495688306, 0.53627246293684738,
0.53753149823586888, 0.53879176411536633, 0.5400532691826897,
0.5413160220038532, 0.54258003110430597, 0.5438453049696903,
0.54511185204658474, 0.54637968074323429, 0.5476487994302669,
0.54891921644139752, 0.55019094007411995, 0.55146397859038521,
0.55273834021726898, 0.55401403314762687, 0.55529106554073693,
0.55656944552293364, 0.55784918118822824, 0.55913028059891867,
0.56041275178619032, 0.56169660275070521, 0.56298184146318087,
0.56426847586496021, 0.56555651386857031, 0.56684596335827386,
0.5681368321906084, 0.56942912819491887, 0.57072285917387933,
0.57201803290400799, 0.57331465713617136, 0.57461273959608139,
0.57591228798478422, 0.57721330997914044, 0.57851581323229762,
0.57981980537415523, 0.58112529401182134, 0.58243228673006264,
0.58374079109174726, 0.58505081463827879, 0.58636236489002536,
0.58767544934674076, 0.58899007548797866, 0.59030625077350052,
0.5916239826436771, 0.5929432785198836, 0.59426414580488773,
0.59558659188323326, 0.59691062412161533, 0.59823624986925261,
0.59956347645825103, 0.60089231120396314, 0.60222276140534192,
0.60355483434528912, 0.60488853729099756, 0.60622387749428852,
0.60756086219194438, 0.60889949860603565, 0.61023979394424344,
0.61158175540017601, 0.61292539015368208, 0.61427070537115802,
0.6156177082058516, 0.61696640579815965, 0.6183168052759227,
0.61966891375471478, 0.62102273833812849, 0.62237828611805623,
0.62373556417496667, 0.62509457957817849, 0.62645533938612863,
0.62781785064663709, 0.62918212039716781, 0.63054815566508626,
0.6319159634679129, 0.63328555081357218, 0.6346569247006385,
0.63603009211858008, 0.63740506004799669, 0.63878183546085521,
0.64016042532072237, 0.6415408365829931, 0.64292307619511668,
0.6443071510968178, 0.64569306822031702, 0.64708083449054588,
0.64847045682536042, 0.64986194213575055, 0.65125529732604737,
0.65265052929412692, 0.65404764493161183, 0.6554466511240693,
0.65684755475120571, 0.65825036268706127, 0.65965508180019905,
0.66106171895389221, 0.662470281006309, 0.66388077481069574,
0.66529320721555585, 0.66670758506482708, 0.66812391519805636,
0.66954220445057289, 0.67096245965365731, 0.67238468763470993,
0.67380889521741538, 0.67523508922190711, 0.67666327646492708,
0.67809346375998514, 0.67952565791751507, 0.68095986574502998,
0.68239609404727364, 0.68383434962637157, 0.68527463928197874,
0.68671696981142683, 0.68816134800986772, 0.68960778067041639,
0.69105627458429097, 0.69250683654095235, 0.69395947332824071,
0.69541419173251007, 0.69687099853876222, 0.69832990053077826,
0.69979090449124826, 0.70125401720190006, 0.70271924544362507,
0.70418659599660338, 0.70565607564042798, 0.7071276911542258,
0.70860144931677771, 0.71007735690663842, 0.71155542070225308,
0.71303564748207338, 0.71451804402467189, 0.71600261710885549,
0.71748937351377728, 0.71897832001904627, 0.72046946340483764,
0.7219628104519995, 0.72345836794216134, 0.72495614265783725,
0.72645614138253245, 0.72795837090084514, 0.72946283799856926,
0.73096954946279535, 0.73247851208201098, 0.73398973264619938,
0.73550321794693774, 0.73701897477749423, 0.73853700993292459,
0.74005733021016773, 0.74157994240813974, 0.74310485332782839,
0.74463206977238605, 0.74616159854722175, 0.74769344646009417,
0.74922762032120138, 0.75076412694327244, 0.75230297314165728,
0.75384416573441693, 0.75538771154241147, 0.75693361738938991,
0.758481890102079, 0.76003253651027103, 0.76158556344691231,
0.76314097774819034, 0.76469878625362309, 0.7662589958061462,
0.76782161325220089, 0.769386645441822, 0.77095409922872682,
0.77252398147040302, 0.7740962990281981, 0.77567105876740827,
0.77724826755736875, 0.77882793227154423, 0.78041005978761957,
0.78199465698759218, 0.78358173075786475, 0.78517128798933999,
0.78676333557751388, 0.78835788042257371, 0.78995492942949441,
0.79155448950813945, 0.79315656757335906, 0.79476117054509521,
0.7963683053484848, 0.79797797891396693, 0.79959019817739119,
0.80120497008012925, 0.80282230156918943, 0.80444219959733254,
0.80606467112319224, 0.80768972311139808, 0.80931736253270259,
0.81094759636411085, 0.81258043158901505, 0.81421587519733385,
0.81585393418565533, 0.81749461555738445, 0.81913792632289761,
0.8207838734997005, 0.82243246411259396, 0.82408370519384444,
0.82573760378336281, 0.82739416692888867, 0.82905340168618369,
0.83071531511923258, 0.83237991430045299, 0.83404720631091445,
0.83571719824056667, 0.83738989718848023, 0.83906531026309572,
0.84074344458248718, 0.8424243072746378, 0.84410790547772752,
0.84579424634043732, 0.84748333702226764, 0.84917518469387376,
0.85086979653741857, 0.8525671797469434, 0.85426734152875994,
0.85597028910186379, 0.85767602969836843, 0.85938457056396655,
0.86109591895841553, 0.86281008215605082, 0.86452706744633134,
0.86624688213441292, 0.86796953354175987, 0.86969502900679097,
0.87142337588556507, 0.87315458155251024, 0.87488865340119604,
0.87662559884515645, 0.87836542531876505, 0.88010814027816542,
0.88185375120226295, 0.88360226559378352, 0.88535369098040029,
0.88710803491593926, 0.88886530498166649, 0.89062550878766356,
0.89238865397430212, 0.89415474821382124, 0.8959237992120197,
0.89769581471007132, 0.89947080248647626, 0.90124877035915674,
0.90302972618771449, 0.90481367787586209, 0.90660063337404539,
0.90839060068227462, 0.91018358785318598, 0.9119796029953533,
0.9137786542768791, 0.91558074992929017, 0.91738589825177019,
0.91919410761576692, 0.92100538647001218, 0.92281974334600192,
0.92463718686398877, 0.92645772573954432, 0.92828136879076073,
0.93010812494616935, 0.93193800325346221, 0.93377101288912279,
0.93560716316908266, 0.93744646356054107, 0.93928892369511052,
0.94113455338347296, 0.94298336263177085, 0.94483536165999271,
0.94669056092266257, 0.94854897113220671, 0.95041060328544014,
0.95227546869371049, 0.95414357901735647, 0.95601494630527861,
0.95788958304061456, 0.95976750219374951, 0.96164871728421064,
0.96353324245340688, 0.96542109255073427, 0.9673122832363088,
0.96920683110462647, 0.97110475383486783, 0.9730060703756126,
0.97491080117466045, 0.97681896846903671, 0.9787305966568961,
0.98064571278348434, 0.9825643471902451, 0.98448653440484979,
0.98641231440089083, 0.98834173445215634, 0.99027485200188514,
0.99221173940487462, 0.9941524925152051, 0.99609724852520865,
0.99804623294731343, 1, 1
), youden = c(
1, 1, 1.0044307210422965,
1.0094274716939247, 1.0144734471497678, 1.0194933498090266, 1.0244610079876548,
1.0293655397913963, 1.0342023155705522, 1.0389696509280195, 1.0436673673191279,
1.0482960917956901, 1.0528568892384893, 1.0573510584375778, 1.0617800146041969,
1.0661452199233414, 1.0704481419194454, 1.0746902284462514, 1.078872892861096,
1.0829975055540413, 1.0870653894920832, 1.0910778183166252, 1.0950360160641135,
1.0989411579093797, 1.1027943715397337, 1.1065967389020241, 1.110349298152471,
1.1140530456969664, 1.1177089382481817, 1.1213178948517963, 1.124880798851726,
1.1283984997761449, 1.1318718151341558, 1.135301532118411, 1.1386884092126344,
1.1420331777053885, 1.1453365431129841, 1.1485991865153686, 1.1518217658093717,
1.1550049168839418, 1.1581492547220806, 1.1612553744341134, 1.1643238522267958,
1.167355246312558, 1.1703500977629762, 1.1733089313102969, 1.1762322561006262,
1.1791205664021287, 1.1819743422713698, 1.1847940501806931, 1.1875801436093274,
1.190333063600709, 1.1930532392883304, 1.1957410883922395, 1.1983970176881695,
1.2010214234511158, 1.2036146918750537, 1.206177199470353, 1.2087093134403366,
1.2112113920383192, 1.213683784906366, 1.2161268333969213, 1.2185408708783667,
1.2209262230255045, 1.2232832080958753, 1.2256121371927722, 1.2279133145157322,
1.2301870375992536, 1.2324335975404168, 1.2346532792160534, 1.236846361490056,
1.2390131174113876, 1.2411538144033067, 1.2432687144442958, 1.2453580742411443,
1.2474221453946108, 1.2494611745580586, 1.2514754035894438, 1.2534650696969942,
1.2554304055789123, 1.2573716395574062, 1.2592889957073401, 1.2611826939797672,
1.263052950320608, 1.2648999767847062, 1.2667239816454929, 1.2685251695004667,
1.2703037413726921, 1.2720598948085047, 1.2737938239715989, 1.2755057197336712,
1.2771957697617669, 1.2788641586024949, 1.2805110677632401, 1.2821366757905124,
1.2837411583455578, 1.2853246882773561, 1.2868874356931104, 1.2884295680263453,
1.2899512501027091, 1.2914526442035832, 1.2929339101275845, 1.2943952052500545,
1.2958366845806131, 1.29725850081886, 1.298660804408295, 1.3000437435885355,
1.3014074644458877, 1.3027521109623503, 1.3040778250631004, 1.3053847466625292,
1.3066730137088762, 1.3079427622275208, 1.3091941263629825, 1.3104272384196713,
1.3116422289014458, 1.3128392265500113, 1.3140183583822131, 1.3151797497262534,
1.3163235242568785, 1.3174498040295715, 1.3185587095137838, 1.3196503596252431,
1.3207248717573656, 1.3217823618118092, 1.3228229442281922, 1.3238467320130105,
1.3248538367677771, 1.3258443687164119, 1.3268184367319087, 1.327776148362299,
1.328717609855941, 1.3296429261861524, 1.3305522010752096, 1.3314455370177349,
1.3323230353034901, 1.3331847960395944, 1.3340309181721897, 1.3348614995075643,
1.3356766367327564, 1.3364764254356527, 1.3372609601245973, 1.3380303342475244,
1.3387846402106347, 1.3395239693966223, 1.3402484121824689, 1.3409580579568221,
1.3416529951369627, 1.3423333111853779, 1.342999092625953, 1.343650425059788,
1.3442873931806545, 1.3449100807901018, 1.3455185708122199, 1.3461129453080751,
1.3466932854898197, 1.3472596717344913, 1.3478121835975081, 1.3483508998258673,
1.348875898371058, 1.3493872564016924, 1.3498850503158684, 1.3503693557532639,
1.3508402476069765, 1.351297800035113, 1.3517420864721337, 1.3521731796399594,
1.3525911515588511, 1.3529960735580584, 1.3533880162862562, 1.3537670497217618,
1.3541332431825492, 1.3544866653360581, 1.354827384208805, 1.3551554671958064,
1.3554709810698091, 1.355773991990342, 1.3560645655125869, 1.3563427665960797,
1.3566086596132361, 1.3568623083577187, 1.3571037760526385, 1.3573331253586005,
1.3575504183815967, 1.3577557166807483, 1.3579490812759025, 1.3581305726550865,
1.3583002507818218, 1.3584581751023039, 1.358604404552447, 1.3587389975648021,
1.3588620120753452, 1.3589735055301451, 1.3590735348919076, 1.3591621566464034,
1.3592394268087791, 1.3593054009297583, 1.3593601341017285, 1.3594036809647241,
1.3594360957123015, 1.359457432097313, 1.3594677434375777, 1.3594670826214581,
1.359455502113335, 1.3594330539589936, 1.3593997897909125, 1.3593557608334677,
1.3593010179080431, 1.3592356114380602, 1.3591595914539174, 1.3590730075978532,
1.3589759091287221, 1.3588683449266967, 1.3587503634978879, 1.3586220129788935,
1.3584833411412687, 1.3583343953959246, 1.3581752227974584, 1.3580058700484106,
1.3578263835034536, 1.3576368091735165, 1.3574371927298405, 1.3572275795079731,
1.3570080145116976, 1.3567785424169005, 1.3565392075753793, 1.3562900540185918,
1.3560311254613446, 1.3557624653054283, 1.3554841166431921, 1.3551961222610687,
1.3548985246430409, 1.3545913659740596, 1.3542746881434065, 1.3539485327480092,
1.3536129410957032, 1.3532679542084496, 1.3529136128255006, 1.3525499574065203,
1.3521770281346597, 1.3517948649195857, 1.3514035074004649, 1.3510029949489064,
1.3505933666718599, 1.3501746614144721, 1.3497469177629022, 1.3493101740470981,
1.34886446834353, 1.3484098384778895, 1.3479463220277452, 1.3474739563251652,
1.3469927784593012, 1.3465028252789346, 1.3460041333949904, 1.3454967391830128,
1.34498067878561, 1.344455988114861, 1.3439227028546936, 1.3433808584632274,
1.3428304901750845, 1.342271633003671, 1.3417043217434244, 1.341128590972035,
1.3405444750526327, 1.3399520081359482, 1.3393512241624426, 1.3387421568644124,
1.3381248397680616, 1.3374993061955509, 1.3368655892670178, 1.3362237219025705,
1.335573736824256, 1.3349156665580026, 1.3342495434355373, 1.3335753995962785,
1.332893266989204, 1.3322031773746952, 1.3315051623263578, 1.3307992532328203,
1.3300854812995067, 1.3293638775503918, 1.3286344728297284, 1.3278972978037582,
1.3271523829623983, 1.3263997586209071, 1.32563945492153, 1.3248715018351245,
1.3240959291627659, 1.3233127665373319, 1.3225220434250695, 1.3217237891271405,
1.3209180327811509, 1.3201048033626606, 1.3192841296866729, 1.3184560404091099,
1.317620564028267, 1.3167777288862517, 1.3159275631704039, 1.3150700949147018,
1.3142053520011472, 1.3133333621611385, 1.3124541529768257, 1.311567751882448,
1.3106741861656588, 1.3097734829688339, 1.3088656692903631, 1.3079507719859294,
1.3070288177697711, 1.3060998332159313, 1.3051638447594918, 1.3042208786977927,
1.30327096119164, 1.3023141182664966, 1.3013503758136624, 1.300379759591439,
1.2994022952262834, 1.2984180082139463, 1.2974269239205993, 1.2964290675839496,
1.2954244643143413, 1.2944131390958447, 1.2933951167873339, 1.2923704221235526,
1.2913390797161672, 1.2903011140548095, 1.2892565495081074, 1.2882054103247031,
1.2871477206342632, 1.2860835044484751, 1.2850127856620335, 1.2839355880536156,
1.2828519352868468, 1.2817618509112563, 1.2806653583632195, 1.2795624809668946,
1.2784532419351446, 1.2773376643704533, 1.2762157712658293, 1.2750875855057011,
1.2739531298668019, 1.272812427019046, 1.2716654995263954, 1.2705123698477174,
1.2693530603376317, 1.2681875932473516, 1.2670159907255127, 1.2658382748189958,
1.264654467473739, 1.2634645905355426, 1.2622686657508648, 1.2610667147676087,
1.2598587591359021, 1.258644820308868, 1.257424919643388, 1.2561990784008557,
1.254967317747925, 1.2537296587572477, 1.2524861224082051, 1.2512367295876303,
1.249981501090526, 1.2487204576207691, 1.247453619791814, 1.2461810081273841,
1.244902643062157, 1.2436185449424428, 1.2423287340268563, 1.2410332304869776,
1.2397320544080106, 1.2384252257894313, 1.2371127645456295, 1.2357946905065444,
1.2344710234182918, 1.2331417829437852, 1.2318069886633485, 1.2304666600753249,
1.2291208165966749, 1.2277694775635708, 1.2264126622319818, 1.225050389778253,
1.2236826792996789, 1.2223095498150685, 1.2209310202653034, 1.2195471095138903,
1.2181578363475056, 1.2167632194765337, 1.215363277535598, 1.2139580290840852,
1.2125474926066631, 1.2111316865137904, 1.2097106291422208, 1.2082843387554987,
1.2068528335444493, 1.2054161316276599, 1.2039742510519567, 1.2025272097928688,
1.201075025755094, 1.1996177167729472, 1.1981553006108077, 1.1966877949635581,
1.1952152174570128, 1.1937375856483412, 1.1922549170264825, 1.1907672290125508,
1.1892745389602355, 1.1877768641561883, 1.1862742218204063, 1.1847666291066041,
1.1832541031025769, 1.1817366608305548, 1.1802143192475483, 1.1786870952456825,
1.1771550056525237, 1.1756180672313941, 1.1740762966816756, 1.172529710639105,
1.1709783256760555, 1.1694221583018085, 1.1678612249628124, 1.1662955420429291,
1.1647251258636684, 1.1631499926844073, 1.1615701587025982, 1.1599856400539597,
1.1583964528126538, 1.1568026129914479, 1.1552041365418586, 1.1536010393542804,
1.1519933372580946, 1.1503810460217598, 1.1487641813528842, 1.1471427588982741,
1.1455167942439635, 1.1438863029152186, 1.1422513003765187, 1.1406118020315121,
1.1389678232229437, 1.1373193792325542, 1.1356664852809508, 1.1340091565274431,
1.1323474080698457, 1.1306812549442464, 1.1290107121247335, 1.1273357945230826,
1.125656516988401, 1.123972894306724, 1.1222849412005624, 1.1205926723283957,
1.1188961022841086, 1.1171952455963683, 1.1154901167279319, 1.1137807300748883,
1.1120670999658211, 1.1103492406608897, 1.1086271663508254, 1.1069008911558291,
1.1051704291243682, 1.1034357942318616, 1.1016970003792448, 1.0999540613914027,
1.0982069910154628, 1.0964558029189304, 1.0947005106876582, 1.0929411278236281,
1.0911776677425351, 1.089410143771147, 1.0876385691444246, 1.0858629570023726,
1.0840833203865992, 1.0822996722365508, 1.0805120253853884, 1.0787203925554671,
1.0769247863533753, 1.0751252192644822, 1.0733217036469394, 1.0715142517250686,
1.0697028755820639, 1.067887587151922, 1.066068398210501, 1.0642453203655959,
1.0624183650458954, 1.0605875434886689, 1.0587528667259973, 1.0569143455693404,
1.0550719905921819, 1.0532258121104592, 1.0513758201604106, 1.0495220244734182,
1.0476644344473174, 1.0458030591135425, 1.0439379070993264, 1.0420689865839965,
1.0401963052481618, 1.0383198702142882, 1.0364396879767441, 1.0345557643188585,
1.0326681042138011, 1.0307767117050817, 1.0288815897610613, 1.026982740095872,
1.0250801629462349, 1.0231738567893722, 1.0212638179806417, 1.0193500402792397,
1.0174325142135636, 1.015511226209483, 1.0135861573542995, 1.0116572815739022,
1.0097245628067317, 1.007787950323862, 1.0058473702364801, 1.00390270781663,
1.0019537608273299, 1, 1
), closest.topleft = c(
1, 1, 0.98726929553784371,
0.97351057857847734, 0.95975977958582082, 0.94616544196435937,
0.93277702442373811, 0.91961322535069245, 0.90668026165222926,
0.89397855620461208, 0.88150564259267084, 0.86925757207804855,
0.85722964716818517, 0.84541682386883432, 0.83381393966656903,
0.82241584507735643, 0.811217479719476, 0.8002139155196264, 0.78940038002498947,
0.77877226750347228, 0.7683251424995845, 0.75805473874081408,
0.74795695521906247, 0.73802785061074905, 0.72826363678319861,
0.71866067186889837, 0.70921545321689461, 0.69992461041777077,
0.69078489852429326, 0.68179319154052731, 0.67294647621957038,
0.66424184618843662, 0.65567649640445691, 0.64724771793842695,
0.63895289307397529, 0.63078949070918722, 0.62275506204462772,
0.61484723654107176, 0.6070637181301094, 0.59940228166109211,
0.59186076956847966, 0.58443708874441491, 0.57712920760221986,
0.56993515331738098, 0.56285300923350701, 0.55588091242162074,
0.54901705138198831, 0.54225966387849278, 0.53560703489631023,
0.5290574947143567, 0.52260941708462538, 0.51626121751113707,
0.51001135162179023, 0.50385831362691058, 0.49780063485877213,
0.49183688238680612, 0.48596565770360034, 0.48018559547716871,
0.4744953623653132, 0.46889365588819121, 0.46337920335550936,
0.4579507608449998, 0.4526071122291061, 0.44734706824699355,
0.44216946561922621, 0.43707316620262476, 0.43205705618300244,
0.42712004530362213, 0.42226106612737302, 0.41747907333079626,
0.41277304302821455, 0.40814197212433184, 0.40358487769377976,
0.39910079638618162, 0.39468878385540185, 0.39034791421172371,
0.38607727949578496, 0.38187598917316667, 0.37774316964860333,
0.37367796379884372, 0.36967953052324248, 0.36574704431122923,
0.36187969482584431, 0.35807668650257468, 0.35433723816277929,
0.35066058264101591, 0.3470459664256399, 0.3434926493120638,
0.33999990406811126, 0.33656701611092177, 0.3331932831948996,
0.32987801511022441, 0.32662053339146069, 0.32342017103583848,
0.32027627223079247, 0.31718819209037064, 0.31415529640014006,
0.3111769613702432, 0.3082525733962676, 0.3053815288276161, 0.30256323374307242,
0.29979710373327739, 0.29708256368984415, 0.29441904760085358,
0.29180599835247784, 0.28924286753650341, 0.28672911526352307,
0.28426420998158919, 0.28184762830011545, 0.27947885481884155,
0.27715738196166684, 0.27488270981518148, 0.27265434597172034,
0.27047180537677873, 0.26833461018063731, 0.266242289594044,
0.26419437974781246, 0.26219042355620037, 0.26022997058393854,
0.25831257691678483, 0.25643780503548286, 0.25460522369301208,
0.2528144077950179, 0.25106493828331872, 0.24935640202238482,
0.24768839168869566, 0.2460605056628796, 0.24447234792454883,
0.24292352794974181, 0.24141366061088909, 0.23994236607922809,
0.23850926972958358, 0.23711400204744676, 0.23575619853827598,
0.23443549963895738, 0.23315155063135429, 0.23190400155788579,
0.23069250713907166, 0.22951672669298712, 0.22837632405656835,
0.22727096750871684, 0.22620032969514789, 0.22516408755493533,
0.22416192224870019, 0.22319351908839954, 0.22225856746866843,
0.22135676079967065, 0.22048779644141686, 0.21965137563950932,
0.2188472034622726, 0.21807498873923292, 0.21733444400090962,
0.21662528541988157, 0.2159472327530958, 0.21530000928538334,
0.21468334177415205, 0.21409696039522291, 0.21354059868978142,
0.21301399351241351, 0.21251688498019927, 0.21204901642283544,
0.21161013433376091, 0.21119998832226025, 0.21081833106651859,
0.21046491826760563, 0.21013950860436426, 0.20984186368918137,
0.20957174802461884, 0.20932892896088467, 0.20911317665412046,
0.20892426402548922, 0.20876196672104086, 0.20862606307233827,
0.20851633405782516, 0.20843256326491727, 0.20837453685280111,
0.20834204351592273, 0.20833487444814941, 0.20835282330759006,
0.20839568618205789, 0.20846326155516093, 0.20855535027300592,
0.20867175551150091, 0.20881228274424374, 0.20897673971098263,
0.2091649363866358, 0.20937668495085776, 0.20961179975814048,
0.20987009730843642, 0.21015139621829326, 0.21045551719248728,
0.21078228299614671, 0.21113151842735212, 0.21150305029020516,
0.21189670736835431, 0.21231232039896902, 0.21274972204715115,
0.21320874688077612, 0.21368923134575302, 0.21419101374169583,
0.21471393419799722, 0.21525783465029563, 0.21582255881732801,
0.21640795217816056, 0.21701386194978911, 0.21764013706510177,
0.21828662815119598, 0.21895318750804424, 0.21963966908749899,
0.22034592847263282, 0.22107182285740426, 0.2218172110266452,
0.22258195333636122, 0.22336591169434131, 0.22416894954106809,
0.22499093183092447, 0.22583172501369073, 0.22669119701632556,
0.22756921722502613, 0.22846565646756198, 0.22938038699587709,
0.23031328246895527, 0.23126421793594351, 0.23223306981952835,
0.23321971589956164, 0.23422403529692931, 0.23524590845765958,
0.23628521713726608, 0.23734184438532085, 0.23841567453025497,
0.23950659316437928, 0.24061448712912381, 0.24173924450049189,
0.24288075457472311, 0.24403890785416299, 0.24521359603333542,
0.24640471198521308, 0.24761214974768458, 0.24883580451021187,
0.25007557260067692, 0.2513313514724132, 0.25260303969141906,
0.25389053692374963, 0.25519374392308392, 0.25651256251846483,
0.25784689560220808, 0.25919664711797813, 0.260561722049027,
0.26194202640659414, 0.26333746721846518, 0.26474795251768446,
0.26617339133142159, 0.267613693669987, 0.26906877051599648,
0.27053853381367937, 0.27202289645833017, 0.27352177228590036,
0.27503507606272803, 0.27656272347540362, 0.27810463112076816,
0.27966071649604324, 0.28123089798909101, 0.28281509486879952,
0.28441322727559337, 0.28602521621206833, 0.28765098353374596,
0.28929045193994696, 0.29094354496478192, 0.29261018696825714,
0.29429030312749427, 0.29598381942806085, 0.29769066265541039,
0.299410760386431, 0.30114404098110081, 0.30289043357424689,
0.30464986806740757, 0.30642227512079689, 0.30820758614536803,
0.31000573329497577, 0.31181664945863474, 0.31364026825287378,
0.3154765240141843, 0.31732535179156041, 0.31918668733912992,
0.3210604671088757, 0.32294662824344522, 0.32484510856904619,
0.3267558465884286, 0.32867878147395074, 0.33061385306072866,
0.33256100183986714, 0.33452016895177134, 0.33649129617953771,
0.33847432594242383, 0.34046920128939495, 0.34247586589274565,
0.34449426404179839, 0.3465243406366737, 0.3485660411821348,
0.35061931178150235, 0.35268409913064119, 0.35476035051201577,
0.35684801378881492, 0.35894703739914363, 0.36105737035028079,
0.36317896221300522, 0.36531176311598373, 0.36745572374022434,
0.36961079531359203, 0.37177692960538739, 0.37395407892098559,
0.37614219609653576, 0.37834123449372004, 0.3805511479945719,
0.38277189099635184, 0.38500341840647956, 0.38724568563752321,
0.38949864860224431, 0.39176226370869699, 0.3940364878553807,
0.39632127842644749, 0.3986165932869607, 0.40092239077820646,
0.40323862971305507, 0.40556526937137383, 0.40790226949548958,
0.41024959028570007, 0.41260719239583332, 0.41497503692885546,
0.41735308543252597, 0.41974129989509867, 0.42213964274106863,
0.4245480768269651, 0.42696656543718919, 0.42939507227989399,
0.43183356148291152, 0.43428199758971864, 0.43674034555544827,
0.43920857074294217, 0.44168663891884402, 0.44417451624973286,
0.44667216929829973, 0.44917956501956058, 0.45169667075711012,
0.45422345423941435, 0.45675988357614161, 0.45930592725453051,
0.46186155413579533, 0.46442673345156893, 0.4670014348003817,
0.46958562814417609, 0.47217928380485635, 0.47478237246087451,
0.47739486514384927, 0.48001673323522004, 0.48264794846293485,
0.48528848289817095, 0.48793830895208773, 0.49059739937261415,
0.49326572724126588, 0.49594326596999516, 0.49862998929807284,
0.50132587128899952, 0.50403088632744808, 0.50674500911623721,
0.50946821467333214, 0.51220047832887883, 0.51494177572226296,
0.51769208279919998, 0.52045137580885392, 0.52321963130098292,
0.52599682612311238, 0.5287829374177363, 0.53157794261954616,
0.53438181945268481, 0.53719454592802762, 0.54001610034049019,
0.54284646126636094, 0.54568560756066009, 0.54853351835452291,
0.55139017305260773, 0.55425555133052995, 0.55712963313231922,
0.56001239866789954, 0.5629038284105965, 0.56580390309466322,
0.56871260371283472, 0.57162991151390008, 0.57455580800030093,
0.57749027492575089, 0.58043329429287749, 0.58338484835088511,
0.58634491959324042, 0.58931349075537864, 0.59229054481243248,
0.59527606497697905, 0.59827003469680962, 0.60127243765271954,
0.60428325775631808, 0.6073024791478574, 0.61033008619408224,
0.61336606348609934, 0.61641039583726576, 0.61946306828109488,
0.62252406606918365, 0.62559337466915732, 0.62867097976263253,
0.63175686724319746, 0.63485102321441367, 0.63795343398783189,
0.64106408608102605, 0.64418296621564797, 0.64731006131549451,
0.65044535850459595, 0.65358884510531856, 0.65674050863648481,
0.65990033681151028, 0.66306831753655604, 0.66624443890869889,
0.66942868921411491, 0.67262105692628182, 0.67582153070419382,
0.67903009939059544, 0.68224675201022644, 0.68547147776808581,
0.68870426604770907, 0.69194510640945928, 0.69519398858883441,
0.69845090249478792, 0.7017158382080656, 0.70498878597955406,
0.70826973622864475, 0.71155867954161145, 0.71485560667000259,
0.71816050852904456, 0.72147337619606189, 0.72479420090890823,
0.72812297406440962, 0.73145968721682653, 0.7348043320763199,
0.73815690050743843, 0.74151738452761384, 0.74488577630566866,
0.74826206816033913, 0.75164625255880746, 0.75503832211524835,
0.75843826958938665, 0.76184608788506691, 0.76526177004883456,
0.76868530926852996, 0.7721166988718926, 0.77555593232517717,
0.77900300323178306, 0.78245790533089066, 0.7859206324961141,
0.78939117873416109, 0.79286953818350558, 0.79635570511307163,
0.79984967392092698, 0.80335143913298779, 0.80686099540173428,
0.81037833750493782, 0.81390346034439665, 0.81743635894468269,
0.82097702845190079, 0.82452546413245487, 0.82808166137182759,
0.83164561567336814, 0.83521732265709181, 0.8387967780584874,
0.84238397772733897, 0.84597891762655242, 0.84958159383099752,
0.85319200252635596, 0.85681014000798206, 0.86043600267977327,
0.86406958705305037, 0.86771088974544786, 0.87135990747981706,
0.87501663708313582, 0.87868107548543339, 0.88235321971872249,
0.88603306691594508, 0.8897206143099281, 0.89341585923235067,
0.89711879911272396, 0.90082943147738426, 0.9045477539484964,
0.90827376424307338, 0.9120074601720074, 0.91574883963911857,
0.91949790064021675, 0.9232546412621826, 0.92701905968206499,
0.93079115416619973, 0.93457092306934897, 0.93835836483386659,
0.94215347798888771, 0.94595626114955267, 0.94976671301626303,
0.95358483237398151, 0.95741061809157779, 0.96124406912123594,
0.96508518449792924, 0.96893396333898918, 0.9727904048437841,
0.97665450829355205, 0.98052627305143758, 0.98440569856282378,
0.98829278435610868, 0.99218753004421767, 0.99608993532749601,
1, 1
)), class = "data.frame", row.names = c(NA, -514L))
pROC/tests/testthat/test-roc.utils.percent.R 0000644 0001762 0000144 00000004510 15040443562 020543 0 ustar ligges users library(pROC)
data(aSAH)
context("roc.utils.percent")
test_that("roc_utils_topercent works on full AUC", {
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r.wfns), r.wfns.percent)
})
test_that("roc_utils_unpercent works on full AUC", {
expect_equal_ignore_call(pROC:::roc_utils_unpercent.roc(r.wfns.percent), r.wfns)
})
test_that("roc_utils_topercent works on partial AUC", {
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r.wfns.partial1), r.wfns.percent.partial1)
})
test_that("roc_utils_unpercent works on partial AUC", {
expect_equal_ignore_call(pROC:::roc_utils_unpercent.roc(r.wfns.percent.partial1), r.wfns.partial1)
})
test_that("roc_utils_topercent works with CI", {
r <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE)
r.percent <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE, percent = TRUE)
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r), r.percent)
})
test_that("roc_utils_unpercent works with CI", {
r <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE)
r.percent <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE, percent = TRUE)
expect_equal_ignore_call(pROC:::roc_utils_unpercent.roc(r.percent), r)
})
test_that("roc_utils_topercent works without AUC", {
r <- roc(aSAH$outcome, aSAH$wfns, auc = FALSE)
r.percent <- roc(aSAH$outcome, aSAH$wfns, auc = FALSE, percent = TRUE)
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r), r.percent)
})
test_that("roc_utils_unpercent works without AUC", {
r <- roc(aSAH$outcome, aSAH$wfns, auc = FALSE)
r.percent <- roc(aSAH$outcome, aSAH$wfns, auc = FALSE, percent = TRUE)
expect_equal_ignore_call(pROC:::roc_utils_unpercent.roc(r.percent), r)
})
test_that("roc_utils_topercent works with different types of CI", {
r <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE)
r.percent <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE, percent = TRUE)
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r), r.percent)
})
test_that("roc.utils.to/unpercent works with ci .thresholds, .sp, .se", {
skip_slow()
for (of in c("thresholds", "sp", "se")) {
set.seed(42)
r <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE, of = of)
set.seed(42)
r.percent <- roc(aSAH$outcome, aSAH$wfns, ci = TRUE, percent = TRUE, of = of)
expect_equal_ignore_call(pROC:::roc_utils_unpercent.roc(r.percent), r)
expect_equal_ignore_call(pROC:::roc_utils_topercent.roc(r), r.percent)
}
})
pROC/tests/testthat/test-smooth.R 0000644 0001762 0000144 00000007455 15040443562 016506 0 ustar ligges users library(pROC)
data(aSAH)
context("smooth")
# Define some density functions
unif.density <- function(x, n, from, to, bw, kernel, ...) {
smooth.x <- seq(from = from, to = to, length.out = n)
smooth.y <- dunif(smooth.x, min = min(x), max = max(x))
return(smooth.y)
}
norm.density <- function(x, n, from, to, bw, kernel, ...) {
smooth.x <- seq(from = from, to = to, length.out = n)
smooth.y <- dnorm(smooth.x, mean = mean(x), sd = sd(x))
return(smooth.y)
}
lnorm.density <- function(x, n, from, to, bw, kernel, ...) {
smooth.x <- seq(from = from, to = to, length.out = n)
smooth.y <- dlnorm(smooth.x, meanlog = mean(x), sdlog = sd(x))
return(smooth.y)
}
test_that("We fall back to the standard smooth", {
tukey <- smooth(c(4, 1, 3, 6, 6, 4, 1, 6, 2, 4, 2))
expect_is(tukey, "tukeysmooth")
expect_equal(as.numeric(tukey), c(3, 3, 3, 3, 4, 4, 4, 4, 2, 2, 2))
})
test_that("smooth with a density function works", {
smoothed <- smooth(r.ndka, method = "density", density = unif.density, n = 10)
expect_is(smoothed, "smooth.roc")
expect_equal(smoothed$sensitivities, c(1, 1, 1, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125, 0, 0))
expect_equal(smoothed$specificities, c(0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1))
expect_equal(as.numeric(smoothed$auc), 0.9375)
})
test_that("smooth with two density functions works", {
smoothed <- smooth(r.ndka, method = "density", density.controls = norm.density, density.cases = lnorm.density, n = 10)
expect_is(smoothed, "smooth.roc")
expect_equal(smoothed$sensitivities, c(
1, 1, 1, 0.635948942024884, 0.460070154191559, 0.344004532431686,
0.25735248652959, 0.188201024566009, 0.130658598389315, 0.0813814489619488,
0.0382893349015216, 0
))
expect_equal(smoothed$specificities, c(0, 0, 0.832138478872629, 0.99999996787709, 1, 1, 1, 1, 1, 1, 1, 1))
expect_equal(as.numeric(smoothed$auc), 0.9694449)
})
test_that("smooth with fitdistr works", {
smoothed <- smooth(r.ndka, method = "fitdistr", n = 10)
expect_is(smoothed, "smooth.roc")
expect_equal(smoothed$sensitivities, c(
1, 1, 0.65584212882921, 0.303849532306639, 0.0922807400203477,
0.017547821937714, 0.00203415264061833, 0.000141550295211778,
5.86072275643637e-06, 1.43622216786009e-07, 2.05997195401133e-09,
0
))
expect_equal(smoothed$specificities, c(
0, 0, 0.961731211013412, 0.999999997253703, 1, 1, 1, 1, 1,
1, 1, 1
))
expect_equal(as.numeric(smoothed$auc), 0.814600645965216)
})
test_that("smooth with fitdistr different densities works", {
smoothed <- smooth(r.ndka, method = "fitdistr", density.controls = "normal", density.cases = "lognormal", n = 10)
expect_is(smoothed, "smooth.roc")
expect_equal(smoothed$sensitivities, c(
1, 1, 0.174065394158716, 0.0241224684680268, 0.00565556180305715,
0.0017644346804079, 0.000654794610631603, 0.000269912354252342,
0.000116632088037343, 4.89426737202444e-05, 1.6544031070368e-05,
0
))
expect_equal(smoothed$specificities, c(
0, 0, 0.961731211013412, 0.999999997253703, 1, 1, 1, 1, 1,
1, 1, 1
))
expect_equal(as.numeric(smoothed$auc), 0.568359871182632)
})
test_that("smooth with fitdistr with a density function works", {
smoothed <- smooth(r.ndka,
method = "fitdistr", n = 10,
density.controls = dnorm, start.controls = list(mean = 10, sd = 10),
density.cases = dlnorm, start = list(meanlog = 2.7, sdlog = .822)
)
expect_is(smoothed, "smooth.roc")
expect_equal(smoothed$sensitivities, c(
1, 1, 0.174065542189585, 0.0241224212514905, 0.00565553823693818,
0.00176442417351747, 0.000654789746505889, 0.000269910020195159,
0.000116630962648119, 4.8942161699917e-05, 1.65438472509127e-05,
0
))
expect_equal(smoothed$specificities, c(
0, 0, 0.961730914432089, 0.999999997253745, 1, 1, 1, 1, 1,
1, 1, 1
))
expect_equal(as.numeric(smoothed$auc), 0.568359799581078)
})
pROC/tests/testthat/test-roc.test.R 0000644 0001762 0000144 00000030167 15040443562 016732 0 ustar ligges users library(pROC)
data(aSAH)
context("roc.test")
# define variables shared among multiple tests here
roc.test_env <- environment()
test_that("roc.test works", {
roc.test_env$t1 <- roc.test(r.wfns, r.s100b)
roc.test_env$t2 <- roc.test(r.wfns, r.ndka)
roc.test_env$t3 <- roc.test(r.ndka, r.s100b)
expect_is(t1, "htest")
expect_is(t2, "htest")
expect_is(t3, "htest")
})
test_that("DeLong roc.test works when curves are identical", {
t4 <- roc.test(r.wfns, r.wfns)
expect_is(t4, "htest")
expect_equal(t4$p.value, 1)
expect_equal(t4$statistic, c(Z = 0))
})
test_that("roc.test statistic and p are as expected with defaults", {
expect_equal(t1$statistic, c(Z = 2.20898359144091))
expect_equal(t1$p.value, 0.0271757822291882)
expect_equal(t1$conf.int[[1]], 0.0104061769564846)
expect_equal(t1$conf.int[[2]], 0.174214419249478)
expect_match(t1$method, "DeLong")
expect_match(t1$method, "correlated")
expect_identical(t1$alternative, "two.sided")
expect_identical(attr(t1$conf.int, "conf.level"), 0.95)
expect_equal(t2$statistic, c(Z = 2.79777591868904))
expect_equal(t2$p.value, 0.00514557970691098)
expect_equal(t2$conf.int[[1]], 0.0634011709339876)
expect_equal(t2$conf.int[[2]], 0.3600405634833566)
expect_match(t2$method, "DeLong")
expect_match(t2$method, "correlated")
expect_identical(t2$alternative, "two.sided")
expect_identical(attr(t2$conf.int, "conf.level"), 0.95)
expect_equal(t3$statistic, c(Z = -1.39077002573558))
expect_equal(t3$p.value, 0.164295175223054)
expect_equal(t3$conf.int[[1]], -0.2876917446341914)
expect_equal(t3$conf.int[[2]], 0.0488706064228094)
expect_match(t3$method, "DeLong")
expect_match(t3$method, "correlated")
expect_identical(t3$alternative, "two.sided")
expect_identical(attr(t3$conf.int, "conf.level"), 0.95)
})
test_that("two.sided roc.test produces identical p values when roc curves are reversed", {
t1b <- roc.test(r.s100b, r.wfns)
expect_equal(t1b$p.value, t1$p.value)
expect_equal(t1b$statistic, -t1$statistic)
t2b <- roc.test(r.ndka, r.wfns)
expect_equal(t2b$p.value, t2$p.value)
expect_equal(t2b$statistic, -t2$statistic)
t3b <- roc.test(r.s100b, r.ndka)
expect_equal(t3b$p.value, t3$p.value)
expect_equal(t3b$statistic, -t3$statistic)
})
test_that("unpaired roc.test works", {
# Warns about pairing
expect_warning(roc.test_env$t1up <- roc.test(r.wfns, r.s100b, paired = FALSE))
expect_warning(roc.test_env$t2up <- roc.test(r.wfns, r.ndka, paired = FALSE))
expect_warning(roc.test_env$t3up <- roc.test(r.ndka, r.s100b, paired = FALSE))
})
test_that("unpaired roc.test statistic and p are as expected", {
expect_equal(t1up$statistic, c(D = 1.43490640926908))
expect_equal(t1up$p.value, 0.152825378808796)
expect_match(t1up$method, "DeLong")
expect_identical(t1up$alternative, "two.sided")
expect_equal(t2up$statistic, c(D = 3.10125096778969))
expect_equal(t2up$p.value, 0.00220950791756457)
expect_match(t2up$method, "DeLong")
expect_identical(t2up$alternative, "two.sided")
expect_equal(t3up$statistic, c(D = -1.55995743389685))
expect_equal(t3up$p.value, 0.120192832430845)
expect_match(t3up$method, "DeLong")
expect_identical(t3up$alternative, "two.sided")
})
test_that("unpaired two.sided roc.test produces identical p values when roc curves are reversed", {
expect_warning(t1upb <- roc.test(r.s100b, r.wfns, paired = FALSE))
expect_equal(t1upb$p.value, t1up$p.value)
expect_equal(t1upb$statistic, -t1up$statistic)
expect_warning(t2upb <- roc.test(r.ndka, r.wfns, paired = FALSE))
expect_equal(t2upb$p.value, t2up$p.value)
expect_equal(t2upb$statistic, -t2up$statistic)
expect_warning(t3upb <- roc.test(r.s100b, r.ndka, paired = FALSE))
expect_equal(t3upb$p.value, t3up$p.value)
expect_equal(t3upb$statistic, -t3up$statistic)
})
test_that("one-sided roc.test work and produce expected results", {
t1gt <- roc.test(r.wfns, r.s100b, alternative = "greater")
t1lt <- roc.test(r.wfns, r.s100b, alternative = "less")
expect_equal(t1gt$statistic, t1$statistic)
expect_equal(t1lt$statistic, t1$statistic)
expect_equal(t1gt$p.value, 0.0135878911145941)
expect_equal(t1lt$p.value, 0.986412108885406)
expect_match(t1gt$method, "DeLong")
expect_match(t1gt$method, "correlated")
expect_identical(t1gt$alternative, "greater")
expect_match(t1lt$method, "DeLong")
expect_match(t1lt$method, "correlated")
expect_identical(t1lt$alternative, "less")
})
test_that("unpaired one-sided roc.test work and produce expected results", {
expect_warning(t1upgt <- roc.test(r.wfns, r.s100b, alternative = "greater", paired = FALSE))
expect_warning(t1uplt <- roc.test(r.wfns, r.s100b, alternative = "less", paired = FALSE))
expect_equal(t1upgt$statistic, t1up$statistic)
expect_equal(t1uplt$statistic, t1up$statistic)
expect_equal(t1upgt$p.value, 0.076412689404398)
expect_equal(t1uplt$p.value, 0.923587310595602)
expect_match(t1upgt$method, "DeLong")
expect_identical(t1upgt$alternative, "greater")
expect_match(t1uplt$method, "DeLong")
expect_identical(t1uplt$alternative, "less")
})
test_that("roc.formula works", {
expect_silent(t1c <- roc.test(aSAH$outcome ~ aSAH$wfns + aSAH$s100b, quiet = TRUE)) # make sure silent is passed
expect_equal(t1c$statistic, t1$statistic)
expect_equal(t1c$p.value, t1$p.value)
expect_match(t1$method, "DeLong")
expect_match(t1$method, "correlated")
expect_identical(t1$alternative, "two.sided")
expect_warning(t1upc <- roc.test(aSAH$outcome ~ aSAH$wfns + aSAH$s100b, quiet = TRUE, paired = FALSE))
expect_equal(t1upc$statistic, t1up$statistic)
expect_equal(t1upc$p.value, t1up$p.value)
expect_match(t1upc$method, "DeLong")
expect_identical(t1upc$alternative, "two.sided")
})
test_that("roc.formula supports subset and na.omit", {
check.only.items <- c("p.value", "statistic")
expect_identical(
roc.test(outcome ~ wfns + ndka, data = aSAH, subset = (gender == "Female"), quiet = TRUE)[check.only.items],
roc.test(aSAH$outcome[aSAH$gender == "Female"], aSAH$wfns[aSAH$gender == "Female"], aSAH$ndka[aSAH$gender == "Female"], quiet = TRUE)[check.only.items]
)
# Generate missing values
aSAH.missing <- aSAH
aSAH.missing$wfns[1:20] <- NA
aSAH.missing$ndka[1:20] <- NA
expect_warning(roctest1 <- roc.test(outcome ~ wfns + ndka, data = aSAH.missing, na.action = na.omit, quiet = TRUE), "na.omit")
roctest2 <- roc.test(aSAH$outcome[21:113], aSAH$wfns[21:113], aSAH$ndka[21:113], quiet = TRUE)
expect_identical(
roctest1[check.only.items],
roctest2[check.only.items]
)
# na.fail should fail
expect_error(roc.test(outcome ~ wfns + ndka, data = aSAH.missing, na.action = na.fail, quiet = TRUE))
# weights should fail too
expect_error(roc.test(outcome ~ wfns + ndka, data = aSAH, weights = seq_len(nrow(aSAH))), regexp = "weights are not supported")
# Both na.action and subset
expect_warning(roctest1 <- roc.test(outcome ~ wfns + ndka, data = aSAH.missing, na.action = na.omit, subset = (gender == "Female"), quiet = TRUE), "na.omit")
roctest2 <- roc.test(aSAH$outcome[21:113][aSAH[21:113, ]$gender == "Female"], aSAH$wfns[21:113][aSAH[21:113, ]$gender == "Female"], aSAH$ndka[21:113][aSAH[21:113, ]$gender == "Female"], quiet = TRUE)
expect_identical(
roctest1[check.only.items],
roctest2[check.only.items]
)
})
test_that("paired tests don't work on unpaired curves", {
# Make an unpaired ROC curve
up.r.ndka <- roc(controls = aSAH$ndka[aSAH$outcome == "Good"], cases = aSAH$ndka[aSAH$outcome == "Poor"], quiet = TRUE)
# unpaired by default
t4 <- roc.test(r.wfns, up.r.ndka)
expect_false(grepl("correlated", t4$method))
# Shoud be an error:
expect_error(roc.test(r.wfns, up.r.ndka, paired = TRUE))
})
test_that("one-sided roc.test work with direction='>' and produce expected results", {
r.mwfns <- roc(aSAH$outcome, -as.numeric(aSAH$wfns))
r.ms100b <- roc(aSAH$outcome, -aSAH$s100b)
## We already tested those before:
# t1gt <- roc.test(r.wfns, r.s100b, alternative = "greater")
# t1lt <- roc.test(r.wfns, r.s100b, alternative = "less")
# Test with inverted direction
m1gt <- roc.test(r.mwfns, r.ms100b, alternative = "greater")
m1lt <- roc.test(r.mwfns, r.ms100b, alternative = "less")
expect_equal(m1gt$statistic, t1$statistic)
expect_equal(m1lt$statistic, t1$statistic)
expect_equal(m1gt$p.value, 0.0135878911145941)
expect_equal(m1lt$p.value, 0.986412108885406)
})
test_that("paired roc.test works with bootstrap", {
skip_slow()
ht <- roc.test(r.wfns, r.s100b, method = "bootstrap", boot.n = 12, paired = TRUE)
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Bootstrap test for two correlated ROC curves")
expect_equal(unname(ht$parameter), c(12, 1))
})
test_that("unpaired roc.test works with bootstrap", {
skip_slow()
expect_warning(ht <- roc.test(r.s100b, r.wfns, method = "bootstrap", boot.n = 12, paired = FALSE), "paired")
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Bootstrap test for two ROC curves")
expect_equal(unname(ht$parameter), c(12, 1))
})
test_that("paired, non stratified roc.test works with bootstrap", {
skip_slow()
ht <- roc.test(r.s100b, r.wfns, method = "bootstrap", boot.n = 12, paired = TRUE, boot.stratified = FALSE)
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Bootstrap test for two correlated ROC curves")
expect_equal(unname(ht$parameter), c(12, 0))
})
test_that("unpaired, non stratified roc.test works with bootstrap", {
skip_slow()
expect_warning(ht <- roc.test(r.s100b, r.wfns, method = "bootstrap", boot.n = 12, paired = FALSE, boot.stratified = FALSE), "paired")
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, "two.sided")
expect_equal(ht$method, "Bootstrap test for two ROC curves")
expect_equal(unname(ht$parameter), c(12, 0))
})
test_that("bootstrap roc.test works with mixed roc, auc and smooth.roc objects", {
skip_slow()
for (roc1 in list(r.s100b, auc(r.s100b), smooth(r.s100b), r.s100b.partial2, r.s100b.partial2$auc)) {
for (roc2 in list(r.wfns, auc(r.wfns), smooth(r.wfns), r.wfns.partial1, r.wfns.partial1$auc)) {
n <- round(runif(1, 3, 9)) # keep boot.n small
stratified <- sample(c(TRUE, FALSE), 1)
paired <- sample(c(TRUE, FALSE), 1)
alternative <- sample(c("two.sided", "less", "greater"), 1)
suppressWarnings( # All sorts of warnings are expected
ht <- roc.test(roc1, roc2,
method = "bootstrap",
boot.n = n, paired = paired, boot.stratified = stratified,
alternative = alternative
)
)
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, alternative)
if (paired) {
expect_equal(ht$method, "Bootstrap test for two correlated ROC curves")
} else {
expect_equal(ht$method, "Bootstrap test for two ROC curves")
}
expect_equal(unname(ht$parameter), c(n, as.integer(stratified)))
}
}
})
test_that("se/sp roc.test works with mixed roc, auc and smooth.roc objects", {
skip_slow()
for (roc1 in list(r.s100b, auc(r.s100b), smooth(r.s100b), r.s100b.partial2, r.s100b.partial2$auc)) {
for (roc2 in list(r.wfns, auc(r.wfns), smooth(r.wfns), r.wfns.partial1, r.wfns.partial1$auc)) {
for (method in c("sensitivity", "specificity")) {
n <- round(runif(1, 3, 9)) # keep boot.n small
stratified <- sample(c(TRUE, FALSE), 1)
paired <- sample(c(TRUE, FALSE), 1)
alternative <- sample(c("two.sided", "less", "greater"), 1)
suppressWarnings( # All sorts of warnings are expected
ht <- roc.test(roc1, roc2,
method = method,
sensitivity = 0.8,
specificity = 0.8,
boot.n = n, paired = paired, boot.stratified = stratified,
alternative = alternative
)
)
expect_bootstrap_htest(ht)
expect_equal(ht$alternative, alternative)
if (paired) {
expect_equal(ht$method, sprintf("%s test for two correlated ROC curves", tools::toTitleCase(method)))
} else {
expect_equal(ht$method, sprintf("%s test for two ROC curves", tools::toTitleCase(method)))
}
expect_equal(unname(ht$parameter), c(n, as.integer(stratified)))
}
}
}
})
pROC/tests/testthat/helper-vdiffr.R 0000644 0001762 0000144 00000000566 15040443562 016751 0 ustar ligges users # Skip expect_doppelganger if vdiffr is not installed
expect_doppelganger <- function(title, fig, ...) {
testthat::skip_if_not_installed("vdiffr")
vdiffr::expect_doppelganger(title, fig, ...)
}
# expect_doppelganger for ggroc
expect_ggroc_doppelganger <- function(title, fig, ...) {
testthat::skip_if_not_installed("ggplot2")
expect_doppelganger(title, fig, ...)
}
pROC/tests/testthat/helper-rocs.R 0000644 0001762 0000144 00000002775 15040443562 016443 0 ustar ligges users data(aSAH)
r.wfns <- roc(aSAH$outcome, aSAH$wfns, quiet = TRUE)
r.ndka <- roc(aSAH$outcome, aSAH$ndka, quiet = TRUE)
r.s100b <- roc(aSAH$outcome, aSAH$s100b, quiet = TRUE)
r.wfns.percent <- roc(aSAH$outcome, aSAH$wfns, percent = TRUE, quiet = TRUE)
r.ndka.percent <- roc(aSAH$outcome, aSAH$ndka, percent = TRUE, quiet = TRUE)
r.s100b.percent <- roc(aSAH$outcome, aSAH$s100b, percent = TRUE, quiet = TRUE)
r.wfns.partial <- roc(aSAH$outcome, aSAH$wfns, quiet = TRUE, partial.auc = c(1, 0.9))
r.ndka.partial <- roc(aSAH$outcome, aSAH$ndka, quiet = TRUE, partial.auc = c(1, 0.9))
r.s100b.partial <- roc(aSAH$outcome, aSAH$s100b, quiet = TRUE, partial.auc = c(1, 0.9))
r.wfns.partial1 <- roc(aSAH$outcome, aSAH$wfns, quiet = TRUE, partial.auc = c(0.9, 0.99))
r.ndka.partial1 <- roc(aSAH$outcome, aSAH$ndka, quiet = TRUE, partial.auc = c(0.9, 0.99))
r.s100b.partial1 <- roc(aSAH$outcome, aSAH$s100b, quiet = TRUE, partial.auc = c(0.9, 0.99))
r.wfns.percent.partial1 <- roc(aSAH$outcome, aSAH$wfns, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
r.ndka.percent.partial1 <- roc(aSAH$outcome, aSAH$ndka, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
r.s100b.percent.partial1 <- roc(aSAH$outcome, aSAH$s100b, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99))
r.s100b.partial2 <- roc(aSAH$outcome, aSAH$s100b, quiet = TRUE, partial.auc = c(.9, .99), partial.auc.focus = "se")
r.s100b.percent.partial2 <- roc(aSAH$outcome, aSAH$s100b, percent = TRUE, quiet = TRUE, partial.auc = c(90, 99), partial.auc.focus = "se")
pROC/tests/testthat/test-large.R 0000644 0001762 0000144 00000001373 14114130125 016245 0 ustar ligges users library(pROC)
context("large data sets")
test_that("roc can deal with 1E5 data points and many thresholds", {
response <- rbinom(1E5, 1, .5)
predictor <- rnorm(1E5)
# ~ 0.6s
r <- roc(response, predictor)
ci(r)
expect_is(auc(r, partial.auc = c(0.9, 1)), "auc")
})
test_that("roc can deal with 1E6 data points and few thresholds", {
response <- rbinom(1E6, 1, .5)
predictor <- rpois(1E6, 1)
# ~ 0.3s
r <- roc(response, predictor)
ci(r)
expect_is(auc(r, partial.auc = c(0.9, 1)), "auc")
})
test_that("roc can deal with 1E7 data points and few thresholds", {
skip_slow()
response <- rbinom(1E7, 1, .5)
predictor <- rpois(1E7, 1)
# ~ 3s
r <- roc(response, predictor)
ci(r)
expect_is(auc(r, partial.auc = c(0.9, 1)), "auc")
})
pROC/tests/testthat/test-Ops.R 0000644 0001762 0000144 00000001051 15040443562 015720 0 ustar ligges users library(pROC)
data(aSAH)
a.ndka <- auc(aSAH$outcome, aSAH$ndka)
test_that("can convert auc to numeric", {
expect_is(a.ndka, "auc") # a.ndka is not a numeric to start with
expect_equal(as.numeric(a.ndka), 0.611957994579946)
})
test_that("can do math on an AUC", {
expect_equal(sqrt(a.ndka), 0.782277440924859)
expect_equal(a.ndka * 2, 1.22391598915989)
expect_equal(a.ndka / 0.5, 1.22391598915989)
expect_equal(a.ndka + 5, 5.611957994579946)
expect_equal(a.ndka - 1, -0.388042005420054)
expect_equal(round(a.ndka, digits = 1), 0.6)
})
pROC/tests/testthat/test-ci.coords.R 0000644 0001762 0000144 00000007133 15040443562 017051 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.coords")
test_that("ci.coords accepts threshold output with x=best", {
expect_error(ci.coords(r.wfns, x = "best", input = "specificity", ret = c("threshold", "specificity", "sensitivity"), boot.n = 1), NA)
})
test_that("ci.coords rejects threshold output except with x=best", {
expect_error(ci.coords(r.wfns, x = 0.9, input = "specificity", ret = c("threshold", "specificity", "sensitivity"), boot.n = 1))
})
test_that("ci.coords accepts threshold output with x=best or if input was threshold", {
expect_s3_class(ci.coords(r.wfns, x = 2, input = "threshold", ret = c("threshold", "specificity", "sensitivity"), boot.n = 1), "ci.coords")
expect_s3_class(ci.coords(r.wfns, x = "best", ret = c("threshold", "specificity", "sensitivity"), boot.n = 1), "ci.coords")
})
# Only test whether ci.coords runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
valid_coords_input <- coord.is.monotone <- c(
"threshold", "sensitivity", "specificity", "tn", "tp", "fn", "fp", "tpr",
"tnr", "fpr", "fnr", "1-specificity", "1-sensitivity", "recall"
)
for (input in valid_coords_input) {
for (stratified in c(TRUE, FALSE)) {
for (test.roc in list(r.s100b, smooth(r.s100b))) {
context(sprintf("input: %s, stratified: %s, class: %s", input, stratified, class(test.roc)))
test_that("ci.coords accepts one x and one ret", {
skip_slow()
obtained <- ci.coords(test.roc,
x = 0.8, input = input, ret = "sp",
boot.n = 3, conf.level = .91, boot.stratified = stratified
)
expect_equal(attr(obtained, "ret"), "specificity")
expect_equal(names(obtained), attr(obtained, "ret"))
for (ci.mat in obtained) {
expect_equal(dim(ci.mat), c(1, 3))
expect_equal(colnames(ci.mat), c("4.5%", "50%", "95.5%"))
}
})
test_that("ci.coords accepts one x and multiple ret", {
skip_slow()
obtained <- ci.coords(test.roc,
x = 0.8, input = input, ret = c("sp", "ppv", "tp", "1-sensitivity"),
boot.n = 3, conf.level = .91, boot.stratified = stratified
)
expect_equal(attr(obtained, "ret"), c("specificity", "ppv", "tp", "1-sensitivity"))
expect_equal(names(obtained), attr(obtained, "ret"))
for (ci.mat in obtained) {
expect_equal(dim(ci.mat), c(1, 3))
expect_equal(colnames(ci.mat), c("4.5%", "50%", "95.5%"))
}
})
test_that("ci.coords accepts multiple x and one ret", {
skip_slow()
obtained <- ci.coords(test.roc,
x = c(0.8, 0.9), input = input, ret = "sp",
boot.n = 3, conf.level = .91, boot.stratified = stratified
)
expect_equal(attr(obtained, "ret"), "specificity")
expect_equal(names(obtained), attr(obtained, "ret"))
for (ci.mat in obtained) {
expect_equal(dim(ci.mat), c(2, 3))
expect_equal(colnames(ci.mat), c("4.5%", "50%", "95.5%"))
}
})
test_that("ci.coords accepts multiple x and ret", {
skip_slow()
obtained <- ci.coords(test.roc,
x = c(0.9, 0.8), input = input, ret = c("sp", "ppv", "tp", "1-se"),
boot.n = 3, conf.level = .91, boot.stratified = stratified
)
expect_equal(attr(obtained, "ret"), c("specificity", "ppv", "tp", "1-sensitivity"))
expect_equal(names(obtained), attr(obtained, "ret"))
for (ci.mat in obtained) {
expect_equal(dim(ci.mat), c(2, 3))
expect_equal(colnames(ci.mat), c("4.5%", "50%", "95.5%"))
}
})
}
}
}
pROC/tests/testthat/test-ci.sp.R 0000644 0001762 0000144 00000002670 15040443562 016203 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.sp")
# Only test whether ci.sp runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
for (stratified in c(TRUE, FALSE)) {
for (test.roc in list(r.s100b, smooth(r.s100b))) {
test_that("ci.sp with default sensitivities", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.sp(test.roc,
boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expect_is(obtained, "ci.sp")
expect_is(obtained, "ci")
expect_equal(dim(obtained), c(11, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
test_that("ci.sp accepts one sensitivity", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.sp(test.roc,
sensitivities = 0.9, boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expect_is(obtained, "ci.sp")
expect_is(obtained, "ci")
expect_equal(dim(obtained), c(1, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
}
}
pROC/tests/testthat/test-are-paired.R 0000644 0001762 0000144 00000013044 15040443562 017175 0 ustar ligges users library(pROC)
data(aSAH)
context("are.paired")
test_that("are.paired works", {
# most basic example
expect_true(are.paired(r.wfns, r.ndka))
# Missing values shouldn't screw up
aSAH.missing <- aSAH
aSAH.missing$wfns[1:20] <- NA
expect_true(are.paired(roc(aSAH.missing$outcome, aSAH.missing$wfns), roc(aSAH.missing$outcome, aSAH.missing$ndka)))
# Also with different data.frames
expect_true(are.paired(roc(aSAH.missing$outcome, aSAH.missing$wfns), r.ndka))
# The following should fail though
expect_false(are.paired(roc(aSAH$outcome[21:113], aSAH$wfns[21:113]), roc(aSAH$outcome, aSAH$ndka)))
# Opposite levels should probably fail
expect_false(are.paired(roc(aSAH$outcome, aSAH$wfns, levels = c("Good", "Poor")), roc(aSAH$outcome, aSAH$ndka, levels = c("Poor", "Good"))))
})
test_that("are.paired works with formula", {
r.wfns.f <- roc(outcome ~ wfns, aSAH)
r.ndka.f <- roc(outcome ~ ndka, aSAH)
# most basic example
expect_true(are.paired(r.wfns.f, r.ndka.f))
# Missing values shouldn't screw up
aSAH.missing <- aSAH
aSAH.missing$wfns[1:20] <- NA
expect_true(are.paired(roc(outcome ~ wfns, aSAH.missing), roc(outcome ~ ndka, aSAH.missing)))
# Also with different data.frames
expect_true(are.paired(roc(outcome ~ wfns, aSAH.missing), r.ndka.f))
# The following should fail though
expect_false(are.paired(roc(outcome ~ wfns, aSAH.missing[21:113, ]), r.ndka))
# Opposite levels should probably fail
expect_false(are.paired(roc(outcome ~ wfns, aSAH, levels = c("Good", "Poor")), roc(outcome ~ ndka, aSAH, levels = c("Poor", "Good"))))
})
test_that("are.paired works with auc and mixed roc", {
expect_true(are.paired(auc(aSAH$outcome, aSAH$wfns), auc(aSAH$outcome, aSAH$ndka)))
expect_true(are.paired(roc(aSAH$outcome, aSAH$wfns), auc(aSAH$outcome, aSAH$ndka)))
expect_true(are.paired(auc(aSAH$outcome, aSAH$wfns), roc(aSAH$outcome, aSAH$ndka)))
})
test_that("are.paired return.paired.rocs works", {
pair <- are.paired(r.wfns, r.ndka, return.paired.rocs = TRUE)
expect_true(pair)
expect_identical(attr(pair, "roc1"), r.wfns)
expect_identical(attr(pair, "roc2"), r.ndka)
})
test_that("are.paired return.paired.rocs works with missing values", {
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
r1 <- roc(aSAH.missing$outcome, aSAH.missing$ndka)
pair <- are.paired(r1, r.wfns, return.paired.rocs = TRUE)
expect_true(pair)
expect_identical(attr(pair, "roc1")$thresholds, roc(aSAH$outcome[21:113], aSAH$ndka[21:113])$thresholds)
expect_identical(attr(pair, "roc2")$thresholds, roc(aSAH$outcome[21:113], aSAH$wfns[21:113])$thresholds)
})
test_that("are.paired return.paired.rocs doesn't return when unpaired", {
pair <- are.paired(roc(aSAH$outcome[21:113], aSAH$wfns[21:113]), r.ndka, return.paired.rocs = TRUE)
expect_null(attributes(pair))
})
test_that("are.paired works with smooth.roc curves", {
expect_true(are.paired(smooth(r.wfns), smooth(r.ndka)))
# Missing values shouldn't screw up
aSAH.missing <- aSAH
aSAH.missing$wfns[1:20] <- NA
expect_true(are.paired(smooth(roc(aSAH.missing$outcome, aSAH.missing$wfns)), smooth(roc(aSAH.missing$outcome, aSAH.missing$ndka))))
# Also with different data.frames
expect_true(are.paired(smooth(roc(aSAH.missing$outcome, aSAH.missing$wfns)), smooth(r.ndka)))
# The following should fail though
expect_false(are.paired(smooth(roc(aSAH$outcome[21:113], aSAH$wfns[21:113])), smooth(roc(aSAH$outcome, aSAH$ndka))))
# Opposite levels should probably fail
expect_false(are.paired(smooth(roc(aSAH$outcome, aSAH$wfns, levels = c("Good", "Poor"))), smooth(roc(aSAH$outcome, aSAH$ndka, levels = c("Poor", "Good")))))
})
test_that("are.paired works with auc and mixed roc and smooth", {
expect_true(are.paired(auc(aSAH$outcome, aSAH$wfns), smooth(roc(aSAH$outcome, aSAH$ndka))))
expect_true(are.paired(smooth(roc(aSAH$outcome, aSAH$wfns)), auc(aSAH$outcome, aSAH$ndka)))
expect_true(are.paired(roc(aSAH$outcome, aSAH$wfns), smooth(roc(aSAH$outcome, aSAH$ndka))))
expect_true(are.paired(smooth(roc(aSAH$outcome, aSAH$wfns)), roc(aSAH$outcome, aSAH$ndka)))
})
test_that("are.paired return.paired.rocs returns smooth curves", {
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
r1 <- roc(aSAH.missing$outcome, aSAH.missing$ndka, smooth = TRUE)
pair <- are.paired(r1, smooth(r.wfns), return.paired.rocs = TRUE)
expect_true(pair)
expect_is(attr(pair, "roc1"), "smooth.roc")
expect_is(attr(pair, "roc2"), "smooth.roc")
})
test_that("are.paired return.paired.rocs smoothes curves with the right method", {
skip_slow()
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
smooth.methods <- c("binormal", "density", "fitdistr", "logcondens", "logcondens.smooth")
for (smooth.method in smooth.methods) {
r1 <- smooth(roc(aSAH.missing$outcome, aSAH.missing$ndka), method = smooth.method)
pair <- are.paired(r1, smooth(r.s100b, method = smooth.method), return.paired.rocs = TRUE)
expect_true(pair)
expect_identical(attr(pair, "roc1")$smoothing.args$method, smooth.method)
expect_identical(attr(pair, "roc2")$smoothing.args$method, smooth.method)
}
})
test_that("are.paired return.paired.rocs doesn't return when unpaired and smooth", {
pair <- are.paired(smooth(roc(aSAH$outcome[21:113], aSAH$wfns[21:113])), r.ndka, return.paired.rocs = TRUE)
expect_null(attributes(pair))
pair <- are.paired(roc(aSAH$outcome[21:113], aSAH$wfns[21:113]), smooth(r.ndka), return.paired.rocs = TRUE)
expect_null(attributes(pair))
pair <- are.paired(smooth(roc(aSAH$outcome[21:113], aSAH$wfns[21:113])), smooth(r.ndka), return.paired.rocs = TRUE)
expect_null(attributes(pair))
})
pROC/tests/testthat/helper-roc-expected.R 0000644 0001762 0000144 00000175334 15040443562 020061 0 ustar ligges users expected.roc <-
list(ndka = list(forward = list(`<` = list(sensitivities = c(
1,
1, 0.97560975609756095, 0.97560975609756095, 0.97560975609756095,
0.95121951219512191, 0.92682926829268297, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.87804878048780488, 0.87804878048780488, 0.87804878048780488,
0.87804878048780488, 0.87804878048780488, 0.87804878048780488,
0.87804878048780488, 0.85365853658536583, 0.82926829268292679,
0.82926829268292679, 0.82926829268292679, 0.80487804878048785,
0.80487804878048785, 0.80487804878048785, 0.80487804878048785,
0.78048780487804881, 0.75609756097560976, 0.75609756097560976,
0.75609756097560976, 0.75609756097560976, 0.75609756097560976,
0.73170731707317072, 0.73170731707317072, 0.73170731707317072,
0.70731707317073167, 0.70731707317073167, 0.70731707317073167,
0.70731707317073167, 0.70731707317073167, 0.70731707317073167,
0.70731707317073167, 0.68292682926829273, 0.65853658536585369,
0.63414634146341464, 0.63414634146341464, 0.6097560975609756,
0.6097560975609756, 0.6097560975609756, 0.58536585365853655,
0.58536585365853655, 0.58536585365853655, 0.58536585365853655,
0.58536585365853655, 0.58536585365853655, 0.56097560975609762,
0.56097560975609762, 0.53658536585365857, 0.53658536585365857,
0.53658536585365857, 0.51219512195121952, 0.51219512195121952,
0.51219512195121952, 0.48780487804878048, 0.46341463414634149,
0.46341463414634149, 0.43902439024390244, 0.41463414634146339,
0.41463414634146339, 0.41463414634146339, 0.3902439024390244,
0.36585365853658536, 0.34146341463414637, 0.34146341463414637,
0.34146341463414637, 0.34146341463414637, 0.31707317073170732,
0.31707317073170732, 0.31707317073170732, 0.31707317073170732,
0.31707317073170732, 0.29268292682926828, 0.26829268292682928,
0.24390243902439024, 0.21951219512195122, 0.21951219512195122,
0.21951219512195122, 0.1951219512195122, 0.1951219512195122,
0.1951219512195122, 0.1951219512195122, 0.17073170731707318,
0.14634146341463414, 0.12195121951219512, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.073170731707317069,
0.073170731707317069, 0.04878048780487805, 0.04878048780487805,
0.024390243902439025, 0.024390243902439025, 0
), specificities = c(
0,
0.013888888888888888, 0.013888888888888888, 0.027777777777777776,
0.041666666666666664, 0.041666666666666664, 0.041666666666666664,
0.041666666666666664, 0.055555555555555552, 0.069444444444444448,
0.083333333333333329, 0.097222222222222224, 0.1111111111111111,
0.125, 0.1388888888888889, 0.15277777777777779, 0.16666666666666666,
0.16666666666666666, 0.18055555555555555, 0.19444444444444445,
0.20833333333333334, 0.22222222222222221, 0.2361111111111111,
0.25, 0.25, 0.25, 0.2638888888888889, 0.27777777777777779, 0.27777777777777779,
0.29166666666666669, 0.31944444444444442, 0.33333333333333331,
0.33333333333333331, 0.34722222222222221, 0.3611111111111111,
0.375, 0.3888888888888889, 0.40277777777777779, 0.40277777777777779,
0.41666666666666669, 0.43055555555555558, 0.43055555555555558,
0.44444444444444442, 0.45833333333333331, 0.47222222222222221,
0.4861111111111111, 0.5, 0.51388888888888884, 0.51388888888888884,
0.51388888888888884, 0.51388888888888884, 0.52777777777777779,
0.52777777777777779, 0.54166666666666663, 0.55555555555555558,
0.55555555555555558, 0.56944444444444442, 0.58333333333333337,
0.59722222222222221, 0.61111111111111116, 0.625, 0.625, 0.63888888888888884,
0.65277777777777779, 0.66666666666666663, 0.68055555555555558,
0.68055555555555558, 0.69444444444444442, 0.70833333333333337,
0.70833333333333337, 0.70833333333333337, 0.72222222222222221,
0.72222222222222221, 0.72222222222222221, 0.73611111111111116,
0.75, 0.76388888888888884, 0.76388888888888884, 0.76388888888888884,
0.77777777777777779, 0.79166666666666663, 0.80555555555555558,
0.80555555555555558, 0.81944444444444442, 0.83333333333333337,
0.84722222222222221, 0.86111111111111116, 0.86111111111111116,
0.86111111111111116, 0.86111111111111116, 0.86111111111111116,
0.875, 0.88888888888888884, 0.88888888888888884, 0.90277777777777779,
0.91666666666666663, 0.93055555555555558, 0.93055555555555558,
0.93055555555555558, 0.93055555555555558, 0.93055555555555558,
0.94444444444444442, 0.95833333333333337, 0.95833333333333337,
0.97222222222222221, 0.97222222222222221, 0.98611111111111116,
0.98611111111111116, 1, 1
), thresholds = c(
-Inf, 3.4399999999999999,
4.2400000000000002, 4.8200000000000003, 5.1050000000000004, 5.1850000000000005,
5.2800000000000002, 5.6850000000000005, 6.0049999999999999, 6.1500000000000004,
6.2949999999999999, 6.3449999999999998, 6.4649999999999999, 6.5649999999999995,
6.6899999999999995, 6.9249999999999998, 7.2400000000000002, 7.5250000000000004,
7.6449999999999996, 7.7050000000000001, 7.8550000000000004, 7.9900000000000002,
8.0549999999999997, 8.1600000000000001, 8.3049999999999997, 8.4550000000000001,
8.5350000000000001, 8.7199999999999989, 8.9550000000000001, 9.2249999999999996,
9.4550000000000001, 9.5199999999999996, 9.6000000000000014, 9.6649999999999991,
9.75, 9.8049999999999997, 9.8200000000000003, 9.8399999999999999,
9.8999999999999986, 10.140000000000001, 10.365, 10.41, 10.465,
10.530000000000001, 10.574999999999999, 10.715, 10.949999999999999,
11.08, 11.344999999999999, 11.635, 11.675000000000001, 11.699999999999999,
11.725000000000001, 11.850000000000001, 12.095000000000001, 12.375,
12.550000000000001, 12.58, 12.629999999999999, 12.690000000000001,
12.73, 12.775, 12.850000000000001, 12.940000000000001, 13.050000000000001,
13.16, 13.305, 13.43, 13.504999999999999, 13.615, 13.77, 13.954999999999998,
14.149999999999999, 14.300000000000001, 14.455, 15.055, 15.715,
15.925000000000001, 16.035, 16.66, 17.255000000000003, 17.350000000000001,
17.629999999999999, 18.035, 18.835000000000001, 20.105, 20.984999999999999,
21.350000000000001, 21.524999999999999, 21.75, 22.100000000000001,
22.350000000000001, 22.530000000000001, 23.604999999999997, 25.884999999999998,
27.84, 30.43, 32.390000000000001, 33.234999999999999, 37.200000000000003,
40.885000000000005, 44.129999999999995, 47.219999999999999, 48.774999999999999,
52.379999999999995, 56.825000000000003, 65.699999999999989, 76.435000000000002,
249.745, Inf
), auc = 0.61195799457994582, smooth = list(binormal = list(
sensitivities = c(
1, 1, 0.88888888888888884, 0.77777777777777768,
0.66666666666666663, 0.55555555555555558, 0.44444444444444442,
0.33333333333333337, 0.22222222222222213, 0.11111111111111113,
0, 0
), specificities = c(
0, 0, 0.16661242811406332, 0.32116061079093378,
0.46181595199875469, 0.58913400780047731, 0.70322453134188379,
0.80368984329727589, 0.88942408284741548, 0.95788508192900568,
1, 1
)
), density = list(sensitivities = c(
1, 1, 0.99074845171639281,
0.024403220732815607, 0.024403220732815607, 0.024403220732815485,
0.024403220732815485, 0.024403220732815485, 0.024403220732815485,
0.024403220732815485, 0.024403220732814385, 0
), specificities = c(
0,
0, 0.015486341483142763, 0.99999919021311823, 0.999999999999999,
0.99999999999999911, 0.99999999999999911, 0.99999999999999911,
0.99999999999999911, 0.99999999999999911, 0.99999999999999967,
1
)), fitdistr = list(sensitivities = c(
1, 1, 0.65584212882921034,
0.30384953230663891, 0.092280740020347723, 0.017547821937713974,
0.002034152640618334, 0.00014155029521177825, 5.8607227564363664e-06,
1.436222167860087e-07, 2.0599719540113273e-09, 0
), specificities = c(
0,
0, 0.96173121101341241, 0.99999999725370281, 1, 1, 1, 1, 1, 1,
1, 1
)), logcondens = list(sensitivities = c(
1, 1, 0.90363300708873062,
0.8511985619616218, 0.798839025851667, 0.74481915325965597, 0.68373593822521772,
0.61228666217682415, 0.5242346453447293, 0.40443156260979363,
0, 0
), specificities = c(
0, 0, 0.11111111111111116, 0.22222222222222232,
0.33333333333333337, 0.44444444444444442, 0.55555555555555558,
0.66666666666666674, 0.77777777777777779, 0.88888888888888884,
1, 1
)), logcondens.smooth = list(sensitivities = c(
1, 1, 0.62758133842790265,
0.61866421759711965, 0.6094436550718132, 0.59922235170292426,
0.5866469294291885, 0.57030995190982403, 0.54715707821662118,
0.50821961541929606, 0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)))), `>` = list(sensitivities = c(
1,
0.97560975609756095, 0.97560975609756095, 0.95121951219512191,
0.95121951219512191, 0.92682926829268297, 0.92682926829268297,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.87804878048780488, 0.85365853658536583, 0.82926829268292679,
0.80487804878048785, 0.80487804878048785, 0.80487804878048785,
0.80487804878048785, 0.78048780487804881, 0.78048780487804881,
0.78048780487804881, 0.75609756097560976, 0.73170731707317072,
0.70731707317073167, 0.68292682926829273, 0.68292682926829273,
0.68292682926829273, 0.68292682926829273, 0.68292682926829273,
0.65853658536585369, 0.65853658536585369, 0.65853658536585369,
0.65853658536585369, 0.63414634146341464, 0.6097560975609756,
0.58536585365853655, 0.58536585365853655, 0.58536585365853655,
0.56097560975609762, 0.53658536585365857, 0.53658536585365857,
0.51219512195121952, 0.48780487804878048, 0.48780487804878048,
0.48780487804878048, 0.46341463414634149, 0.46341463414634149,
0.46341463414634149, 0.43902439024390244, 0.43902439024390244,
0.41463414634146339, 0.41463414634146339, 0.41463414634146339,
0.41463414634146339, 0.41463414634146339, 0.41463414634146339,
0.3902439024390244, 0.3902439024390244, 0.3902439024390244, 0.36585365853658536,
0.36585365853658536, 0.34146341463414637, 0.31707317073170732,
0.29268292682926828, 0.29268292682926828, 0.29268292682926828,
0.29268292682926828, 0.29268292682926828, 0.29268292682926828,
0.29268292682926828, 0.26829268292682928, 0.26829268292682928,
0.26829268292682928, 0.24390243902439024, 0.24390243902439024,
0.24390243902439024, 0.24390243902439024, 0.24390243902439024,
0.21951219512195122, 0.1951219512195122, 0.1951219512195122,
0.1951219512195122, 0.1951219512195122, 0.17073170731707318,
0.17073170731707318, 0.17073170731707318, 0.14634146341463414,
0.12195121951219512, 0.12195121951219512, 0.12195121951219512,
0.12195121951219512, 0.12195121951219512, 0.12195121951219512,
0.12195121951219512, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.073170731707317069,
0.04878048780487805, 0.024390243902439025, 0.024390243902439025,
0.024390243902439025, 0, 0
), specificities = c(
0, 0, 0.013888888888888888,
0.013888888888888888, 0.027777777777777776, 0.027777777777777776,
0.041666666666666664, 0.041666666666666664, 0.055555555555555552,
0.069444444444444448, 0.069444444444444448, 0.069444444444444448,
0.069444444444444448, 0.069444444444444448, 0.083333333333333329,
0.097222222222222224, 0.1111111111111111, 0.1111111111111111,
0.125, 0.1388888888888889, 0.1388888888888889, 0.1388888888888889,
0.1388888888888889, 0.1388888888888889, 0.15277777777777779,
0.16666666666666666, 0.18055555555555555, 0.19444444444444445,
0.19444444444444445, 0.20833333333333334, 0.22222222222222221,
0.2361111111111111, 0.2361111111111111, 0.2361111111111111, 0.25,
0.2638888888888889, 0.27777777777777779, 0.27777777777777779,
0.27777777777777779, 0.29166666666666669, 0.29166666666666669,
0.29166666666666669, 0.30555555555555558, 0.31944444444444442,
0.31944444444444442, 0.33333333333333331, 0.34722222222222221,
0.3611111111111111, 0.375, 0.375, 0.3888888888888889, 0.40277777777777779,
0.41666666666666669, 0.43055555555555558, 0.44444444444444442,
0.44444444444444442, 0.45833333333333331, 0.47222222222222221,
0.47222222222222221, 0.4861111111111111, 0.4861111111111111,
0.4861111111111111, 0.4861111111111111, 0.5, 0.51388888888888884,
0.52777777777777779, 0.54166666666666663, 0.55555555555555558,
0.56944444444444442, 0.56944444444444442, 0.58333333333333337,
0.59722222222222221, 0.59722222222222221, 0.61111111111111116,
0.625, 0.63888888888888884, 0.65277777777777779, 0.66666666666666663,
0.66666666666666663, 0.68055555555555558, 0.70833333333333337,
0.72222222222222221, 0.72222222222222221, 0.73611111111111116,
0.75, 0.75, 0.75, 0.76388888888888884, 0.77777777777777779, 0.79166666666666663,
0.80555555555555558, 0.81944444444444442, 0.83333333333333337,
0.83333333333333337, 0.84722222222222221, 0.86111111111111116,
0.875, 0.88888888888888884, 0.90277777777777779, 0.91666666666666663,
0.93055555555555558, 0.94444444444444442, 0.95833333333333337,
0.95833333333333337, 0.95833333333333337, 0.95833333333333337,
0.97222222222222221, 0.98611111111111116, 0.98611111111111116,
1
), thresholds = c(
Inf, 249.745, 76.435000000000002, 65.699999999999989,
56.825000000000003, 52.379999999999995, 48.774999999999999, 47.219999999999999,
44.129999999999995, 40.885000000000005, 37.200000000000003, 33.234999999999999,
32.390000000000001, 30.43, 27.84, 25.884999999999998, 23.604999999999997,
22.530000000000001, 22.350000000000001, 22.100000000000001, 21.75,
21.524999999999999, 21.350000000000001, 20.984999999999999, 20.105,
18.835000000000001, 18.035, 17.629999999999999, 17.350000000000001,
17.255000000000003, 16.66, 16.035, 15.925000000000001, 15.715,
15.055, 14.455, 14.300000000000001, 14.149999999999999, 13.954999999999998,
13.77, 13.615, 13.504999999999999, 13.43, 13.305, 13.16, 13.050000000000001,
12.940000000000001, 12.850000000000001, 12.775, 12.73, 12.690000000000001,
12.629999999999999, 12.58, 12.550000000000001, 12.375, 12.095000000000001,
11.850000000000001, 11.725000000000001, 11.699999999999999, 11.675000000000001,
11.635, 11.344999999999999, 11.08, 10.949999999999999, 10.715,
10.574999999999999, 10.530000000000001, 10.465, 10.41, 10.365,
10.140000000000001, 9.8999999999999986, 9.8399999999999999, 9.8200000000000003,
9.8049999999999997, 9.75, 9.6649999999999991, 9.6000000000000014,
9.5199999999999996, 9.4550000000000001, 9.2249999999999996, 8.9550000000000001,
8.7199999999999989, 8.5350000000000001, 8.4550000000000001, 8.3049999999999997,
8.1600000000000001, 8.0549999999999997, 7.9900000000000002, 7.8550000000000004,
7.7050000000000001, 7.6449999999999996, 7.5250000000000004, 7.2400000000000002,
6.9249999999999998, 6.6899999999999995, 6.5649999999999995, 6.4649999999999999,
6.3449999999999998, 6.2949999999999999, 6.1500000000000004, 6.0049999999999999,
5.6850000000000005, 5.2800000000000002, 5.1850000000000005, 5.1050000000000004,
4.8200000000000003, 4.2400000000000002, 3.4399999999999999, -Inf
), auc = 0.38804200542005424, smooth = list(binormal = list(sensitivities = c(
1,
1, 0.88888888888888884, 0.77777777777777768, 0.66666666666666663,
0.55555555555555558, 0.44444444444444442, 0.33333333333333337,
0.22222222222222213, 0.11111111111111113, 0, 0
), specificities = c(
0,
0, 0.042114918070994309, 0.11057591715258469, 0.19631015670272414,
0.29677546865811616, 0.41086599219952258, 0.53818404800124531,
0.67883938920906639, 0.83338757188593671, 1, 1
)), density = list(
sensitivities = c(
1, 1, 0.97559677926718558, 0.97559677926718458,
0.97559677926718458, 0.97559677926718458, 0.97559677926718458,
0.97559677926718458, 0.97559677926718458, 0.97559677926718458,
0.0092515482836072627, 0
), specificities = c(
0, 0, 3.4524729812651632e-16,
9.1226915172916031e-16, 9.1226915172916031e-16, 9.2798538864975309e-16,
9.2798538864975309e-16, 9.2798538864975309e-16, 1.0359597490083634e-15,
8.0978688191541923e-07, 0.98451365851685735, 1
)
), fitdistr = list(
sensitivities = c(
1, 1, 0.99999999794002792, 0.99999985637778321,
0.99999413927724357, 0.9998584497047881, 0.99796584735938154,
0.98245217806228602, 0.90771925997965219, 0.69615046769336109,
0.34415787117078966, 0
), specificities = c(
0, 0, 3.9920836420121644e-220,
8.9642454244700092e-173, 3.6302765381684218e-131, 2.6514139939139415e-95,
3.4924262502075261e-65, 8.2963832904754802e-41, 3.5543667446643779e-22,
2.7462971753675956e-09, 0.038268788986587518, 1
)
), logcondens = list(
sensitivities = c(
1, 1, 0.90363300708873062, 0.8511985619616218,
0.798839025851667, 0.74481915325965597, 0.68373593822521772,
0.61228666217682415, 0.5242346453447293, 0.40443156260979363,
0, 0
), specificities = c(
0, 0, 0.11111111111111116, 0.22222222222222232,
0.33333333333333337, 0.44444444444444442, 0.55555555555555558,
0.66666666666666674, 0.77777777777777779, 0.88888888888888884,
1, 1
)
), logcondens.smooth = list(sensitivities = c(
1, 1,
0.62758133842790265, 0.61866421759711965, 0.6094436550718132,
0.59922235170292426, 0.5866469294291885, 0.57030995190982403,
0.54715707821662118, 0.50821961541929606, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
))))), reversed = list(
`<` = list(
sensitivities = c(
1, 0.98611111111111116, 0.98611111111111116,
0.97222222222222221, 0.95833333333333337, 0.95833333333333337,
0.95833333333333337, 0.95833333333333337, 0.94444444444444442,
0.93055555555555558, 0.91666666666666663, 0.90277777777777779,
0.88888888888888884, 0.875, 0.86111111111111116, 0.84722222222222221,
0.83333333333333337, 0.83333333333333337, 0.81944444444444442,
0.80555555555555558, 0.79166666666666663, 0.77777777777777779,
0.76388888888888884, 0.75, 0.75, 0.75, 0.73611111111111116,
0.72222222222222221, 0.72222222222222221, 0.70833333333333337,
0.68055555555555558, 0.66666666666666663, 0.66666666666666663,
0.65277777777777779, 0.63888888888888884, 0.625, 0.61111111111111116,
0.59722222222222221, 0.59722222222222221, 0.58333333333333337,
0.56944444444444442, 0.56944444444444442, 0.55555555555555558,
0.54166666666666663, 0.52777777777777779, 0.51388888888888884,
0.5, 0.4861111111111111, 0.4861111111111111, 0.4861111111111111,
0.4861111111111111, 0.47222222222222221, 0.47222222222222221,
0.45833333333333331, 0.44444444444444442, 0.44444444444444442,
0.43055555555555558, 0.41666666666666669, 0.40277777777777779,
0.3888888888888889, 0.375, 0.375, 0.3611111111111111, 0.34722222222222221,
0.33333333333333331, 0.31944444444444442, 0.31944444444444442,
0.30555555555555558, 0.29166666666666669, 0.29166666666666669,
0.29166666666666669, 0.27777777777777779, 0.27777777777777779,
0.27777777777777779, 0.2638888888888889, 0.25, 0.2361111111111111,
0.2361111111111111, 0.2361111111111111, 0.22222222222222221,
0.20833333333333334, 0.19444444444444445, 0.19444444444444445,
0.18055555555555555, 0.16666666666666666, 0.15277777777777779,
0.1388888888888889, 0.1388888888888889, 0.1388888888888889,
0.1388888888888889, 0.1388888888888889, 0.125, 0.1111111111111111,
0.1111111111111111, 0.097222222222222224, 0.083333333333333329,
0.069444444444444448, 0.069444444444444448, 0.069444444444444448,
0.069444444444444448, 0.069444444444444448, 0.055555555555555552,
0.041666666666666664, 0.041666666666666664, 0.027777777777777776,
0.027777777777777776, 0.013888888888888888, 0.013888888888888888,
0, 0
), specificities = c(
0, 0, 0.024390243902439025, 0.024390243902439025,
0.024390243902439025, 0.04878048780487805, 0.073170731707317069,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.097560975609756101, 0.12195121951219512, 0.12195121951219512,
0.12195121951219512, 0.12195121951219512, 0.12195121951219512,
0.12195121951219512, 0.12195121951219512, 0.14634146341463414,
0.17073170731707318, 0.17073170731707318, 0.17073170731707318,
0.1951219512195122, 0.1951219512195122, 0.1951219512195122,
0.1951219512195122, 0.21951219512195122, 0.24390243902439024,
0.24390243902439024, 0.24390243902439024, 0.24390243902439024,
0.24390243902439024, 0.26829268292682928, 0.26829268292682928,
0.26829268292682928, 0.29268292682926828, 0.29268292682926828,
0.29268292682926828, 0.29268292682926828, 0.29268292682926828,
0.29268292682926828, 0.29268292682926828, 0.31707317073170732,
0.34146341463414637, 0.36585365853658536, 0.36585365853658536,
0.3902439024390244, 0.3902439024390244, 0.3902439024390244,
0.41463414634146339, 0.41463414634146339, 0.41463414634146339,
0.41463414634146339, 0.41463414634146339, 0.41463414634146339,
0.43902439024390244, 0.43902439024390244, 0.46341463414634149,
0.46341463414634149, 0.46341463414634149, 0.48780487804878048,
0.48780487804878048, 0.48780487804878048, 0.51219512195121952,
0.53658536585365857, 0.53658536585365857, 0.56097560975609762,
0.58536585365853655, 0.58536585365853655, 0.58536585365853655,
0.6097560975609756, 0.63414634146341464, 0.65853658536585369,
0.65853658536585369, 0.65853658536585369, 0.65853658536585369,
0.68292682926829273, 0.68292682926829273, 0.68292682926829273,
0.68292682926829273, 0.68292682926829273, 0.70731707317073167,
0.73170731707317072, 0.75609756097560976, 0.78048780487804881,
0.78048780487804881, 0.78048780487804881, 0.80487804878048785,
0.80487804878048785, 0.80487804878048785, 0.80487804878048785,
0.82926829268292679, 0.85365853658536583, 0.87804878048780488,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.92682926829268297, 0.92682926829268297, 0.95121951219512191,
0.95121951219512191, 0.97560975609756095, 0.97560975609756095,
1
), thresholds = c(
-Inf, 3.4399999999999999, 4.2400000000000002,
4.8200000000000003, 5.1050000000000004, 5.1850000000000005,
5.2800000000000002, 5.6850000000000005, 6.0049999999999999,
6.1500000000000004, 6.2949999999999999, 6.3449999999999998,
6.4649999999999999, 6.5649999999999995, 6.6899999999999995,
6.9249999999999998, 7.2400000000000002, 7.5250000000000004,
7.6449999999999996, 7.7050000000000001, 7.8550000000000004,
7.9900000000000002, 8.0549999999999997, 8.1600000000000001,
8.3049999999999997, 8.4550000000000001, 8.5350000000000001,
8.7199999999999989, 8.9550000000000001, 9.2249999999999996,
9.4550000000000001, 9.5199999999999996, 9.6000000000000014,
9.6649999999999991, 9.75, 9.8049999999999997, 9.8200000000000003,
9.8399999999999999, 9.8999999999999986, 10.140000000000001,
10.365, 10.41, 10.465, 10.530000000000001, 10.574999999999999,
10.715, 10.949999999999999, 11.08, 11.344999999999999, 11.635,
11.675000000000001, 11.699999999999999, 11.725000000000001,
11.850000000000001, 12.095000000000001, 12.375, 12.550000000000001,
12.58, 12.629999999999999, 12.690000000000001, 12.73, 12.775,
12.850000000000001, 12.940000000000001, 13.050000000000001,
13.16, 13.305, 13.43, 13.504999999999999, 13.615, 13.77,
13.954999999999998, 14.149999999999999, 14.300000000000001,
14.455, 15.055, 15.715, 15.925000000000001, 16.035, 16.66,
17.255000000000003, 17.350000000000001, 17.629999999999999,
18.035, 18.835000000000001, 20.105, 20.984999999999999, 21.350000000000001,
21.524999999999999, 21.75, 22.100000000000001, 22.350000000000001,
22.530000000000001, 23.604999999999997, 25.884999999999998,
27.84, 30.43, 32.390000000000001, 33.234999999999999, 37.200000000000003,
40.885000000000005, 44.129999999999995, 47.219999999999999,
48.774999999999999, 52.379999999999995, 56.825000000000003,
65.699999999999989, 76.435000000000002, 249.745, Inf
), auc = 0.38804200542005424,
smooth = list(binormal = list(sensitivities = c(
1, 1,
0.88888888888888884, 0.77777777777777768, 0.66666666666666663,
0.55555555555555558, 0.44444444444444442, 0.33333333333333337,
0.22222222222222213, 0.11111111111111113, 0, 0
), specificities = c(
0,
0, 0.078867440848734052, 0.15574787162396841, 0.23619172831183718,
0.32172535932349933, 0.41397059696043026, 0.5153092702831551,
0.63000483317461498, 0.76807086794978208, 1, 1
)), density = list(
sensitivities = c(
1, 1, 0.98451365851685735, 8.0978688191541923e-07,
1.0359597490083634e-15, 9.2798538864975309e-16, 9.2798538864975309e-16,
9.2798538864975309e-16, 9.1226915172916031e-16, 9.1226915172916031e-16,
3.4524729812651632e-16, 0
), specificities = c(
0,
0, 0.0092515482836072627, 0.97559677926718458, 0.97559677926718458,
0.97559677926718458, 0.97559677926718458, 0.97559677926718458,
0.97559677926718458, 0.97559677926718458, 0.97559677926718558,
1
)
), fitdistr = list(
sensitivities = c(
1, 1, 0.038268788986587518,
2.7462971753675956e-09, 3.5543667446643779e-22, 8.2963832904754802e-41,
3.4924262502075261e-65, 2.6514139939139415e-95, 3.6302765381684218e-131,
8.9642454244700092e-173, 3.9920836420121644e-220, 0
),
specificities = c(
0, 0, 0.34415787117078966, 0.69615046769336109,
0.90771925997965219, 0.98245217806228602, 0.99796584735938154,
0.9998584497047881, 0.99999413927724357, 0.99999985637778321,
0.99999999794002792, 1
)
), logcondens = list(sensitivities = c(
1,
1, 0.85778454966569506, 0.62179078174318914, 0.41603723085109146,
0.26239037570279455, 0.15511883519799263, 0.10128638051436067,
0.023985163198016246, 0.0044162288973589314, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
)), logcondens.smooth = list(
sensitivities = c(
1, 1, 0.72658680070168447, 0.62119107780976202,
0.49446346037741784, 0.35806353231687915, 0.232023673461772,
0.15735364925566664, 0.038445047328011128, 0.0072295330746923181,
0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)
))
), `>` = list(
sensitivities = c(
1,
1, 0.98611111111111116, 0.98611111111111116, 0.97222222222222221,
0.97222222222222221, 0.95833333333333337, 0.95833333333333337,
0.94444444444444442, 0.93055555555555558, 0.93055555555555558,
0.93055555555555558, 0.93055555555555558, 0.93055555555555558,
0.91666666666666663, 0.90277777777777779, 0.88888888888888884,
0.88888888888888884, 0.875, 0.86111111111111116, 0.86111111111111116,
0.86111111111111116, 0.86111111111111116, 0.86111111111111116,
0.84722222222222221, 0.83333333333333337, 0.81944444444444442,
0.80555555555555558, 0.80555555555555558, 0.79166666666666663,
0.77777777777777779, 0.76388888888888884, 0.76388888888888884,
0.76388888888888884, 0.75, 0.73611111111111116, 0.72222222222222221,
0.72222222222222221, 0.72222222222222221, 0.70833333333333337,
0.70833333333333337, 0.70833333333333337, 0.69444444444444442,
0.68055555555555558, 0.68055555555555558, 0.66666666666666663,
0.65277777777777779, 0.63888888888888884, 0.625, 0.625, 0.61111111111111116,
0.59722222222222221, 0.58333333333333337, 0.56944444444444442,
0.55555555555555558, 0.55555555555555558, 0.54166666666666663,
0.52777777777777779, 0.52777777777777779, 0.51388888888888884,
0.51388888888888884, 0.51388888888888884, 0.51388888888888884,
0.5, 0.4861111111111111, 0.47222222222222221, 0.45833333333333331,
0.44444444444444442, 0.43055555555555558, 0.43055555555555558,
0.41666666666666669, 0.40277777777777779, 0.40277777777777779,
0.3888888888888889, 0.375, 0.3611111111111111, 0.34722222222222221,
0.33333333333333331, 0.33333333333333331, 0.31944444444444442,
0.29166666666666669, 0.27777777777777779, 0.27777777777777779,
0.2638888888888889, 0.25, 0.25, 0.25, 0.2361111111111111,
0.22222222222222221, 0.20833333333333334, 0.19444444444444445,
0.18055555555555555, 0.16666666666666666, 0.16666666666666666,
0.15277777777777779, 0.1388888888888889, 0.125, 0.1111111111111111,
0.097222222222222224, 0.083333333333333329, 0.069444444444444448,
0.055555555555555552, 0.041666666666666664, 0.041666666666666664,
0.041666666666666664, 0.041666666666666664, 0.027777777777777776,
0.013888888888888888, 0.013888888888888888, 0
), specificities = c(
0,
0.024390243902439025, 0.024390243902439025, 0.04878048780487805,
0.04878048780487805, 0.073170731707317069, 0.073170731707317069,
0.097560975609756101, 0.097560975609756101, 0.097560975609756101,
0.12195121951219512, 0.14634146341463414, 0.17073170731707318,
0.1951219512195122, 0.1951219512195122, 0.1951219512195122,
0.1951219512195122, 0.21951219512195122, 0.21951219512195122,
0.21951219512195122, 0.24390243902439024, 0.26829268292682928,
0.29268292682926828, 0.31707317073170732, 0.31707317073170732,
0.31707317073170732, 0.31707317073170732, 0.31707317073170732,
0.34146341463414637, 0.34146341463414637, 0.34146341463414637,
0.34146341463414637, 0.36585365853658536, 0.3902439024390244,
0.41463414634146339, 0.41463414634146339, 0.41463414634146339,
0.43902439024390244, 0.46341463414634149, 0.46341463414634149,
0.48780487804878048, 0.51219512195121952, 0.51219512195121952,
0.51219512195121952, 0.53658536585365857, 0.53658536585365857,
0.53658536585365857, 0.56097560975609762, 0.56097560975609762,
0.58536585365853655, 0.58536585365853655, 0.58536585365853655,
0.58536585365853655, 0.58536585365853655, 0.58536585365853655,
0.6097560975609756, 0.6097560975609756, 0.6097560975609756,
0.63414634146341464, 0.63414634146341464, 0.65853658536585369,
0.68292682926829273, 0.70731707317073167, 0.70731707317073167,
0.70731707317073167, 0.70731707317073167, 0.70731707317073167,
0.70731707317073167, 0.70731707317073167, 0.73170731707317072,
0.73170731707317072, 0.73170731707317072, 0.75609756097560976,
0.75609756097560976, 0.75609756097560976, 0.75609756097560976,
0.75609756097560976, 0.78048780487804881, 0.80487804878048785,
0.80487804878048785, 0.80487804878048785, 0.80487804878048785,
0.82926829268292679, 0.82926829268292679, 0.82926829268292679,
0.85365853658536583, 0.87804878048780488, 0.87804878048780488,
0.87804878048780488, 0.87804878048780488, 0.87804878048780488,
0.87804878048780488, 0.87804878048780488, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.90243902439024393, 0.90243902439024393, 0.90243902439024393,
0.92682926829268297, 0.95121951219512191, 0.97560975609756095,
0.97560975609756095, 0.97560975609756095, 1, 1
), thresholds = c(
Inf,
249.745, 76.435000000000002, 65.699999999999989, 56.825000000000003,
52.379999999999995, 48.774999999999999, 47.219999999999999,
44.129999999999995, 40.885000000000005, 37.200000000000003,
33.234999999999999, 32.390000000000001, 30.43, 27.84, 25.884999999999998,
23.604999999999997, 22.530000000000001, 22.350000000000001,
22.100000000000001, 21.75, 21.524999999999999, 21.350000000000001,
20.984999999999999, 20.105, 18.835000000000001, 18.035, 17.629999999999999,
17.350000000000001, 17.255000000000003, 16.66, 16.035, 15.925000000000001,
15.715, 15.055, 14.455, 14.300000000000001, 14.149999999999999,
13.954999999999998, 13.77, 13.615, 13.504999999999999, 13.43,
13.305, 13.16, 13.050000000000001, 12.940000000000001, 12.850000000000001,
12.775, 12.73, 12.690000000000001, 12.629999999999999, 12.58,
12.550000000000001, 12.375, 12.095000000000001, 11.850000000000001,
11.725000000000001, 11.699999999999999, 11.675000000000001,
11.635, 11.344999999999999, 11.08, 10.949999999999999, 10.715,
10.574999999999999, 10.530000000000001, 10.465, 10.41, 10.365,
10.140000000000001, 9.8999999999999986, 9.8399999999999999,
9.8200000000000003, 9.8049999999999997, 9.75, 9.6649999999999991,
9.6000000000000014, 9.5199999999999996, 9.4550000000000001,
9.2249999999999996, 8.9550000000000001, 8.7199999999999989,
8.5350000000000001, 8.4550000000000001, 8.3049999999999997,
8.1600000000000001, 8.0549999999999997, 7.9900000000000002,
7.8550000000000004, 7.7050000000000001, 7.6449999999999996,
7.5250000000000004, 7.2400000000000002, 6.9249999999999998,
6.6899999999999995, 6.5649999999999995, 6.4649999999999999,
6.3449999999999998, 6.2949999999999999, 6.1500000000000004,
6.0049999999999999, 5.6850000000000005, 5.2800000000000002,
5.1850000000000005, 5.1050000000000004, 4.8200000000000003,
4.2400000000000002, 3.4399999999999999, -Inf
), auc = 0.61195799457994582,
smooth = list(binormal = list(sensitivities = c(
1, 1,
0.88888888888888884, 0.77777777777777768, 0.66666666666666663,
0.55555555555555558, 0.44444444444444442, 0.33333333333333337,
0.22222222222222213, 0.11111111111111113, 0, 0
), specificities = c(
0,
0, 0.23192913205021823, 0.36999516682538541, 0.48469072971684507,
0.58602940303956985, 0.67827464067650067, 0.76380827168816279,
0.8442521283760317, 0.92113255915126591, 1, 1
)), density = list(
sensitivities = c(
1, 1, 0.99999999999999967, 0.99999999999999911,
0.99999999999999911, 0.99999999999999911, 0.99999999999999911,
0.99999999999999911, 0.999999999999999, 0.99999919021311823,
0.015486341483142763, 0
), specificities = c(
0, 0,
0.024403220732814385, 0.024403220732815485, 0.024403220732815485,
0.024403220732815485, 0.024403220732815485, 0.024403220732815485,
0.024403220732815607, 0.024403220732815607, 0.99074845171639281,
1
)
), fitdistr = list(sensitivities = c(
1, 1, 1, 1,
1, 1, 1, 1, 1, 0.99999999725370281, 0.96173121101341241,
0
), specificities = c(
0, 0, 2.0599719540113273e-09, 1.436222167860087e-07,
5.8607227564363664e-06, 0.00014155029521177825, 0.002034152640618334,
0.017547821937713974, 0.092280740020347723, 0.30384953230663891,
0.65584212882921034, 1
)), logcondens = list(sensitivities = c(
1,
1, 0.85778454966569506, 0.62179078174318914, 0.41603723085109146,
0.26239037570279455, 0.15511883519799263, 0.10128638051436067,
0.023985163198016246, 0.0044162288973589314, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
)), logcondens.smooth = list(
sensitivities = c(
1, 1, 0.72658680070168447, 0.62119107780976202,
0.49446346037741784, 0.35806353231687915, 0.232023673461772,
0.15735364925566664, 0.038445047328011128, 0.0072295330746923181,
0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)
))
)
)), wfns = list(forward = list(
`<` = list(sensitivities = c(
1, 0.95121951219512191, 0.65853658536585369,
0.63414634146341464, 0.43902439024390244, 0
), specificities = c(
0,
0.51388888888888884, 0.79166666666666663, 0.83333333333333337,
0.94444444444444442, 1
), thresholds = c(
-Inf, 1.5, 2.5, 3.5,
4.5, Inf
), auc = 0.82367886178861793, smooth = list(binormal = list(
sensitivities = c(
1, 1, 0.88888888888888884, 0.77777777777777768,
0.66666666666666663, 0.55555555555555558, 0.44444444444444442,
0.33333333333333337, 0.22222222222222213, 0.11111111111111113,
0, 0
), specificities = c(
0, 0, 0.62533312733387414, 0.7545881594190047,
0.83138558305192944, 0.8840526000127753, 0.92247694842983718,
0.9513179178044695, 0.97309882220458377, 0.98921642370297957,
1, 1
)
))), `>` = list(sensitivities = c(
1, 0.56097560975609762,
0.36585365853658536, 0.34146341463414637, 0.04878048780487805,
0
), specificities = c(
0, 0.055555555555555552, 0.16666666666666666,
0.20833333333333334, 0.4861111111111111, 1
), thresholds = c(
Inf,
4.5, 3.5, 2.5, 1.5, -Inf
), auc = 0.17632113821138212, smooth = list(
binormal = list(sensitivities = c(
1, 1, 0.88888888888888884,
0.77777777777777768, 0.66666666666666663, 0.55555555555555558,
0.44444444444444442, 0.33333333333333337, 0.22222222222222213,
0.11111111111111113, 0, 0
), specificities = c(
0, 0, 0.010783576297020432,
0.026901177795416224, 0.048682082195530475, 0.077523051570162843,
0.11594739998722474, 0.16861441694807056, 0.24541184058099536,
0.37466687266612586, 1, 1
))
))
), reversed = list(`<` = list(
sensitivities = c(
1, 0.4861111111111111, 0.20833333333333334,
0.16666666666666666, 0.055555555555555552, 0
), specificities = c(
0,
0.04878048780487805, 0.34146341463414637, 0.36585365853658536,
0.56097560975609762, 1
), thresholds = c(
-Inf, 1.5, 2.5, 3.5,
4.5, Inf
), auc = 0.17632113821138212, smooth = list(binormal = list(
sensitivities = c(
1, 1, 0.88888888888888884, 0.77777777777777768,
0.66666666666666663, 0.55555555555555558, 0.44444444444444442,
0.33333333333333337, 0.22222222222222213, 0.11111111111111113,
0, 0
), specificities = c(
0, 0, 0.0013816610498169654,
0.0069756572121715049, 0.019364477973144105, 0.042177720917290107,
0.080989338145638884, 0.14517642542680345, 0.25274117065129986,
0.44769221428129474, 1, 1
)
))
), `>` = list(
sensitivities = c(
1,
0.94444444444444442, 0.83333333333333337, 0.79166666666666663,
0.51388888888888884, 0
), specificities = c(
0, 0.43902439024390244,
0.63414634146341464, 0.65853658536585369, 0.95121951219512191,
1
), thresholds = c(Inf, 4.5, 3.5, 2.5, 1.5, -Inf), auc = 0.82367886178861782,
smooth = list(binormal = list(sensitivities = c(
1, 1, 0.88888888888888884,
0.77777777777777768, 0.66666666666666663, 0.55555555555555558,
0.44444444444444442, 0.33333333333333337, 0.22222222222222213,
0.11111111111111113, 0, 0
), specificities = c(
0, 0, 0.55230778571870565,
0.74725882934870058, 0.85482357457319669, 0.9190106618543612,
0.95782227908270989, 0.98063552202685589, 0.99302434278782847,
0.99861833895018304, 1, 1
)))
))), s100b = list(forward = list(
`<` = list(
sensitivities = c(
1, 0.97560975609756095, 0.97560975609756095,
0.97560975609756095, 0.97560975609756095, 0.90243902439024393,
0.87804878048780488, 0.82926829268292679, 0.78048780487804881,
0.75609756097560976, 0.73170731707317072, 0.68292682926829273,
0.65853658536585369, 0.65853658536585369, 0.63414634146341464,
0.63414634146341464, 0.63414634146341464, 0.63414634146341464,
0.6097560975609756, 0.58536585365853655, 0.58536585365853655,
0.56097560975609762, 0.53658536585365857, 0.51219512195121952,
0.51219512195121952, 0.48780487804878048, 0.46341463414634149,
0.43902439024390244, 0.43902439024390244, 0.41463414634146339,
0.41463414634146339, 0.3902439024390244, 0.3902439024390244,
0.34146341463414637, 0.34146341463414637, 0.34146341463414637,
0.34146341463414637, 0.31707317073170732, 0.29268292682926828,
0.29268292682926828, 0.26829268292682928, 0.24390243902439024,
0.21951219512195122, 0.1951219512195122, 0.14634146341463414,
0.12195121951219512, 0.097560975609756101, 0.073170731707317069,
0.04878048780487805, 0.024390243902439025, 0
), specificities = c(
0,
0, 0.069444444444444448, 0.1111111111111111, 0.1388888888888889,
0.22222222222222221, 0.30555555555555558, 0.3888888888888889,
0.4861111111111111, 0.54166666666666663, 0.54166666666666663,
0.58333333333333337, 0.63888888888888884, 0.69444444444444442,
0.73611111111111116, 0.76388888888888884, 0.77777777777777779,
0.80555555555555558, 0.80555555555555558, 0.80555555555555558,
0.81944444444444442, 0.81944444444444442, 0.81944444444444442,
0.81944444444444442, 0.83333333333333337, 0.83333333333333337,
0.84722222222222221, 0.86111111111111116, 0.875, 0.875, 0.88888888888888884,
0.88888888888888884, 0.90277777777777779, 0.90277777777777779,
0.91666666666666663, 0.93055555555555558, 0.95833333333333337,
0.97222222222222221, 0.97222222222222221, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1
), thresholds = c(
-Inf, 0.035000000000000003,
0.044999999999999998, 0.055, 0.065000000000000002, 0.075000000000000011,
0.084999999999999992, 0.095000000000000001, 0.10500000000000001,
0.11499999999999999, 0.125, 0.13500000000000001, 0.14500000000000002,
0.155, 0.16500000000000001, 0.17499999999999999, 0.185, 0.20500000000000002,
0.22500000000000001, 0.23499999999999999, 0.245, 0.255, 0.26500000000000001,
0.27500000000000002, 0.29000000000000004, 0.31, 0.32500000000000001,
0.33500000000000002, 0.34499999999999997, 0.36499999999999999,
0.39500000000000002, 0.41999999999999998, 0.435, 0.44500000000000001,
0.45500000000000002, 0.46499999999999997, 0.47499999999999998,
0.48499999999999999, 0.495, 0.51000000000000001, 0.54000000000000004,
0.57000000000000006, 0.6399999999999999, 0.70499999999999996,
0.72499999999999998, 0.755, 0.79499999999999993, 0.83999999999999997,
0.90999999999999992, 1.5149999999999999, Inf
), auc = 0.73136856368563685,
smooth = list(binormal = list(sensitivities = c(
1, 1,
0.88888888888888884, 0.77777777777777768, 0.66666666666666663,
0.55555555555555558, 0.44444444444444442, 0.33333333333333337,
0.22222222222222213, 0.11111111111111113, 0, 0
), specificities = c(
0,
0, 0.31926034068390191, 0.53332668430381991, 0.68758579956209709,
0.80017645978030316, 0.88127986696010441, 0.9375641008236737,
0.97381171895978846, 0.99367420371972059, 1, 1
)), density = list(
sensitivities = c(
1, 1, 0.99931926332046905, 0.464810600933454,
0.22917666069447112, 0.09005239526766956, 0.017555089627706303,
0.017490235777182776, 0.017490235777181288, 0.017490228541216186,
0.00043674621134013675, 0
), specificities = c(
0,
0, 0.0012607813351102808, 0.8750672775523769, 0.99610977939383138,
0.99999999998884759, 1, 1, 1, 1, 1, 1
)
), fitdistr = list(
sensitivities = c(
1, 1, 0.83511403670197726, 0.58446982128433378,
0.3223722368816308, 0.13383389526947279, 0.040536895253957712,
0.0087778814778924647, 0.0013408834167663738, 0.00014287557463888575,
1.0119933123736651e-05, 0
), specificities = c(
0,
0, 0.42469571321058891, 0.96688511000396316, 0.99990406546220234,
0.9999999867074495, 0.99999999999991218, 1, 1, 1,
1, 1
)
), logcondens = list(sensitivities = c(
1, 1,
0.96925785071341375, 0.9299795293124361, 0.87933626192559511,
0.82287867390211533, 0.76057870800949001, 0.68785049271852017,
0.59811207367258978, 0.48211757900052843, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
)), logcondens.smooth = list(
sensitivities = c(
1, 1, 0.84177191214496794, 0.82344092400426538,
0.80126261909933771, 0.77348704817668512, 0.73877220209616368,
0.69240897243333099, 0.62599194142499259, 0.52494563940985528,
0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)
))
), `>` = list(sensitivities = c(
1,
0.97560975609756095, 0.95121951219512191, 0.92682926829268297,
0.90243902439024393, 0.87804878048780488, 0.85365853658536583,
0.80487804878048785, 0.78048780487804881, 0.75609756097560976,
0.73170731707317072, 0.70731707317073167, 0.70731707317073167,
0.68292682926829273, 0.65853658536585369, 0.65853658536585369,
0.65853658536585369, 0.65853658536585369, 0.6097560975609756,
0.6097560975609756, 0.58536585365853655, 0.58536585365853655,
0.56097560975609762, 0.56097560975609762, 0.53658536585365857,
0.51219512195121952, 0.48780487804878048, 0.48780487804878048,
0.46341463414634149, 0.43902439024390244, 0.41463414634146339,
0.41463414634146339, 0.3902439024390244, 0.36585365853658536,
0.36585365853658536, 0.36585365853658536, 0.36585365853658536,
0.34146341463414637, 0.34146341463414637, 0.31707317073170732,
0.26829268292682928, 0.24390243902439024, 0.21951219512195122,
0.17073170731707318, 0.12195121951219512, 0.097560975609756101,
0.024390243902439025, 0.024390243902439025, 0.024390243902439025,
0.024390243902439025, 0
), specificities = c(
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0.027777777777777776, 0.027777777777777776,
0.041666666666666664, 0.069444444444444448, 0.083333333333333329,
0.097222222222222224, 0.097222222222222224, 0.1111111111111111,
0.1111111111111111, 0.125, 0.125, 0.1388888888888889, 0.15277777777777779,
0.16666666666666666, 0.16666666666666666, 0.18055555555555555,
0.18055555555555555, 0.18055555555555555, 0.18055555555555555,
0.19444444444444445, 0.19444444444444445, 0.19444444444444445,
0.22222222222222221, 0.2361111111111111, 0.2638888888888889,
0.30555555555555558, 0.3611111111111111, 0.41666666666666669,
0.45833333333333331, 0.45833333333333331, 0.51388888888888884,
0.61111111111111116, 0.69444444444444442, 0.77777777777777779,
0.86111111111111116, 0.88888888888888884, 0.93055555555555558,
1, 1
), thresholds = c(
Inf, 1.5149999999999999, 0.90999999999999992,
0.83999999999999997, 0.79499999999999993, 0.755, 0.72499999999999998,
0.70499999999999996, 0.6399999999999999, 0.57000000000000006,
0.54000000000000004, 0.51000000000000001, 0.495, 0.48499999999999999,
0.47499999999999998, 0.46499999999999997, 0.45500000000000002,
0.44500000000000001, 0.435, 0.41999999999999998, 0.39500000000000002,
0.36499999999999999, 0.34499999999999997, 0.33500000000000002,
0.32500000000000001, 0.31, 0.29000000000000004, 0.27500000000000002,
0.26500000000000001, 0.255, 0.245, 0.23499999999999999, 0.22500000000000001,
0.20500000000000002, 0.185, 0.17499999999999999, 0.16500000000000001,
0.155, 0.14500000000000002, 0.13500000000000001, 0.125, 0.11499999999999999,
0.10500000000000001, 0.095000000000000001, 0.084999999999999992,
0.075000000000000011, 0.065000000000000002, 0.055, 0.044999999999999998,
0.035000000000000003, -Inf
), auc = 0.26863143631436315, smooth = list(
binormal = list(sensitivities = c(
1, 1, 0.88888888888888884,
0.77777777777777768, 0.66666666666666663, 0.55555555555555558,
0.44444444444444442, 0.33333333333333337, 0.22222222222222213,
0.11111111111111113, 0, 0
), specificities = c(
0, 0, 0.0063257962802793768,
0.02618828104021155, 0.062435899176326318, 0.11872013303989556,
0.19982354021969684, 0.31241420043790291, 0.46667331569618037,
0.68073965931609826, 1, 1
)), density = list(sensitivities = c(
1,
1, 0.99956325378865984, 0.98250977145878382, 0.98250976422281866,
0.98250976422281722, 0.98244491037229364, 0.90994760473233038,
0.77082333930552882, 0.53518939906654595, 0.00068073667953089849,
0
), specificities = c(
0, 0, 3.690663638556004e-17, 3.690663638556004e-17,
3.690663638556004e-17, 3.8450687873718744e-17, 8.4026002997308378e-17,
1.1152374486878449e-11, 0.0038902206061686736, 0.12493272244762309,
0.99873921866488968, 1
)), fitdistr = list(sensitivities = c(
1,
1, 0.99998988006687617, 0.99985712442536112, 0.99865911658323359,
0.99122211852210751, 0.95946310474604235, 0.86616610473052713,
0.67762776311836914, 0.41553017871566622, 0.16488596329802269,
0
), specificities = c(
0, 0, 1.0236375083230024e-47, 2.9906095000627991e-37,
4.1678530082321198e-28, 2.7707940894835804e-20, 8.7868943140878936e-14,
1.3292550660413001e-08, 9.5934537797792092e-05, 0.033114889996037018,
0.57530428678941115, 1
)), logcondens = list(sensitivities = c(
1,
1, 0.96925785071341375, 0.9299795293124361, 0.87933626192559511,
0.82287867390211533, 0.76057870800949001, 0.68785049271852017,
0.59811207367258978, 0.48211757900052843, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
)), logcondens.smooth = list(
sensitivities = c(
1, 1, 0.84177191214496794, 0.82344092400426538,
0.80126261909933771, 0.77348704817668512, 0.73877220209616368,
0.69240897243333099, 0.62599194142499259, 0.52494563940985528,
0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)
)
))
), reversed = list(`<` = list(
sensitivities = c(
1, 1, 0.93055555555555558, 0.88888888888888884,
0.86111111111111116, 0.77777777777777779, 0.69444444444444442,
0.61111111111111116, 0.51388888888888884, 0.45833333333333331,
0.45833333333333331, 0.41666666666666669, 0.3611111111111111,
0.30555555555555558, 0.2638888888888889, 0.2361111111111111,
0.22222222222222221, 0.19444444444444445, 0.19444444444444445,
0.19444444444444445, 0.18055555555555555, 0.18055555555555555,
0.18055555555555555, 0.18055555555555555, 0.16666666666666666,
0.16666666666666666, 0.15277777777777779, 0.1388888888888889,
0.125, 0.125, 0.1111111111111111, 0.1111111111111111, 0.097222222222222224,
0.097222222222222224, 0.083333333333333329, 0.069444444444444448,
0.041666666666666664, 0.027777777777777776, 0.027777777777777776,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
), specificities = c(
0,
0.024390243902439025, 0.024390243902439025, 0.024390243902439025,
0.024390243902439025, 0.097560975609756101, 0.12195121951219512,
0.17073170731707318, 0.21951219512195122, 0.24390243902439024,
0.26829268292682928, 0.31707317073170732, 0.34146341463414637,
0.34146341463414637, 0.36585365853658536, 0.36585365853658536,
0.36585365853658536, 0.36585365853658536, 0.3902439024390244,
0.41463414634146339, 0.41463414634146339, 0.43902439024390244,
0.46341463414634149, 0.48780487804878048, 0.48780487804878048,
0.51219512195121952, 0.53658536585365857, 0.56097560975609762,
0.56097560975609762, 0.58536585365853655, 0.58536585365853655,
0.6097560975609756, 0.6097560975609756, 0.65853658536585369,
0.65853658536585369, 0.65853658536585369, 0.65853658536585369,
0.68292682926829273, 0.70731707317073167, 0.70731707317073167,
0.73170731707317072, 0.75609756097560976, 0.78048780487804881,
0.80487804878048785, 0.85365853658536583, 0.87804878048780488,
0.90243902439024393, 0.92682926829268297, 0.95121951219512191,
0.97560975609756095, 1
), thresholds = c(
-Inf, 0.035000000000000003,
0.044999999999999998, 0.055, 0.065000000000000002, 0.075000000000000011,
0.084999999999999992, 0.095000000000000001, 0.10500000000000001,
0.11499999999999999, 0.125, 0.13500000000000001, 0.14500000000000002,
0.155, 0.16500000000000001, 0.17499999999999999, 0.185, 0.20500000000000002,
0.22500000000000001, 0.23499999999999999, 0.245, 0.255, 0.26500000000000001,
0.27500000000000002, 0.29000000000000004, 0.31, 0.32500000000000001,
0.33500000000000002, 0.34499999999999997, 0.36499999999999999,
0.39500000000000002, 0.41999999999999998, 0.435, 0.44500000000000001,
0.45500000000000002, 0.46499999999999997, 0.47499999999999998,
0.48499999999999999, 0.495, 0.51000000000000001, 0.54000000000000004,
0.57000000000000006, 0.6399999999999999, 0.70499999999999996,
0.72499999999999998, 0.755, 0.79499999999999993, 0.83999999999999997,
0.90999999999999992, 1.5149999999999999, Inf
), auc = 0.26863143631436315,
smooth = list(binormal = list(sensitivities = c(
1, 1, 0.88888888888888884,
0.77777777777777768, 0.66666666666666663, 0.55555555555555558,
0.44444444444444442, 0.33333333333333337, 0.22222222222222213,
0.11111111111111113, 0, 0
), specificities = c(
0, 0, 0.036980450235785507,
0.077223470604070241, 0.12339217012272917, 0.17707059391233013,
0.24065190559688782, 0.3182498490917357, 0.41808483571447186,
0.56200769409386819, 1, 1
)), density = list(sensitivities = c(
1,
1, 0.99873921866488968, 0.12493272244762309, 0.0038902206061686736,
1.1152374486878449e-11, 8.4026002997308378e-17, 3.8450687873718744e-17,
3.690663638556004e-17, 3.690663638556004e-17, 3.690663638556004e-17,
0
), specificities = c(
0, 0, 0.00068073667953089849, 0.53518939906654595,
0.77082333930552882, 0.90994760473233038, 0.98244491037229364,
0.98250976422281722, 0.98250976422281866, 0.98250977145878382,
0.99956325378865984, 1
)), fitdistr = list(sensitivities = c(
1,
1, 0.57530428678941115, 0.033114889996037018, 9.5934537797792092e-05,
1.3292550660413001e-08, 8.7868943140878936e-14, 2.7707940894835804e-20,
4.1678530082321198e-28, 2.9906095000627991e-37, 1.0236375083230024e-47,
0
), specificities = c(
0, 0, 0.16488596329802269, 0.41553017871566622,
0.67762776311836914, 0.86616610473052713, 0.95946310474604235,
0.99122211852210751, 0.99865911658323359, 0.99985712442536112,
0.99998988006687617, 1
)), logcondens = list(sensitivities = c(
1,
1, 0.68640943170234492, 0.47305003502387177, 0.30140748787016336,
0.17529939841995956, 0.081977746864886791, 0.019706665328343642,
0, 0, 0, 0
), specificities = c(
0, 0, 0.11111111111111116,
0.22222222222222232, 0.33333333333333337, 0.44444444444444442,
0.55555555555555558, 0.66666666666666674, 0.77777777777777779,
0.88888888888888884, 1, 1
)), logcondens.smooth = list(sensitivities = c(
1,
1, 0.68160709500887995, 0.52447817567232491, 0.35644973890290044,
0.21421346701630162, 0.10440198579322246, 0.032733231067172075,
0.0023298031569144451, 2.8609038515980956e-07, 0, 0
), specificities = c(
0,
0, 0.11111111111111116, 0.22222222222222232, 0.33333333333333337,
0.44444444444444442, 0.55555555555555558, 0.66666666666666674,
0.77777777777777779, 0.88888888888888884, 1, 1
)))
), `>` = list(
sensitivities = c(
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.97222222222222221,
0.97222222222222221, 0.95833333333333337, 0.93055555555555558,
0.91666666666666663, 0.90277777777777779, 0.90277777777777779,
0.88888888888888884, 0.88888888888888884, 0.875, 0.875, 0.86111111111111116,
0.84722222222222221, 0.83333333333333337, 0.83333333333333337,
0.81944444444444442, 0.81944444444444442, 0.81944444444444442,
0.81944444444444442, 0.80555555555555558, 0.80555555555555558,
0.80555555555555558, 0.77777777777777779, 0.76388888888888884,
0.73611111111111116, 0.69444444444444442, 0.63888888888888884,
0.58333333333333337, 0.54166666666666663, 0.54166666666666663,
0.4861111111111111, 0.3888888888888889, 0.30555555555555558,
0.22222222222222221, 0.1388888888888889, 0.1111111111111111,
0.069444444444444448, 0, 0
), specificities = c(
0, 0.024390243902439025,
0.04878048780487805, 0.073170731707317069, 0.097560975609756101,
0.12195121951219512, 0.14634146341463414, 0.1951219512195122,
0.21951219512195122, 0.24390243902439024, 0.26829268292682928,
0.29268292682926828, 0.29268292682926828, 0.31707317073170732,
0.34146341463414637, 0.34146341463414637, 0.34146341463414637,
0.34146341463414637, 0.3902439024390244, 0.3902439024390244,
0.41463414634146339, 0.41463414634146339, 0.43902439024390244,
0.43902439024390244, 0.46341463414634149, 0.48780487804878048,
0.51219512195121952, 0.51219512195121952, 0.53658536585365857,
0.56097560975609762, 0.58536585365853655, 0.58536585365853655,
0.6097560975609756, 0.63414634146341464, 0.63414634146341464,
0.63414634146341464, 0.63414634146341464, 0.65853658536585369,
0.65853658536585369, 0.68292682926829273, 0.73170731707317072,
0.75609756097560976, 0.78048780487804881, 0.82926829268292679,
0.87804878048780488, 0.90243902439024393, 0.97560975609756095,
0.97560975609756095, 0.97560975609756095, 0.97560975609756095,
1
), thresholds = c(
Inf, 1.5149999999999999, 0.90999999999999992,
0.83999999999999997, 0.79499999999999993, 0.755, 0.72499999999999998,
0.70499999999999996, 0.6399999999999999, 0.57000000000000006,
0.54000000000000004, 0.51000000000000001, 0.495, 0.48499999999999999,
0.47499999999999998, 0.46499999999999997, 0.45500000000000002,
0.44500000000000001, 0.435, 0.41999999999999998, 0.39500000000000002,
0.36499999999999999, 0.34499999999999997, 0.33500000000000002,
0.32500000000000001, 0.31, 0.29000000000000004, 0.27500000000000002,
0.26500000000000001, 0.255, 0.245, 0.23499999999999999, 0.22500000000000001,
0.20500000000000002, 0.185, 0.17499999999999999, 0.16500000000000001,
0.155, 0.14500000000000002, 0.13500000000000001, 0.125, 0.11499999999999999,
0.10500000000000001, 0.095000000000000001, 0.084999999999999992,
0.075000000000000011, 0.065000000000000002, 0.055, 0.044999999999999998,
0.035000000000000003, -Inf
), auc = 0.73136856368563685, smooth = list(
binormal = list(sensitivities = c(
1, 1, 0.88888888888888884,
0.77777777777777768, 0.66666666666666663, 0.55555555555555558,
0.44444444444444442, 0.33333333333333337, 0.22222222222222213,
0.11111111111111113, 0, 0
), specificities = c(
0, 0, 0.43799230590613181,
0.58191516428552836, 0.68175015090826441, 0.75934809440311224,
0.82292940608766996, 0.87660782987727093, 0.92277652939592991,
0.96301954976421456, 1, 1
)), density = list(sensitivities = c(
1,
1, 1, 1, 1, 1, 1, 0.99999999998884759, 0.99610977939383138,
0.8750672775523769, 0.0012607813351102808, 0
), specificities = c(
0,
0, 0.00043674621134013675, 0.017490228541216186, 0.017490235777181288,
0.017490235777182776, 0.017555089627706303, 0.09005239526766956,
0.22917666069447112, 0.464810600933454, 0.99931926332046905,
1
)), fitdistr = list(sensitivities = c(
1, 1, 1, 1, 1,
1, 0.99999999999991218, 0.9999999867074495, 0.99990406546220234,
0.96688511000396316, 0.42469571321058891, 0
), specificities = c(
0,
0, 1.0119933123736651e-05, 0.00014287557463888575, 0.0013408834167663738,
0.0087778814778924647, 0.040536895253957712, 0.13383389526947279,
0.3223722368816308, 0.58446982128433378, 0.83511403670197726,
1
)), logcondens = list(sensitivities = c(
1, 1, 0.68640943170234492,
0.47305003502387177, 0.30140748787016336, 0.17529939841995956,
0.081977746864886791, 0.019706665328343642, 0, 0, 0,
0
), specificities = c(
0, 0, 0.11111111111111116, 0.22222222222222232,
0.33333333333333337, 0.44444444444444442, 0.55555555555555558,
0.66666666666666674, 0.77777777777777779, 0.88888888888888884,
1, 1
)), logcondens.smooth = list(
sensitivities = c(
1,
1, 0.68160709500887995, 0.52447817567232491, 0.35644973890290044,
0.21421346701630162, 0.10440198579322246, 0.032733231067172075,
0.0023298031569144451, 2.8609038515980956e-07, 0, 0
),
specificities = c(
0, 0, 0.11111111111111116, 0.22222222222222232,
0.33333333333333337, 0.44444444444444442, 0.55555555555555558,
0.66666666666666674, 0.77777777777777779, 0.88888888888888884,
1, 1
)
)
)
))))
pROC/tests/testthat/helper-roc.utils-expected.R 0000644 0001762 0000144 00000006006 15040443562 021205 0 ustar ligges users expected_roc_utils_calc_coords <-
structure(c(
-1, -2, -3, -4, 1, 0.5, 0.10000000000000001, 0, 0,
0.5, 0.90000000000000002, 1, 0.36283185840707965, 0.5, 0.60973451327433625,
0.63716814159292035, 0, 36, 64.799999999999997, 72, 41, 20.5,
4.1000000000000005, 0, 0, 20.5, 36.899999999999999, 41, 72, 36,
7.2000000000000028, 0, NaN, 0.63716814159292035, 0.63716814159292035,
0.63716814159292035, 0.36283185840707965, 0.36283185840707965,
0.36283185840707954, NaN, 1, 0.5, 0.10000000000000001, 0, 0,
0.5, 0.90000000000000002, 1, 1, 0.5, 0.099999999999999978, 0,
0, 0.5, 0.89999999999999991, 1, 0.63716814159292035, 0.63716814159292035,
0.63716814159292035, NaN, 1, 0.5, 0.099999999999999978, 0, 0,
0.5, 0.90000000000000002, 1, 0.63716814159292035, 0.5, 0.39026548672566375,
0.36283185840707965, NaN, 0.36283185840707965, 0.36283185840707965,
0.36283185840707965, 0.63716814159292035, 0.63716814159292035,
0.63716814159292046, NaN, 0.36283185840707965, 0.36283185840707965,
0.36283185840707954, NaN, 1, 0.5, 0.10000000000000001, 0, 1,
1, 1.0000000000000002, NaN, NaN, 1, 1, 1, 1, 0.50462962962962965,
0.10833333333333334, 0.009259259259259257, 0.009259259259259257,
0.25231481481481483, 0.8100925925925927, 1
), .Dim = c(4L, 26L), .Dimnames = list(NULL, c(
"threshold", "sensitivity", "specificity",
"accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "tpr", "tnr",
"fpr", "fnr", "fdr", "1-specificity", "1-sensitivity", "1-accuracy",
"1-npv", "1-ppv", "precision", "recall", "lr_pos", "lr_neg",
"youden", "closest.topleft"
)))
expected_roc_utils_calc_coords.percent <-
structure(c(
-1, -2, -3, -4, 100, 50, 10, 0, 0, 50, 90, 100, 36.283185840707965,
50, 60.973451327433622, 63.716814159292035, 0, 36, 64.799999999999997,
72, 41, 20.5, 4.0999999999999996, 0, 0, 20.5, 36.899999999999999,
41, 72, 36, 7.2000000000000028, 0, NaN, 63.716814159292035, 63.716814159292042,
63.716814159292035, 36.283185840707965, 36.283185840707965, 36.283185840707951,
NaN, 100, 50, 10, 0, 0, 50, 90, 100, 100, 50, 10, 0, 0, 50, 90,
100, 63.716814159292035, 63.716814159292035, 63.716814159292042,
NaN, 100, 50, 10, 0, 0, 50, 90, 100, 63.716814159292035, 50,
39.026548672566378, 36.283185840707965, NaN, 36.283185840707965,
36.283185840707958, 36.283185840707965, 63.716814159292035, 63.716814159292035,
63.716814159292049, NaN, 36.283185840707965, 36.283185840707965,
36.283185840707951, NaN, 100, 50, 10, 0, 1, 1, 1.0000000000000002,
NaN, NaN, 1, 1, 1, 100, 50.462962962962962, 10.833333333333334,
0.92592592592592571, 0.92592592592592571, 25.231481481481481,
81.009259259259267, 100
), .Dim = c(4L, 26L), .Dimnames = list(
NULL, c(
"threshold", "sensitivity", "specificity", "accuracy",
"tn", "tp", "fn", "fp", "npv", "ppv", "tpr", "tnr", "fpr",
"fnr", "fdr", "1-specificity", "1-sensitivity", "1-accuracy",
"1-npv", "1-ppv", "precision", "recall", "lr_pos", "lr_neg",
"youden", "closest.topleft"
)
))
pROC/tests/testthat/test-ggroc.R 0000644 0001762 0000144 00000007173 15040443562 016273 0 ustar ligges users context("ggroc")
test_that("Ggroc screenshot looks normal", {
skip_if(packageVersion("ggplot2") < "2.4")
test_ggplot_screenshot <- function() {
print(ggroc(r.s100b.percent, alpha = 0.5, colour = "red", linetype = 2, linewidth = 2))
}
expect_ggroc_doppelganger("ggroc.screenshot", test_ggplot_screenshot)
})
test_that("Ggroc works with legacy.axis and percent", {
skip_if(packageVersion("ggplot2") < "2.4")
# nothing
test_ggplot_screenshot <- function() {
print(ggroc(r.s100b))
}
expect_ggroc_doppelganger("ggroc.screenshot_base", test_ggplot_screenshot)
# percent
test_ggplot_screenshot <- function() {
print(ggroc(r.s100b.percent))
}
expect_ggroc_doppelganger("ggroc.screenshot_percent", test_ggplot_screenshot)
# legacy.axes
test_ggplot_screenshot <- function() {
print(ggroc(r.s100b, legacy.axes = TRUE))
}
expect_ggroc_doppelganger("ggroc.screenshot_legacy", test_ggplot_screenshot)
# percent, legacy.axes
test_ggplot_screenshot <- function() {
print(ggroc(r.s100b.percent, legacy.axes = TRUE))
}
expect_ggroc_doppelganger("ggroc.screenshot_percent_legacy", test_ggplot_screenshot)
})
test_that("Ggroc list screenshot looks normal", {
test_ggplot_list_screenshot <- function() {
print(ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka)))
}
expect_ggroc_doppelganger("ggroc.list.screenshot", test_ggplot_list_screenshot)
})
test_that("Ggroc list can take multiple aes", {
test_ggplot_list_screenshot <- function() {
print(ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka), aes = c("c", "linetype")))
}
expect_ggroc_doppelganger("ggroc.list.multi.aes", test_ggplot_list_screenshot)
})
test_that("Ggroc list doesn't get merged with set colour", {
test_ggplot_list_screenshot <- function() {
print(ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka), colour = "red"))
}
expect_ggroc_doppelganger("ggroc.list.colour", test_ggplot_list_screenshot)
})
test_that("Ggroc list extra aestetics screenshot looks normal", {
test_ggplot_list_extra_aes_screenshot <- function() {
print(ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka), aes = "linetype", color = "red"))
}
expect_ggroc_doppelganger("ggroc.list.extra.aes.screenshot", test_ggplot_list_extra_aes_screenshot)
})
test_that("Ggroc list with group facet screenshot looks normal", {
test_ggplot_list_group_facet_screenshot <- function() {
library(ggplot2)
g <- ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka), aes = "group") + facet_grid(. ~ name)
print(g)
}
expect_ggroc_doppelganger("ggroc.list.group.facet.screenshot", test_ggplot_list_group_facet_screenshot)
})
test_that("Ggroc aesthetics can be modified with scale_colour_manual", {
test_ggplot_list_screenshot <- function() {
print(ggroc(list(s100b = r.s100b, wfns = r.wfns, ndka = r.ndka), aes = c("c", "linetype")) +
scale_colour_manual(values = c("purple", "yellow", "purple")))
}
expect_ggroc_doppelganger("ggroc.list.scale.colour.manual", test_ggplot_list_screenshot)
})
test_that("Ggroc screenshot looks normal with a single smooth.roc", {
skip_if(packageVersion("ggplot2") < "2.4")
test_ggplot_screenshot <- function() {
print(ggroc(smooth(r.s100b), , alpha = 0.5, colour = "red", linetype = 2, linewidth = 2))
}
expect_ggroc_doppelganger("ggroc.smooth.screenshot", test_ggplot_screenshot)
})
test_that("Ggroc screenshot looks normal with a list of smooth.roc", {
test_ggplot_screenshot <- function() {
print(ggroc(list(s100b = smooth(r.s100b), wfns = smooth(r.wfns), ndka = smooth(r.ndka))))
}
expect_ggroc_doppelganger("ggroc.smooth.list.screenshot", test_ggplot_screenshot)
})
pROC/tests/testthat/_snaps/ 0000755 0001762 0000144 00000000000 15040443562 015345 5 ustar ligges users pROC/tests/testthat/_snaps/plot/ 0000755 0001762 0000144 00000000000 15040443562 016323 5 ustar ligges users pROC/tests/testthat/_snaps/plot/legacy-axes.svg 0000644 0001762 0000144 00000012770 14427235226 021261 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-4.svg 0000644 0001762 0000144 00000027141 14520415670 023133 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-6.svg 0000644 0001762 0000144 00000017740 14427235226 023144 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/basic-ndka.svg 0000644 0001762 0000144 00000014443 14427235226 021052 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/plot-pr.svg 0000644 0001762 0000144 00000022016 15040443562 020442 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-1.svg 0000644 0001762 0000144 00000016217 14427235226 023135 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/plot-formula.svg 0000644 0001762 0000144 00000017725 14427235226 021505 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-3.svg 0000644 0001762 0000144 00000070014 14427235226 023132 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-5.svg 0000644 0001762 0000144 00000014660 14520415670 023136 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/basic-s100b.svg 0000644 0001762 0000144 00000012764 14427235226 020766 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/advanced-screenshot-2.svg 0000644 0001762 0000144 00000017650 14520415670 023135 0 ustar ligges users
pROC/tests/testthat/_snaps/plot/basic-wfns.svg 0000644 0001762 0000144 00000011602 14427235226 021104 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ 0000755 0001762 0000144 00000000000 15040443562 016446 5 ustar ligges users pROC/tests/testthat/_snaps/ggroc/ggroc-list-group-facet-screenshot.svg 0000644 0001762 0000144 00000044573 14427235226 025647 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-smooth-screenshot.svg 0000644 0001762 0000144 00000032727 14427235226 023771 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-list-colour.svg 0000644 0001762 0000144 00000022005 14520415670 022542 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-screenshot-base.svg 0000644 0001762 0000144 00000016413 14520415670 023361 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-screenshot-legacy.svg 0000644 0001762 0000144 00000016415 14520415670 023715 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-list-screenshot.svg 0000644 0001762 0000144 00000024571 15040443562 023425 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-list-scale-colour-manual.svg 0000644 0001762 0000144 00000024755 15040443562 025117 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-list-extra-aes-screenshot.svg 0000644 0001762 0000144 00000024755 15040443562 025320 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-screenshot-percent.svg 0000644 0001762 0000144 00000016357 14520415670 024116 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-screenshot-percent-legacy.svg 0000644 0001762 0000144 00000016361 14520415670 025353 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-screenshot.svg 0000644 0001762 0000144 00000016465 14427235226 022463 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-list-multi-aes.svg 0000644 0001762 0000144 00000024755 15040443562 023154 0 ustar ligges users
pROC/tests/testthat/_snaps/ggroc/ggroc-smooth-list-screenshot.svg 0000644 0001762 0000144 00000071126 15040443562 024732 0 ustar ligges users
pROC/tests/testthat/_snaps/geom_polygon_auc/ 0000755 0001762 0000144 00000000000 15040443562 020673 5 ustar ligges users pROC/tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-percent-legacy-screenshot.svg 0000644 0001762 0000144 00000020030 15040443562 031644 0 ustar ligges users
pROC/tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-screenshot.svg 0000644 0001762 0000144 00000020062 15040443562 026751 0 ustar ligges users
pROC/tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-partial-screenshot.svg 0000644 0001762 0000144 00000017460 15040443562 030413 0 ustar ligges users
pROC/tests/testthat/test-numeric-Inf.R 0000644 0001762 0000144 00000001600 15040443562 017333 0 ustar ligges users library(pROC)
test_that("roc rejects rejects invalid data", {
# Control always negative
controls <- c(-Inf, 1, 2, 3, 4, 5)
cases <- c(2, 3, 4, 5, 6)
expect_warning(r <- roc(controls = controls, cases = cases), "Infinite value")
expect_equal(r, NaN)
# Control always positive
# 100% specificity impossible
controls <- c(1, 2, 3, 4, 5, Inf)
cases <- c(2, 3, 4, 5, 6)
expect_warning(r <- roc(controls = controls, cases = cases), "Infinite value")
expect_equal(r, NaN)
})
test_that("roc rejects rejects also valid data", {
# OK
controls <- c(1, 2, 3, 4, 5)
cases <- c(-Inf, 2, 3, 4, 5, 6)
expect_warning(r <- roc(controls = controls, cases = cases), "Infinite value")
expect_equal(r, NaN)
# OK
controls <- c(1, 2, 3, 4, Inf)
cases <- c(2, 3, 4, 5, 6)
expect_warning(r <- roc(controls = controls, cases = cases), "Infinite value")
expect_equal(r, NaN)
})
pROC/tests/testthat/test-coords.R 0000644 0001762 0000144 00000064634 15040443562 016470 0 ustar ligges users library(pROC)
data(aSAH)
context("coords")
test_that("coords with thresholds works", {
return.rows <- c("threshold", "specificity", "sensitivity", "accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "1-specificity", "1-sensitivity", "1-accuracy", "1-npv", "1-ppv", "lr_pos", "lr_neg", "youden", "closest.topleft")
obtained <- coords(r.s100b, "all", ret = return.rows)
expect_equal(obtained, expected.coords[, return.rows])
})
test_that("coords returns all thresholds by default", {
obtained <- coords(r.s100b)
expect_equal(obtained, expected.coords[, c("threshold", "specificity", "sensitivity")])
# but not if it's an empty numeric, as this might be indicative of user error
expect_error(coords(r.s100b, numeric(0)), "length")
})
test_that("coords returns all thresholds by default with smooth.roc", {
obtained <- coords(smooth(r.s100b))
expect_equal(obtained, expected.coords.smooth[, c("specificity", "sensitivity")])
# but not if it's an empty numeric, as this might be indicative of user error
expect_error(coords(r.s100b, numeric(0)), "length")
})
test_that("coords returns all columns with ret = 'all' with smooth.roc", {
obtained <- coords(smooth(r.s100b), ret = "all")
expect_equal(obtained, expected.coords.smooth)
})
test_that("coords with transpose = TRUE works", {
suppressWarnings({
return.rows <- c("threshold", "specificity", "sensitivity", "accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "1-specificity", "1-sensitivity", "1-accuracy", "1-npv", "1-ppv", "youden", "closest.topleft")
obtained <- coords(r.s100b, "all", ret = return.rows, transpose = TRUE)
expect_equal(obtained, t(expected.coords[, return.rows]))
obtained <- coords(r.s100b, transpose = TRUE)
expect_equal(obtained, t(expected.coords[, c("threshold", "specificity", "sensitivity")]))
# With drop=TRUE
obtained <- coords(r.s100b, "all", ret = "se", transpose = TRUE, drop = TRUE)
expect_is(obtained, "numeric")
# Not why drop.data.frame returns a list, skipping
# obtained <- coords(r.s100b, "best", ret = "all", transpose = FALSE, drop=TRUE)
# With drop=FALSE
obtained <- coords(r.s100b, "all", ret = "se", transpose = TRUE, drop = FALSE)
expect_is(obtained, "matrix")
})
})
test_that("coords with ret='all' works", {
obtained <- coords(r.s100b, "all", ret = "all")
expect_equal(dim(obtained), c(51, 26))
expect_equal(obtained[, colnames(expected.coords)], expected.coords)
})
test_that("coords with ret='all' doesn't accept additional options", {
expect_error(coords(r.s100b, "all", ret = c("all", "thresholds")))
})
test_that("coords with percent works", {
return.rows <- "all"
percent.cols <- c("specificity", "sensitivity", "accuracy", "npv", "ppv", "1-specificity", "1-sensitivity", "1-accuracy", "1-npv", "1-ppv", "youden", "closest.topleft", "fdr", "fpr", "tpr", "tnr", "fnr", "precision", "recall")
obtained.percent <- coords(r.s100b.percent, "all", ret = return.rows)
# Adjust for percent
obtained.percent[, percent.cols] <- obtained.percent[, percent.cols] / 100
expect_equal(obtained.percent, expected.coords)
})
test_that("coords with local maximas thresholds works", {
return.rows <- "all"
obtained <- coords(r.s100b, "local maximas", ret = return.rows)
# expected.thresholds <- c(-Inf, 0.065, 0.075, 0.085, 0.095, 0.105, 0.115, 0.135, 0.155, 0.205, 0.245, 0.29, 0.325, 0.345, 0.395, 0.435, 0.475, 0.485, 0.51)
expected.thresholds <- c(
-Inf, 0x1.0a3d70a3d70a4p-4, 0x1.3333333333334p-4,
0x1.5c28f5c28f5c2p-4, 0x1.851eb851eb852p-4, 0x1.ae147ae147ae2p-4,
0x1.d70a3d70a3d7p-4, 0x1.147ae147ae148p-3, 0x1.3d70a3d70a3d7p-3,
0x1.a3d70a3d70a3ep-3, 0x1.f5c28f5c28f5cp-3, 0x1.28f5c28f5c29p-2,
0x1.4cccccccccccdp-2, 0x1.6147ae147ae14p-2, 0x1.947ae147ae148p-2,
0x1.bd70a3d70a3d7p-2, 0x1.e666666666666p-2, 0x1.f0a3d70a3d70ap-2,
0x1.051eb851eb852p-1
)
expect_equal(as.vector(obtained[, "threshold"]), expected.thresholds)
expect_equivalent(obtained, expected.coords[expected.coords[, "threshold"] %in% expected.thresholds, ])
})
test_that("coords with best threshold works", {
return.rows <- "all"
obtained <- coords(r.s100b, "best", ret = return.rows)
expect_equivalent(obtained, expected.coords[abs(expected.coords[, "threshold"] - 0.205) < 0.001, , drop = FALSE])
})
test_that("coords with arbitrary thresholds works", {
return.rows <- c("threshold", "specificity", "sensitivity", "accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "1-specificity", "1-sensitivity", "1-accuracy", "1-npv", "1-ppv", "youden", "closest.topleft")
obtained <- coords(r.s100b, c(0.205, 0.055), input = "threshold", ret = return.rows)
expect_equivalent(obtained, expected.coords[c(18, 4), return.rows])
})
test_that("coords with arbitrary thresholds at exact data point works", {
return.rows <- "all"
expect_equal(sum(aSAH$s100b == 0.05), 3)
expect_equal(sum(aSAH$s100b == 0.52), 1)
obtained <- coords(r.s100b, c(0.05, 0.52), input = "threshold", ret = return.rows)
expect_equivalent(obtained[, -1], expected.coords[c(3, 40), -1])
})
test_that("coords with arbitrary thresholds works with direction=>", {
obtained <- coords(r.s100b.reversed, c(0.05, 0.055, 0.205, 0.52), input = "threshold", ret = "all")
expect_equivalent(obtained, expected.coords.reverse)
})
test_that("coords with single arbitrary threshold works", {
return.rows <- "all"
obtained <- coords(r.s100b, c(0.205), input = "threshold", ret = return.rows)
expect_equivalent(obtained, expected.coords[18, , drop = FALSE])
})
test_that("coords with arbitrary thresholds at exact data point works", {
expect_equal(sum(aSAH$s100b == 0.05), 3)
expect_equal(sum(aSAH$s100b == 0.52), 1)
obtained <- coords(r.s100b, c(0.05), input = "threshold", ret = "all")
expect_equivalent(obtained[, -1], expected.coords[3, -1])
obtained <- coords(r.s100b, c(0.52), input = "threshold", ret = "all")
expect_equivalent(obtained[, -1], expected.coords[40, -1])
})
test_that("coords with arbitrary thresholds works with direction=>", {
obtained <- coords(r.s100b.reversed, c(0.05), input = "threshold", ret = "all")
expect_equivalent(obtained, expected.coords.reverse[1, ])
obtained <- coords(r.s100b.reversed, c(0.055), input = "threshold", ret = "all")
expect_equivalent(obtained, expected.coords.reverse[2, ])
obtained <- coords(r.s100b.reversed, c(0.205), input = "threshold", ret = "all")
expect_equivalent(obtained, expected.coords.reverse[3, ])
obtained <- coords(r.s100b.reversed, c(0.52), input = "threshold", ret = "all")
expect_equivalent(obtained, expected.coords.reverse[4, ])
})
test_that("coords with sensitivity works", {
obtained <- coords(r.s100b, seq(0, 1, .1), input = "sensitivity", ret = c("threshold", "specificity", "sensitivity"))
expect_equal(obtained[, "threshold"], c(Inf, rep(NA, 9), -Inf))
expect_equal(obtained[, "sensitivity"], seq(0, 1, .1))
expect_equal(obtained[, "specificity"], c(1, 1, 1, 0.972222222222222, 0.888888888888889, 0.833333333333333, 0.805555555555556, 0.56875, 0.447222222222222, 0.230555555555556, 0))
})
test_that("coords with sensitivity works with percent", {
obtained <- coords(r.s100b.percent, seq(0, 100, 10), input = "sensitivity", ret = c("threshold", "specificity", "sensitivity"))
expect_equal(obtained[, "threshold"], c(Inf, rep(NA, 9), -Inf))
expect_equal(obtained[, "sensitivity"], seq(0, 100, 10))
expect_equal(obtained[, "specificity"], c(1, 1, 1, 0.972222222222222, 0.888888888888889, 0.833333333333333, 0.805555555555556, 0.56875, 0.447222222222222, 0.230555555555556, 0) * 100)
})
test_that("coords with specificity works", {
obtained <- coords(r.s100b, seq(0, 1, .1), input = "specificity", ret = c("threshold", "specificity", "sensitivity"))
expect_equal(obtained[, "threshold"], c(-Inf, rep(NA, 9), 0.51))
expect_equal(obtained[, "specificity"], seq(0, 1, .1))
expect_equal(obtained[, "sensitivity"], c(1, 0.975609756097561, 0.921951219512195, 0.879674796747967, 0.823693379790941, 0.774390243902439, 0.675609756097561, 0.655284552845528, 0.634146341463415, 0.390243902439024, 0.292682926829268))
})
test_that("coords with specificity works with percent", {
obtained <- coords(r.s100b.percent, seq(0, 100, 10), input = "specificity", ret = c("threshold", "specificity", "sensitivity"))
expect_equal(obtained[, "threshold"], c(-Inf, rep(NA, 9), 0.51))
expect_equal(obtained[, "specificity"], seq(0, 100, 10))
expect_equal(obtained[, "sensitivity"], c(1, 0.975609756097561, 0.921951219512195, 0.879674796747967, 0.823693379790941, 0.774390243902439, 0.675609756097561, 0.655284552845528, 0.634146341463415, 0.390243902439024, 0.292682926829268) * 100)
})
test_that("drop works", {
suppressWarnings({
# First make sure we get matrices with drop = FALSE
expect_is(coords(r.s100b, 0.51, input = "threshold", ret = c("sensitivity", "specificity"), drop = FALSE, transpose = TRUE), "matrix")
expect_is(coords(r.s100b, 0.51, input = "threshold", ret = "specificity", drop = FALSE, transpose = TRUE), "matrix")
expect_is(coords(r.s100b, "local maximas", input = "threshold", ret = "specificity", drop = FALSE, transpose = TRUE), "matrix")
expect_is(coords(r.s100b, c(0.51, 0.2), input = "threshold", ret = "specificity", drop = FALSE, transpose = TRUE), "matrix")
# Look for numeric
expect_is(coords(r.s100b, 0.51, input = "threshold", ret = c("sensitivity", "specificity"), drop = TRUE, transpose = TRUE), "numeric")
expect_is(coords(r.s100b, 0.51, input = "threshold", ret = "specificity", drop = TRUE, transpose = TRUE), "numeric")
expect_is(coords(r.s100b, "local maximas", input = "threshold", ret = "specificity", drop = TRUE, transpose = TRUE), "numeric")
expect_is(coords(r.s100b, c(0.51, 0.2), input = "threshold", ret = "specificity", drop = TRUE, transpose = TRUE), "numeric")
})
})
test_that("coords returns the correct basic values ", {
obtained <- coords(r.s100b, 0.205,
ret = c(
"t", "tp", "fp", "tn", "fn",
"sp", "se", "acc",
"npv", "ppv", "precision", "recall",
"tpr", "fpr", "tnr", "fnr", "fdr"
)
)
obtained.percent <- coords(r.s100b.percent, 0.205,
ret = c(
"t", "tp", "fp", "tn", "fn",
"sp", "se", "acc",
"npv", "ppv", "precision", "recall",
"tpr", "fpr", "tnr", "fnr", "fdr"
)
)
# We assume the following values:
# tp fp tn fn N
# 26 14 58 15 113
expected <- data.frame(
threshold = 0.205,
tp = 26,
fp = 14,
tn = 58,
fn = 15,
specificity = 58 / (58 + 14),
sensitivity = 26 / (26 + 15),
accuracy = (26 + 58) / 113,
npv = 58 / (58 + 15),
ppv = 26 / (26 + 14),
precision = 26 / (26 + 14),
recall = 26 / (26 + 15),
tpr = 26 / (26 + 15),
fpr = 1 - (58 / (58 + 14)),
tnr = 58 / (58 + 14),
fnr = 1 - (26 / (26 + 15)),
fdr = 14 / (26 + 14)
)
expect_equivalent(obtained, expected)
expect_equivalent(obtained.percent[, 1:5], expected[, 1:5])
expect_equivalent(obtained.percent[, 6:17], expected[, 6:17] * 100)
})
test_that("coords works with smooth.roc and x = 'best' and transpose=TRUE", {
suppressWarnings({
smooth.s100b <- smooth(r.s100b)
expect <- structure(c(
0.750857175922901, 0.608610567514677, 0.699245574642041,
54.0617166664488, 24.9530332681018, 16.0469667318982, 17.9382833335512,
0.771112992655678, 0.581773544045047, 0.418226455954953, 0.249142824077099,
0.608610567514677, 0.750857175922901, 0.391389432485323, 0.249142824077099,
0.391389432485323, 0.300754425357959, 0.228887007344322, 0.418226455954953,
0.581773544045047, 0.608610567514677, 2.4428179690470926, 0.52125683157286817,
1.35946774343758, 0.215257834650296
), .Dim = c(25L, 1L), .Dimnames = list(c(
"specificity", "sensitivity",
"accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "fdr", "fpr",
"tpr", "tnr", "fnr", "1-specificity", "1-sensitivity", "1-accuracy",
"1-npv", "1-ppv", "precision", "recall", "lr_pos", "lr_neg",
"youden", "closest.topleft"
), NULL))
reduced.cols <- c("specificity", "sensitivity", "youden")
obtained <- coords(smooth.s100b, "best", ret = reduced.cols, transpose = TRUE)
expect_equal(obtained, expect[reduced.cols, ])
obtained <- coords(smooth.s100b, "best", ret = reduced.cols, drop = FALSE, transpose = TRUE)
expect_equal(obtained, expect[reduced.cols, , drop = FALSE])
obtained <- coords(smooth.s100b, "best", ret = "all", drop = FALSE, transpose = TRUE)
expect_equal(obtained, expect)
obtained <- coords(smooth.s100b, "best", ret = "all", transpose = TRUE)
expect_equal(obtained, expect[, 1])
obtained <- coords(smooth.s100b, "best", ret = "all", drop = FALSE, transpose = TRUE)
expect_equal(obtained, expect)
expect_warning(obtained <- coords(smooth.s100b, "best", ret = "all", as.list = TRUE), "as.list")
expect_equal(obtained, as.list(expect[, 1]))
expect_equal(names(obtained), rownames(expect))
expect_warning(obtained <- coords(smooth.s100b, "best", ret = "all", as.list = TRUE, drop = FALSE), "as.list")
expect_equal(obtained[[1]], as.list(expect[, 1])) # names
expect_equal(names(obtained[[1]]), rownames(expect))
expect_warning(obtained <- coords(smooth.s100b, "best", ret = reduced.cols, as.list = TRUE), "as.list")
expect_equal(obtained, as.list(expect[reduced.cols, 1]))
expect_equal(names(obtained), reduced.cols)
expect_warning(obtained <- coords(smooth.s100b, "best", ret = reduced.cols, as.list = TRUE, drop = FALSE), "as.list")
expect_equal(obtained[[1]], as.list(expect[reduced.cols, 1])) # names
expect_equal(names(obtained[[1]]), reduced.cols)
})
})
test_that("coords works with smooth.roc", {
suppressWarnings({
smooth.s100b <- smooth(r.s100b)
expect <- structure(c(
0.750857175922901, 0.608610567514677, 0.699245574642041,
54.0617166664488, 24.9530332681018, 16.0469667318982, 17.9382833335512,
0.771112992655678, 0.581773544045047, 0.418226455954953, 0.249142824077099,
0.608610567514677, 0.750857175922901, 0.391389432485323, 0.249142824077099,
0.391389432485323, 0.300754425357959, 0.228887007344322, 0.418226455954953,
0.581773544045047, 0.608610567514677, 2.4428179690470926, 0.52125683157286817,
1.35946774343758, 0.215257834650296
), .Dim = c(25L, 1L), .Dimnames = list(c(
"specificity", "sensitivity",
"accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "fdr", "fpr",
"tpr", "tnr", "fnr", "1-specificity", "1-sensitivity", "1-accuracy",
"1-npv", "1-ppv", "precision", "recall", "lr_pos", "lr_neg",
"youden", "closest.topleft"
), NULL))
reduced.cols <- c("specificity", "sensitivity", "youden")
obtained <- coords(smooth.s100b, "best", ret = reduced.cols)
expect_equal(obtained, as.data.frame(t(expect[reduced.cols, , drop = FALSE])))
obtained <- coords(smooth.s100b, "best", ret = "all", drop = FALSE)
expect_equal(obtained, as.data.frame(t(expect)))
# Without drop
obtained <- coords(smooth.s100b, "best", ret = reduced.cols)
expect_equivalent(obtained, as.data.frame(t(expect[reduced.cols, ])))
# drop = TRUE
expect_warning(obtained <- coords(smooth.s100b, "best", ret = reduced.cols, drop = TRUE))
expect_equal(obtained, as.list(expect[reduced.cols, ]))
# With as.matrix
expect_warning(obtained <- coords(smooth.s100b, "best", ret = reduced.cols, as.matrix = TRUE))
expect_equal(obtained, t(expect[reduced.cols, , drop = FALSE]))
# With matrix and drop = TRUE
expect_warning(obtained <- coords(smooth.s100b, "best", ret = reduced.cols, as.matrix = TRUE, drop = TRUE))
expect_equal(obtained, expect[reduced.cols, ])
# Default drop with numeric
obtained <- coords(smooth.s100b, c(0.2, 0.5), input = "specificity", ret = "se")
expect_is(obtained, "data.frame")
# With numeric x
obtained <- coords(smooth.s100b, c(0.2, 0.5, 0.6), input = "specificity")
expect_is(obtained, "data.frame")
expect_equal(dim(obtained), c(3, 2))
})
})
test_that("coords works with smooth.roc and x = numeric", {
smooth.s100b <- smooth(r.s100b)
expect <- structure(list(
specificity = c(0.5, 0.90000000000000002), sensitivity = c(
0.79774939210378937,
0.41207187155396763
), accuracy = c(0.60803296527659623, 0.72296413038683782), tn = c(36, 64.799999999999997), tp = c(
32.707725076255365,
16.894946733712672
), fn = c(8.2922749237446354, 24.105053266287328), fp = c(36, 7.2000000000000028), npv = c(
0.81278281736440605,
0.72886745600288694
), ppv = c(0.47604145006918286, 0.70118215742199363), fdr = c(0.52395854993081703, 0.29881784257800637), fpr = c(
0.5,
0.099999999999999978
), tpr = c(0.79774939210378937, 0.41207187155396763), tnr = c(0.5, 0.90000000000000002), fnr = c(
0.20225060789621063,
0.58792812844603237
), `1-specificity` = c(0.5, 0.099999999999999978), `1-sensitivity` = c(0.20225060789621063, 0.58792812844603237), `1-accuracy` = c(0.39196703472340377, 0.27703586961316218),
`1-npv` = c(0.18721718263559395, 0.27113254399711306), `1-ppv` = c(
0.52395854993081714,
0.29881784257800637
), precision = c(
0.47604145006918286,
0.70118215742199363
), recall = c(0.79774939210378937, 0.41207187155396763), lr_pos = c(1.5954987842075787, 4.1207187155396774), lr_neg = c(
0.40450121579242126,
0.65325347605114703
), youden = c(1.2977493921037895, 1.3120718715539677), closest.topleft = c(0.29090530839438672, 0.35565948421805432)
), class = "data.frame", row.names = c(NA, -2L))
reduced.cols <- c("specificity", "sensitivity", "youden")
obtained <- coords(smooth.s100b, c(0.5, 0.9), input = "sp", ret = "all")
expect_equal(obtained, expect)
obtained <- coords(smooth.s100b, c(0.5, 0.9), input = "spe", ret = reduced.cols)
expect_equal(obtained, expect[, reduced.cols])
obtained <- coords(smooth.s100b, 0.9, input = "specificity", ret = "all")
expect_equivalent(obtained, expect[2, , drop = FALSE])
obtained <- coords(smooth.s100b, 0.9, input = "specificity", ret = reduced.cols)
expect_equivalent(obtained, expect[2, reduced.cols])
obtained <- coords(smooth.s100b, 0.9, input = "specificity", ret = reduced.cols)
expect_equivalent(obtained, expect[2, reduced.cols, drop = FALSE])
})
test_that("coords works with smooth.roc and x = numeric and input = 'se'", {
smooth.s100b <- smooth(r.s100b)
expect <- structure(list(
specificity = c(0.84418934548477731, 0.29332202419872122), sensitivity = c(0.5, 0.90000000000000002), accuracy = c(
0.7193064856186191,
0.51344412161334452
), tn = c(60.781632874903963, 21.119185742307927), tp = c(20.5, 36.899999999999999), fn = c(20.5, 4.1000000000000014), fp = c(11.218367125096037, 50.880814257692073), npv = c(
0.74779049983468704,
0.83742536171095305
), ppv = c(0.64631322032274796, 0.42036520522212539), fdr = c(0.35368677967725209, 0.57963479477787461), fpr = c(
0.15581065451522269,
0.70667797580127878
), tpr = c(0.5, 0.90000000000000002), tnr = c(
0.84418934548477731,
0.29332202419872122
), fnr = c(0.5, 0.10000000000000003), `1-specificity` = c(
0.15581065451522269,
0.70667797580127878
), `1-sensitivity` = c(0.5, 0.099999999999999978), `1-accuracy` = c(0.2806935143813809, 0.48655587838665548),
`1-npv` = c(0.25220950016531296, 0.16257463828904695), `1-ppv` = c(
0.35368677967725204,
0.57963479477787461
), precision = c(
0.64631322032274796,
0.42036520522212539
), recall = c(0.5, 0.90000000000000002), lr_pos = c(3.2090231669693039, 1.2735645241802247), lr_neg = c(
0.59228418680512263,
0.34092223477992739
), youden = c(1.3441893454847773, 1.1933220241987212), closest.topleft = c(0.27427696006046209, 0.50939376148259274)
), class = "data.frame", row.names = c(NA, -2L))
reduced.cols <- c("specificity", "sensitivity", "youden")
obtained <- coords(smooth.s100b, c(0.5, 0.9), input = "se", ret = "all")
expect_equal(obtained, expect)
obtained <- coords(smooth.s100b, c(0.5, 0.9), input = "se", ret = reduced.cols)
expect_equal(obtained, expect[, reduced.cols])
obtained <- coords(smooth.s100b, 0.9, input = "se", ret = "all")
expect_equivalent(obtained, expect[2, , drop = FALSE])
obtained <- coords(smooth.s100b, 0.9, input = "se", ret = reduced.cols)
expect_equivalent(obtained, expect[2, reduced.cols, drop = FALSE])
})
test_that("coords with x = 'best' takes partial AUC into account", {
# with sp
obtained <- coords(r.s100b.partial1, "b", ret = "t")
expect_equal(obtained$threshold, 0.475)
# with se
obtained <- coords(r.s100b.partial2, "b", ret = "t")
expect_equal(obtained$threshold, 0.075)
})
test_that("coords with x = 'best' takes partial AUC into account with smooth.roc", {
# with sp
obtained <- coords(smooth(r.s100b.partial1), "b", ret = "sp")
expect_equal(obtained$specificity, 0.900608847772859)
obtained <- coords(smooth(r.s100b.partial1), "b", ret = c("se", "se", "youden"))
expect_equivalent(as.vector(obtained), c(0.410958904109589, 0.410958904109589, 1.311567751882448))
# with se
obtained <- coords(smooth(r.s100b.partial2), "b", ret = "se")
expect_equal(obtained$sensitivity, 0.900195694716243)
obtained <- coords(smooth(r.s100b.partial2), "b", ret = c("se", "se", "youden"))
expect_equivalent(as.vector(obtained), c(0.900195694716243, 0.900195694716243, 1.193053239288330))
})
test_that("coords with x = 'all' takes partial AUC into account", {
# with sp
obtained <- coords(r.s100b.partial1, "all", ret = c("t", "se", "sp"))
expect_equal(dim(obtained), c(9, 3))
expect_equivalent(obtained[1, ], c(NA, 0.3902439, 0.9))
expect_equivalent(obtained[9, ], c(NA, 0.292682926, 0.99))
# with se
obtained <- coords(r.s100b.partial2, "all", ret = c("t", "se", "sp"))
expect_equal(dim(obtained), c(7, 3))
expect_equivalent(obtained[1, ], c(NA, 0.99, 0.0))
expect_equivalent(obtained[7, ], c(NA, 0.9, 0.230555555555556))
})
test_that("coords with ignore.partial.auc = TRUE ignores partial AUC", {
# with sp
obtained <- coords(r.s100b.partial1, "all", ret = "t", ignore.partial.auc = TRUE)
expect_equal(dim(obtained), c(51, 1))
# with se
obtained <- coords(r.s100b.partial2, "all", ret = "t", ignore.partial.auc = TRUE)
expect_equal(dim(obtained), c(51, 1))
})
test_that("coords with x = 'all' takes partial AUC into account with smooth.roc", {
# with sp
obtained <- coords(smooth(r.s100b.partial1), "all", ret = "sp")
expect_equal(dim(obtained), c(141, 1))
expect_equal(min(obtained), 0.9)
expect_equal(max(obtained), 0.99)
# with se
obtained <- coords(smooth(r.s100b.partial2), "all", ret = "se")
expect_equal(dim(obtained), c(48, 1))
expect_equal(min(obtained), 0.9)
expect_equal(max(obtained), 0.99)
})
test_that("coords with ignore.partial.auc = TRUE ignores partial AUC of smooth.roc", {
# with sp
obtained <- coords(smooth(r.s100b.partial1), "all", ret = "sp", ignore.partial.auc = TRUE)
expect_equal(dim(obtained), c(514, 1))
# with se
obtained <- coords(smooth(r.s100b.partial2), "all", ret = "se", ignore.partial.auc = TRUE)
expect_equal(dim(obtained), c(514, 1))
})
test_that("coords with x = 'local maximas' takes partial AUC into account", {
# with sp
obtained <- coords(r.s100b.partial1, "local maximas", ret = "t")
expect_equal(obtained$threshold, c(0.435, 0.475, 0.485))
# with se
obtained <- coords(r.s100b.partial2, "local maximas", ret = "t")
expect_equal(obtained$threshold, c(0.065, 0.075))
})
test_that("invalid best.weights", {
expect_error(coords(r.s100b, "best", best.weights = 1))
expect_error(coords(r.s100b, "best", best.weights = 0:1))
expect_error(coords(r.s100b, "best", best.weights = c(0.1, 0.9)), NA)
expect_error(coords(r.s100b, "best", best.weights = 1:3))
# with smooth
expect_error(coords(smooth(r.s100b), "best", best.weights = 1))
expect_error(coords(smooth(r.s100b), "best", best.weights = 0:1))
expect_error(coords(smooth(r.s100b), "best", best.weights = c(0.1, 0.9)), NA)
expect_error(coords(smooth(r.s100b), "best", best.weights = 1:3))
})
test_that("invalid best.method", {
expect_error(coords(r.s100b, "best", best.method = 1))
expect_error(coords(r.s100b, "best", best.method = "1"))
# with smooth
expect_error(coords(smooth(r.s100b), "best", best.method = 1))
expect_error(coords(smooth(r.s100b), "best", best.method = "1"))
})
test_that("invalid se/sp", {
smooth.s100b <- smooth(r.s100b)
for (inp in c("sens", "spec")) {
for (r in list(r.s100b, smooth.s100b)) {
expect_error(coords(r, x = -2, input = inp))
expect_error(coords(r, x = 0, input = inp), NA)
expect_error(coords(r, x = 1, input = inp), NA)
expect_error(coords(r, x = 10, input = inp))
}
}
smooth.s100b.percent <- smooth(r.s100b.percent)
for (inp in c("sens", "spec")) {
for (r in list(r.s100b.percent, smooth.s100b.percent)) {
expect_error(coords(r.s100b.percent, x = -2, input = inp))
expect_error(coords(r.s100b.percent, x = 0, input = inp), NA)
expect_error(coords(r.s100b.percent, x = 10, input = inp), NA)
expect_error(coords(r.s100b.percent, x = 100, input = inp), NA)
expect_error(coords(r.s100b.percent, x = 101, input = inp))
}
}
})
test_that("invalid x", {
expect_error(coords(r.s100b.percent, x = list(1)))
expect_error(coords(r.s100b, x = aSAH))
expect_error(coords(smooth(r.s100b), x = mean))
# character but invalid
expect_error(coords(smooth(r.s100b), x = "c"))
expect_error(coords(r.s100b, x = "c"))
})
test_that("Infinite values work with both directions", {
# direction = >
Data <- structure(list(Outcome = c(1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L), Value = c(72L, 65L, 271L, 73L, 87L, 114L, 111L, 47L, 88L, 44L, 121L, 207L, 33L, 138L, 284L, 62L, 120L, 116L, 202L, 172L, 117L, 69L, 102L, 150L, 131L, 77L, 124L, 46L, 579L, 117L, 96L, 83L, 102L)), class = "data.frame", row.names = c(NA, -33L))
ROC <- roc(Outcome ~ Value, data = Data, ci = TRUE, direction = ">")
co <- coords(ROC, x = c(-Inf, Inf))
expect_equivalent(co, data.frame(threshold = c(-Inf, Inf), specificity = c(1, 0), sensitivity = c(0, 1)))
# direction = <
co <- coords(r.s100b, x = c(-Inf, Inf))
expect_equivalent(co, data.frame(threshold = c(-Inf, Inf), specificity = c(0, 1), sensitivity = c(1, 0)))
})
test_that("Coords pick the right end of 'flat' bits of the curve, according to direction", {
# expect_equal(r.s100b$sensitivities[2], 0.975609756097561) # tested elsewhere
expect_equivalent(
coords(r.s100b, 0.975609756097561, "se", "sp"),
0.13888888888888889 # and not 0
)
expect_equivalent(
coords(r.s100b, 1, "sp", "se"),
0.2926829268292683 # and not 0
)
})
pROC/tests/testthat/helper-expect_equal_roc.R 0000644 0001762 0000144 00000004153 15042617211 021003 0 ustar ligges users remove.calls.recursive <- function(x) {
if (is.null(x)) {
return(NULL)
}
attr(x, "roc") <- remove.calls.recursive(attr(x, "roc"))
attr(x, "auc") <- remove.calls.recursive(attr(x, "auc"))
attr(x, "ci") <- remove.calls.recursive(attr(x, "ci"))
if (!is.list(x)) {
return(x)
}
x$roc <- remove.calls.recursive(x$roc)
x$auc <- remove.calls.recursive(x$auc)
x$ci <- remove.calls.recursive(x$ci)
x$call <- NULL
return(x)
}
remove.fun.sesp.recursive <- function(x) {
if (is.null(x)) {
return(NULL)
}
attr(x, "roc") <- remove.fun.sesp.recursive(attr(x, "roc"))
attr(x, "auc") <- remove.fun.sesp.recursive(attr(x, "auc"))
attr(x, "ci") <- remove.fun.sesp.recursive(attr(x, "ci"))
if (!is.list(x)) {
return(x)
}
x$roc <- remove.fun.sesp.recursive(x$roc)
x$auc <- remove.fun.sesp.recursive(x$auc)
x$ci <- remove.fun.sesp.recursive(x$ci)
x$fun.sesp <- NULL
return(x)
}
remove.response.names.recursive <- function(x) {
if (is.null(x)) {
return(NULL)
}
attr(x, "roc") <- remove.response.names.recursive(attr(x, "roc"))
attr(x, "auc") <- remove.response.names.recursive(attr(x, "auc"))
attr(x, "ci") <- remove.response.names.recursive(attr(x, "ci"))
if (!is.list(x)) {
return(x)
}
x$roc <- remove.response.names.recursive(x$roc)
x$auc <- remove.response.names.recursive(x$auc)
x$ci <- remove.response.names.recursive(x$ci)
x$fun.sesp <- remove.response.names.recursive(x$fun.sesp)
names(x$response) <- NULL
names(x$original.response) <- NULL
x$response.name <- NULL
x$predictor.name <- NULL
return(x)
}
expect_equal_ignore_call <- function(x, y, ...) {
x <- remove.calls.recursive(x)
y <- remove.calls.recursive(y)
x <- remove.fun.sesp.recursive(x)
y <- remove.fun.sesp.recursive(y)
expect_equal(x, y, ...)
}
expect_equal_roc_formula <- function(x, y, ...) {
# roc.formula adds names to response and original.response
# this expectation ignores them, as well as the call
x <- remove.calls.recursive(x)
x <- remove.response.names.recursive(x)
y <- remove.calls.recursive(y)
y <- remove.response.names.recursive(y)
expect_equal(x, y, ...)
}
pROC/tests/testthat/test-multiclass.R 0000644 0001762 0000144 00000026453 15040443562 017354 0 ustar ligges users library(pROC)
data(aSAH)
context("multiclass-roc")
test_that("univariate multiclass roc/auc works", {
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b), "2")
expect_equal(class(uv.mr), "multiclass.roc")
expect_equal(length(uv.mr$rocs), 6)
expect_equal(as.numeric(auc(uv.mr)), 0.6539999352)
expect_false(uv.mr$percent)
expect_false(attributes(uv.mr$auc)$partial.auc)
expect_false(attributes(uv.mr$auc)$percent)
})
test_that("univariate multiclass roc works with formula", {
expect_warning(uv.mr <- multiclass.roc(gos6 ~ s100b, aSAH), "2")
expect_equal(as.numeric(auc(uv.mr)), 0.6539999352)
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6 ~ aSAH$s100b), "2")
expect_equal(as.numeric(auc(uv.mr)), 0.6539999352)
expect_warning(uv.mr <- multiclass.roc(gos6 ~ s100b, aSAH, subset = (gender == "Female")), "2")
expect_equal(length(uv.mr$response), sum(aSAH$gender == "Female"))
expect_error(multiclass.roc(gos6 ~ s100b, aSAH, weights = age))
})
test_that("univariate multiclass roc/auc works with percent=TRUE", {
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, percent = TRUE), "2")
uv.ma <- auc(uv.mr)
expect_equal(as.numeric(uv.ma), 65.39999352)
expect_equal(as.numeric(uv.mr$auc), 65.39999352)
expect_true(uv.mr$percent)
expect_true(attributes(uv.mr$auc)$percent)
expect_true(attributes(uv.ma)$percent)
expect_false(attributes(uv.mr$auc)$partial.auc)
expect_false(attributes(uv.ma)$partial.auc)
})
test_that("univariate multiclass roc/auc works with partial.auc", {
pauc.spec <- c(1, .9)
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, partial.auc = pauc.spec), "2")
uv.ma <- auc(uv.mr, partial.auc = pauc.spec)
expect_equal(as.numeric(uv.mr$auc), 0.0116176879)
expect_equal(as.numeric(uv.ma), 0.0116176879)
expect_equal(attributes(uv.mr$auc)$partial.auc, pauc.spec)
expect_equal(attributes(uv.ma)$partial.auc, pauc.spec)
# Calling AUC without partial.auc gives a full AUC, even if ROC was called with it
expect_equal(as.numeric(auc(uv.mr)), 0.6539999352)
# SE
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, partial.auc = pauc.spec, partial.auc.focus = "se"), "2")
uv.ma <- auc(uv.mr, partial.auc = pauc.spec, partial.auc.focus = "se")
expect_equal(as.numeric(uv.mr$auc), 0.02513286)
expect_equal(as.numeric(uv.ma), 0.02513286)
expect_equal(attributes(uv.mr$auc)$partial.auc.focus, "sensitivity")
expect_equal(attributes(uv.ma)$partial.auc.focus, "sensitivity")
})
test_that("univariate multiclass roc/auc works with directions", {
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, direction = "auto"), "2")
expect_equal(sapply(uv.mr$rocs, "[[", "direction"), c("<", ">", ">", ">", ">", ">"))
expect_equal(as.numeric(uv.mr$auc), 0.6539999352)
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, direction = "<"), "2")
expect_equal(sapply(uv.mr$rocs, "[[", "direction"), rep("<", 6))
expect_equal(as.numeric(uv.mr$auc), 0.3487473175)
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b, direction = ">"), "2")
expect_equal(sapply(uv.mr$rocs, "[[", "direction"), rep(">", 6))
expect_equal(as.numeric(uv.mr$auc), 0.6512526825)
})
test_that("univariate multiclass handles missing levels", {
expect_warning(multiclass.roc(aSAH$gos6, aSAH$s100b), "response level")
})
test_that("multivariate multiclass roc/auc works", {
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Perfect separation
preds <- lapply(n, function(x) runif(x, 0.8, 1))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.3)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0, 0.2)),
"X3" = c(runif(n[1] + n[2], 0, 0.5), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor)
expect_equal(class(mv.mr), "mv.multiclass.roc")
expect_equal(length(mv.mr$rocs), 3)
expect_equal(unname(sapply(mv.mr$rocs, length)), rep(2, 3))
expect_equal(as.numeric(auc(mv.mr)), 1)
# Imperfect separation
preds <- lapply(n, function(x) runif(x, 0.4, 0.6))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.7)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0.2, 0.8)),
"X3" = c(runif(n[1] + n[2], 0.3, 0.7), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor)
expect_equal(class(mv.mr), "mv.multiclass.roc")
expect_equal(as.numeric(auc(mv.mr)), 0.6480791667)
expect_false(mv.mr$percent)
expect_false(attributes(mv.mr$auc)$partial.auc)
expect_false(attributes(mv.mr$auc)$percent)
})
test_that("multivariate multiclass with formula works", {
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Imperfect separation
preds <- lapply(n, function(x) runif(x, 0.4, 0.6))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.7)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0.2, 0.8)),
"X3" = c(runif(n[1] + n[2], 0.3, 0.7), preds[[3]])
))
test_data <- cbind(as.data.frame(predictor), "response" = responses)
mv.mr <- multiclass.roc(responses, predictor)
mv.mr.f <- multiclass.roc(response ~ ., data = test_data)
expect_equal(as.numeric(auc(mv.mr.f)), as.numeric(auc(mv.mr)))
mv.mr.f <- multiclass.roc(response ~ X1 + X2 + X3, data = test_data)
expect_equal(as.numeric(auc(mv.mr)), as.numeric(auc(mv.mr)))
subset <- rbinom(sum(n), 1, .5) == 1
mv.mr.f <- multiclass.roc(response ~ X1 + X2 + X3, data = test_data, subset = subset)
expect_equal(length(mv.mr.f$response), sum(subset))
})
test_that("multivariate multiclass roc/auc works with percent=TRUE", {
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Perfect separation
preds <- lapply(n, function(x) runif(x, 0.8, 1))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.3)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0, 0.2)),
"X3" = c(runif(n[1] + n[2], 0, 0.5), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor, percent = TRUE)
expect_equal(as.numeric(auc(mv.mr)), 100)
# Imperfect separation
preds <- lapply(n, function(x) runif(x, 0.4, 0.6))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.7)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0.2, 0.8)),
"X3" = c(runif(n[1] + n[2], 0.3, 0.7), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor, percent = TRUE)
expect_equal(as.numeric(auc(mv.mr)), 64.80791667)
expect_true(mv.mr$percent)
expect_false(attributes(mv.mr$auc)$partial.auc)
expect_true(attributes(mv.mr$auc)$percent)
})
test_that("multivariate multiclass roc/auc works with partial.auc", {
pauc.spec <- c(1, .9)
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Perfect separation
preds <- lapply(n, function(x) runif(x, 0.8, 1))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.3)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0, 0.2)),
"X3" = c(runif(n[1] + n[2], 0, 0.5), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor, partial.auc = c(1, .9))
expect_equal(as.numeric(mv.mr$auc), .1)
expect_equal(as.numeric(auc(mv.mr)), 1)
expect_equal(as.numeric(auc(mv.mr, partial.auc = c(1, .9))), .1)
# Imperfect separation
preds <- lapply(n, function(x) runif(x, 0.4, 0.6))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.7)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0.2, 0.8)),
"X3" = c(runif(n[1] + n[2], 0.3, 0.7), preds[[3]])
))
mv.mr <- multiclass.roc(responses, predictor, partial.auc = c(1, .9))
expect_equal(as.numeric(mv.mr$auc), 0.0529250000)
expect_equal(as.numeric(auc(mv.mr)), 0.6480791667)
expect_equal(as.numeric(auc(mv.mr, partial.auc = c(1, .9))), 0.0529250000)
expect_false(mv.mr$percent)
expect_equal(attributes(mv.mr$auc)$partial.auc, pauc.spec)
expect_false(attributes(mv.mr$auc)$percent)
})
test_that("multivariate multiclass roc/auc works with direction", {
n <- c(100, 80, 150)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Perfect separation
preds <- lapply(n, function(x) runif(x, 0.8, 1))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.3)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0, 0.2)),
"X3" = c(runif(n[1] + n[2], 0, 0.5), preds[[3]])
))
expect_error(multiclass.roc(responses, predictor, direction = "auto"))
mr.mv.1 <- multiclass.roc(responses, predictor, direction = "<")
mr.mv.2 <- multiclass.roc(responses, predictor, direction = ">")
expect_equal(as.numeric(mr.mv.1$auc), 0)
expect_equal(as.numeric(mr.mv.2$auc), 1)
for (i in 1:3) {
for (j in 1:2) {
expect_equal(mr.mv.1$rocs[[i]][[j]]$direction, "<")
expect_equal(mr.mv.2$rocs[[i]][[j]]$direction, ">")
}
}
})
test_that("multivariate behavior with missing levels/columns", {
n <- c(10, 10, 10)
responses <- factor(c(rep("X1", n[1]), rep("X2", n[2]), rep("X3", n[3])))
# construct prediction matrix: one column per class
set.seed(42)
# Perfect separation
preds <- lapply(n, function(x) runif(x, 0.8, 1))
predictor <- as.matrix(data.frame(
"X1" = c(preds[[1]], runif(n[2] + n[3], 0, 0.3)),
"X2" = c(runif(n[1], 0.1, 0.4), preds[[2]], runif(n[3], 0, 0.2)),
"X3" = c(runif(n[1] + n[2], 0, 0.5), preds[[3]])
))
# Wrong number of predictor rows
expect_error(multiclass.roc(responses[1:20], predictor), "agree")
# Column in predictor not in response warns:
expect_warning(multiclass.roc(as.character(responses[1:20]), predictor[1:20, ]), "X3")
# Level with no obervation warns:
expect_warning(multiclass.roc(responses[1:20], predictor[1:20, 1:2]), "X3")
# Removed both level and column should be silent
expect_silent(multiclass.roc(as.character(responses[1:20]), predictor[1:20, 1:2]))
# Single column is an error
expect_error(multiclass.roc(responses, predictor[, 1, drop = F]))
# Wrong column names
pr2 <- predictor
colnames(pr2) <- c("Y1", "Y2", "Y3")
expect_error(multiclass.roc(responses, pr2))
colnames(pr2) <- c("Y1", "X2", "X3")
expect_warning(multiclass.roc(as.character(responses[11:30]), pr2[11:30, ]), "Y1")
})
test_that("Invalid CI functions fail cleanly", {
expect_warning(uv.mr <- multiclass.roc(aSAH$gos6, aSAH$s100b), "2")
expect_error(ci.se(uv.mr), "not available for multiclass ROC curves")
expect_error(ci.se(uv.mr$auc), "not available for multiclass ROC curves")
expect_error(ci.sp(uv.mr), "not available for multiclass ROC curves")
expect_error(ci.sp(uv.mr$auc), "not available for multiclass ROC curves")
expect_error(ci.coords(uv.mr), "not available for multiclass ROC curves")
expect_error(ci.coords(uv.mr$auc), "not available for multiclass ROC curves")
expect_error(ci.thresholds(uv.mr), "not available for multiclass ROC curves")
expect_error(ci.thresholds(uv.mr$auc), "not available for multiclass ROC curves")
})
pROC/tests/testthat/test-roc.R 0000644 0001762 0000144 00000044543 15040443562 015757 0 ustar ligges users library(pROC)
data(aSAH)
level.values <- list(
forward = c("Good", "Poor"),
reversed = c("Poor", "Good")
)
smooth.methods <- c("binormal", "density", "fitdistr", "logcondens", "logcondens.smooth")
for (marker in c("ndka", "wfns", "s100b")) {
for (levels.direction in names(level.values)) {
for (percent in c(FALSE, TRUE)) {
for (direction in c("auto", "<", ">")) {
context(sprintf("'roc' function works with percent = %s, marker = %s, levels.direction = %s, direction = %s", percent, marker, levels.direction, direction))
expected.direction <- ifelse(direction == "auto", ifelse(levels.direction == "forward", "<", ">"), direction)
r <- roc(aSAH$outcome, aSAH[[marker]], levels = level.values[[levels.direction]], direction = direction, percent = percent, quiet = TRUE)
test_that("roc.formula produces the same results as roc.default", {
rf <- roc(as.formula(sprintf("outcome ~ %s", marker)), data = aSAH, levels = level.values[[levels.direction]], direction = direction, percent = percent, quiet = TRUE)
expect_is(rf, "roc")
expect_equal(as.numeric(rf$auc), as.numeric(r$auc))
for (item in c("percent", "sensitivities", "specificities", "thresholds", "direction", "cases", "controls")) {
expect_identical(rf[[item]], r[[item]], label = sprintf("roc(outcome ~ %s, %s, %s, %s)[[\"%s\"]]", marker, levels.direction, percent, direction, item))
}
for (item in c("original.predictor", "original.response", "predictor", "response", "levels")) {
expect_identical(unname(rf[[item]]), unname(r[[item]]), label = sprintf("roc(outcome ~ %s, %s, %s, %s)[[\"%s\"]]", marker, levels.direction, percent, direction, item))
}
})
test_that("roc.default works with control/cases as well", {
rcs <- roc(controls = r$controls, cases = r$cases, levels = level.values[[levels.direction]], direction = direction, percent = percent, quiet = TRUE)
expect_is(rcs, "roc")
expect_equal(as.numeric(rcs$auc), as.numeric(r$auc))
for (item in c("percent", "sensitivities", "specificities", "thresholds", "direction", "cases", "controls")) {
expect_identical(rcs[[item]], r[[item]])
}
})
test_that("roc.default produces the expected results", {
expect_is(r, "roc")
expect_identical(r$percent, percent)
expect_identical(r$direction, expected.direction)
expect_identical(r$levels, level.values[[levels.direction]])
expect_equal(r$thresholds, expected.roc[[marker]][[levels.direction]][[expected.direction]][["thresholds"]])
expect_equal(r$sensitivities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["sensitivities"]] * ifelse(percent, 100, 1))
expect_equal(r$specificities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["specificities"]] * ifelse(percent, 100, 1))
})
if (marker == "wfns") {
available.smooth.methods <- "binormal"
} else {
available.smooth.methods <- smooth.methods
}
for (smooth.method in available.smooth.methods) {
context(sprintf("smooth(roc(...)) works with percent = %s, marker = %s, levels.direction = %s, direction = %s and smooth.method = %s", percent, marker, levels.direction, direction, smooth.method))
test_that("smoothing a ROC curve produces expected results", {
skip_slow()
skip_if(getRversion() < "4.4.0")
if (smooth.method == "logcondens" || smooth.method == "logcondens.smooth") {
testthat::skip_if_not_installed("logcondens")
}
s <- smooth(r, method = smooth.method, 10)
expect_is(s, "smooth.roc")
expect_identical(s$percent, percent)
expect_identical(s$direction, expected.direction)
expect_equal(s$sensitivities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["sensitivities"]] * ifelse(percent, 100, 1))
expect_equal(s$specificities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["specificities"]] * ifelse(percent, 100, 1))
})
test_that("building curve with smooth=TRUE produces expected results", {
skip_slow()
skip_if(getRversion() < "4.4.0")
context(sprintf("roc(..., smooth=TRUE) works with percent = %s, marker = %s, levels.direction = %s, direction = %s and smooth.method = %s", percent, marker, levels.direction, direction, smooth.method))
if (smooth.method == "logcondens" || smooth.method == "logcondens.smooth") {
testthat::skip_if_not_installed("logcondens")
}
s2 <- roc(aSAH$outcome, aSAH[[marker]],
levels = level.values[[levels.direction]], direction = direction, percent = percent, quiet = TRUE,
smooth = TRUE, smooth.n = 10, smooth.method = smooth.method
)
expect_is(s2, "smooth.roc")
expect_identical(s2$percent, percent)
expect_identical(s2$direction, expected.direction)
expect_equal(s2$sensitivities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["sensitivities"]] * ifelse(percent, 100, 1))
expect_equal(s2$specificities, expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["specificities"]] * ifelse(percent, 100, 1))
})
}
}
}
}
}
# dump("expected.roc", file="helper-roc-expected.R")
test_that("roc.default handles NAs", {
# Generate missing values
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
aSAH.missing$wfns[1:20] <- NA
# na.rm=FALSE works
# With NDKA
expect_true(is.na(roc(aSAH.missing$outcome, aSAH.missing$ndka, na.rm = FALSE)))
expect_false(is.na(auc(roc(aSAH.missing$outcome, aSAH.missing$ndka, na.rm = TRUE))))
# With WFNS
expect_true(is.na(roc(aSAH.missing$outcome, aSAH.missing$wfns, na.rm = FALSE)))
expect_false(is.na(auc(roc(aSAH.missing$outcome, aSAH.missing$wfns, na.rm = TRUE))))
# Same as subset
expect_identical(
as.numeric(auc(roc(aSAH.missing$outcome, aSAH.missing$ndka, na.rm = TRUE))),
as.numeric(auc(roc(aSAH[21:113, ]$outcome, aSAH.missing[21:113, ]$ndka)))
)
# With ordered
expect_identical(
as.numeric(auc(roc(aSAH.missing$outcome, aSAH.missing$wfns, na.rm = TRUE))),
as.numeric(auc(roc(aSAH[21:113, ]$outcome, aSAH.missing[21:113, ]$wfns)))
)
# Also with case/controls
expect_identical(
as.numeric(auc(roc(controls = aSAH.missing$ndka[aSAH.missing$outcome == "Good"], cases = aSAH.missing$ndka[aSAH.missing$outcome == "Poor"]))),
as.numeric(auc(roc(aSAH[21:113, ]$outcome, aSAH.missing[21:113, ]$ndka)))
)
# With ordered
expect_identical(
as.numeric(auc(roc(controls = aSAH.missing$wfns[aSAH.missing$outcome == "Good"], cases = aSAH.missing$wfns[aSAH.missing$outcome == "Poor"]))),
as.numeric(auc(roc(aSAH[21:113, ]$outcome, aSAH.missing[21:113, ]$wfns)))
)
})
test_that("roc.formula behaves", {
# By this point we've tested the main stuff, so just check a few basic elements
roc.check.only.items <- c("sensitivities", "specificities", "thresholds", "cases", "controls")
expect_identical(
roc(outcome ~ wfns, data = aSAH)[roc.check.only.items],
roc(aSAH$outcome, aSAH$wfns)[roc.check.only.items]
)
# formula without data
expect_identical(
roc(aSAH$outcome ~ aSAH$wfns)[roc.check.only.items],
roc(aSAH$outcome, aSAH$wfns)[roc.check.only.items]
)
# formula with data from parent env
outcome <- aSAH$outcome
wfns <- aSAH$wfns
expect_identical(
roc(outcome ~ wfns)[roc.check.only.items],
roc(outcome, wfns)[roc.check.only.items]
)
expect_identical(
roc(outcome ~ wfns, data = aSAH, subset = (gender == "Female"))[roc.check.only.items],
roc(aSAH$outcome[aSAH$gender == "Female"], aSAH$wfns[aSAH$gender == "Female"])[roc.check.only.items]
)
# Generate missing values
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
expect_warning(roc1 <- roc(outcome ~ ndka, data = aSAH.missing, na.action = na.omit), "na.omit")
roc2 <- roc(aSAH[21:113, ]$outcome, aSAH[21:113, ]$ndka)[roc.check.only.items]
expect_identical(
roc1[roc.check.only.items],
roc2[roc.check.only.items]
)
# na.fail should fail
expect_error(roc(outcome ~ ndka, data = aSAH.missing, na.action = na.fail))
# weights should fail too
expect_error(roc(outcome ~ ndka, data = aSAH, weights = seq_len(nrow(aSAH)), quiet = TRUE), regexp = "weights are not supported")
# invalid formula should fail
expect_error(roc(~ndka, data = aSAH))
# Both na.action and subset
expect_warning(roc1 <- roc(outcome ~ ndka, data = aSAH.missing, na.action = na.omit, subset = (gender == "Female")), "na.omit")
roc2 <- roc(aSAH[21:113, ]$outcome[aSAH[21:113, ]$gender == "Female"], aSAH[21:113, ]$ndka[aSAH[21:113, ]$gender == "Female"])
expect_identical(
roc1[roc.check.only.items],
roc2[roc.check.only.items]
)
})
test_that("roc can't take both response/predictor and case/control", {
expect_error(roc(aSAH$outcome, aSAH$ndka, controls = aSAH$ndka[aSAH$outcome == "Good"], cases = aSAH$ndka[aSAH$outcome == "Poor"]))
})
test_that("roc with multiple predictors returns expected ROC curves", {
roclist <- roc(outcome ~ wfns + ndka + s100b, data = aSAH, quiet = TRUE)
expect_is(roclist, "list")
expect_type(roclist, "list")
expect_length(roclist, 3)
expect_identical(names(roclist), c("wfns", "ndka", "s100b"))
expect_equal_roc_formula(roclist$wfns, r.wfns)
expect_equal_roc_formula(roclist$ndka, r.ndka)
expect_equal_roc_formula(roclist$s100b, r.s100b)
attach(aSAH)
roclist <- roc(outcome ~ wfns + ndka + s100b, quiet = TRUE)
expect_equal_roc_formula(roclist$wfns, r.wfns)
expect_equal_roc_formula(roclist$ndka, r.ndka)
expect_equal_roc_formula(roclist$s100b, r.s100b)
detach(aSAH)
})
test_that("extra arguments passed to roc with multiple predictors", {
roclist <- roc(outcome ~ wfns + ndka + s100b,
data = aSAH, quiet = TRUE,
percent = TRUE, partial.auc = c(90, 99)
)
expect_equal_roc_formula(roclist$wfns, r.wfns.percent.partial1)
expect_equal_roc_formula(roclist$ndka, r.ndka.percent.partial1)
expect_equal_roc_formula(roclist$s100b, r.s100b.percent.partial1)
})
test_that("roc works with densitites", {
range.ndka <- range(aSAH$ndka)
bw <- bw.nrd0(aSAH$ndka)
from <- min(aSAH$ndka) - (3 * bw)
to <- max(aSAH$ndka) + (3 * bw)
density.controls <- density(aSAH$ndka[aSAH$outcome == "Good"], from = from, to = to, bw = bw)
density.cases <- density(aSAH$ndka[aSAH$outcome == "Poor"], from = from, to = to, bw = bw)
density.roc <- roc(density.cases = density.cases$y, density.controls = density.controls$y)
smoothed.roc <- smooth(r.ndka, method = "density")
expect_is(density.roc, "smooth.roc")
expect_equal(density.roc$sensitivities, smoothed.roc$sensitivities)
expect_equal(density.roc$specificities, smoothed.roc$specificities)
expect_equal(as.numeric(density.roc$auc), as.numeric(smoothed.roc$auc))
})
test_that("roc.density works with extra arguments", {
skip_if(getRversion() < "4.4.0")
range.ndka <- range(aSAH$ndka)
bw <- bw.nrd0(aSAH$ndka)
from <- min(aSAH$ndka) - (3 * bw)
to <- max(aSAH$ndka) + (3 * bw)
density.controls <- density(aSAH$ndka[aSAH$outcome == "Good"], from = from, to = to, bw = bw)
density.cases <- density(aSAH$ndka[aSAH$outcome == "Poor"], from = from, to = to, bw = bw)
density.roc.partial <- roc(
density.cases = density.cases$y,
density.controls = density.controls$y,
partial.auc = c(1, .9), partial.auc.focus = "se",
partial.auc.correct = TRUE
)
expect_equal(as.numeric(density.roc.partial$auc), 0.506196226093)
density.roc.percent <- roc(
density.cases = density.cases$y,
density.controls = density.controls$y,
percent = TRUE
)
expect_equal(as.numeric(density.roc.percent$auc), 60.44728041)
})
test_that("roc doesn't accept density with other arguments", {
density.controls <- density(aSAH$ndka[aSAH$outcome == "Good"])
density.cases <- density(aSAH$ndka[aSAH$outcome == "Poor"])
expect_error(
roc(aSAH$outcome, aSAH$ndka, density.cases = density.controls, density.controls = density.cases),
"incompatible"
)
expect_error(
roc(cases = aSAH$ndka, controls = aSAH$ndka, density.cases = density.controls, density.controls = density.cases),
"incompatible"
)
})
test_that("roc.data.frame works", {
r <- roc(aSAH, outcome, s100b, ret = "roc")
expect_is(r, "roc")
co <- roc(aSAH, outcome, s100b, ret = "coords")
expect_equal(dim(co), c(51, 3))
co <- roc(aSAH, outcome, s100b, ret = "all_coords")
expect_equal(nrow(co), 51)
expect_true(nrow(co) >= 22)
})
test_that("roc.data.frame works with quoted names", {
r <- roc(aSAH, "outcome", "s100b", ret = "roc")
expect_is(r, "roc")
co <- roc(aSAH, "outcome", "s100b", ret = "coords")
expect_equal(dim(co), c(51, 3))
co <- roc(aSAH, "outcome", "s100b", ret = "all_coords")
expect_equal(nrow(co), 51)
expect_true(nrow(co) >= 22)
})
test_that("roc_ works", {
r <- roc_(aSAH, "outcome", "s100b", ret = "roc")
expect_is(r, "roc")
co <- roc_(aSAH, "outcome", "s100b", ret = "coords")
expect_equal(dim(co), c(51, 3))
co <- roc_(aSAH, "outcome", "s100b", ret = "all_coords")
expect_equal(nrow(co), 51)
expect_true(nrow(co) >= 22)
})
test_that("roc.data.frame reject invalid columns", {
outcomes <- aSAH$outcome
suppressWarnings(expect_error(roc(aSAH, outcomes, s100b), "Column")) # Warning about NSE
suppressWarnings(expect_error(roc(aSAH, "outcomes", "s100b"), "Column")) # Warning about NSE
expect_error(roc_(aSAH, "outcomes", "s100b"), "Column")
s100c <- aSAH$s100b
suppressWarnings(expect_error(roc(aSAH, outcome, s100c), "Column")) # Warning about NSE
suppressWarnings(expect_error(roc(aSAH, "outcome", "s100c"), "Column")) # Warning about NSE
expect_error(roc_(aSAH, "outcome", "s100c"), "Column")
})
test_that("roc reject and warns for invalid levels", {
expect_warning(expect_error(roc(aSAH$gos6, aSAH$s100b), "No case observation"), "levels")
expect_error(roc(aSAH$gos6, aSAH$s100b, levels = levels(aSAH$gos6)), "levels")
expect_warning(roc(factor(aSAH$gos6), aSAH$s100b, quiet = TRUE), "levels")
expect_warning(expect_error(roc(aSAH, gos6, s100b), "No case observation"), "levels")
expect_error(roc(aSAH, gos6, s100b, levels = levels(aSAH$gos6)), "levels")
dat <- aSAH
dat$gos6 <- factor(aSAH$gos6)
expect_warning(roc(dat, gos6, s100b, quiet = TRUE), "levels")
})
test_that("roc reject and warns for invalid predictors", {
expect_error(roc(aSAH$outcome, as.character(aSAH$wfns)), "Predictor")
expect_warning(roc(aSAH$outcome, as.matrix(aSAH$ndka)), "Deprecated")
expect_warning(roc(as.matrix(aSAH$outcome), aSAH$ndka), "Deprecated")
expect_error(roc(aSAH$outcome[1:100], aSAH$ndka), "length")
expect_error(roc(aSAH$outcome[1:100], aSAH$ndka[1:50]), "length")
})
test_that("roc reject requires cases & controls", {
expect_error(roc(aSAH$outcome[aSAH$outcome == "Good"], aSAH$ndka[aSAH$outcome == "Good"]), "case")
expect_error(roc(aSAH$outcome[aSAH$outcome == "Poor"], aSAH$ndka[aSAH$outcome == "Poor"]), "control")
expect_error(roc(aSAH[aSAH$outcome == "Good", ], outcome, ndka), "case")
expect_error(roc(aSAH[aSAH$outcome == "Poor", ], outcome, ndka), "control")
})
test_that("roc works with ordered predictor", {
wfns2 <- ordered(as.numeric(aSAH$wfns) + 2)
r <- roc(aSAH$outcome, wfns2)
expect_equal(r$thresholds, c(-Inf, 3.5, 4.5, 5.5, 6.5, Inf))
levels(wfns2) <- letters[1:5]
# TODO: this behavior should be fixed, see issue #63.
# For now ensure basic behavior with warning is at least consistent.
expect_warning(r <- roc(aSAH$outcome, wfns2))
expect_equal(r$thresholds, c(-Inf, 1.5, 2.5, 3.5, 4.5, Inf))
# In reality we want to say something like c(-Inf, "a", "b", "c", "d", "e", Inf)
})
test_that("roc works with spaces in formula", {
test_dat <- aSAH[c("outcome", "wfns", "age", "ndka")]
colnames(test_dat)[3] <- "A ge"
# All data
r <- roc(outcome ~ ., data = test_dat, quiet = TRUE)
expect_equal(length(r), 3)
expect_equal(names(r), c("wfns", "A ge", "ndka"))
expect_equal(r$`A ge`$predictor, aSAH$age)
# One column
r <- roc(outcome ~ `A ge`, data = test_dat, quiet = TRUE)
expect_equal(r$predictor, aSAH$age)
# Two columns
r <- roc(outcome ~ `A ge` + ndka, data = test_dat, quiet = TRUE)
expect_equal(names(r), c("A ge", "ndka"))
expect_equal(r$`A ge`$predictor, aSAH$age)
# Two columns, different order
r <- roc(outcome ~ ndka + `A ge`, data = test_dat, quiet = TRUE)
expect_equal(names(r), c("ndka", "A ge"))
expect_equal(r$`A ge`$predictor, aSAH$age)
})
test_that("roc works with `with` and formula", {
# This is the correct way to do things... with on the formula
formW <- with(aSAH, as.formula("outcome ~ wfns"))
roc(formW)
# This must fail gracefully
form <- as.formula("outcome ~ wfns")
expect_error(roc(form), "outcome")
# Now this can work with #111
with(aSAH, roc(form))
# Wrapping functions can mess things up...
wrap_roc <- function(formula) {
roc(formula)
}
with(aSAH, wrap_roc(form))
wrap_roc2 <- function(formula) {
with(aSAH, roc(formula))
}
wrap_roc2(form)
})
# The code below can be used to refresh the "expected.roc" data, just in case...
# expected.roc <- list()
# for (marker in c("ndka", "wfns", "s100b")) {
# expected.roc[[marker]] <- list()
# for (levels.direction in names(level.values)) {
# expected.roc[[marker]][[levels.direction]] <- list()
# for (direction in c("<", ">")) {
# r <- roc(aSAH$outcome, aSAH[[marker]], levels = level.values[[levels.direction]], direction = direction, percent = FALSE, quiet = TRUE)
# if (!isTRUE(percent) && direction != "auto") {
# expected.roc[[marker]][[levels.direction]][[direction]] <- r[c("sensitivities", "specificities", "thresholds")]
# expected.roc[[marker]][[levels.direction]][[direction]][["auc"]] <- as.numeric(r$auc)
# }
# for (smooth.method in available.smooth.methods) {
# s <- smooth(r, method=smooth.method, 10)
# expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["sensitivities"]] <- s$sensitivities
# expected.roc[[marker]][[levels.direction]][[expected.direction]][["smooth"]][[smooth.method]][["specificities"]] <- s$specificities
# }
# }
# }
# }
# save("expected.roc", system.file("extdata", "test-roc-expected.R", package="pROC"), file = "dump_roc_expected.R")
pROC/tests/testthat/test-auc.R 0000644 0001762 0000144 00000031362 15040443562 015737 0 ustar ligges users library(pROC)
data(aSAH)
context("auc")
test_that("full auc works", {
expect_equal(as.numeric(auc(r.wfns)), 0.823678861788618)
expect_equal(as.numeric(auc(r.wfns.percent)), 82.3678861788618)
expect_equal(as.numeric(auc(r.ndka)), 0.611957994579946)
expect_equal(as.numeric(auc(r.ndka.percent)), 61.1957994579946)
})
test_that("partial auc works on arbitrary intervals", {
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, .9))), 0.0334417344173442)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 90))), 3.34417344173442)
# direction is unspecified
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, 1))), 0.0334417344173442)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 100))), 3.34417344173442)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, .8))), 0.0598373983739837)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 80))), 5.98373983739837)
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.5, 0))), 0.488134475939354)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(50, 0))), 48.8134475939354)
# NDKA
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, .9))), 0.0107046070460705)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 90))), 1.07046070460705)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, 1))), 0.0107046070460705)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 100))), 1.07046070460705)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, .8))), 0.0277777777777778)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 80))), 2.77777777777778)
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.5, 0))), 0.416836043360434)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(50, 0))), 41.6836043360434)
# Full interval == full auc
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, 0))), 0.823678861788618)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 0))), 82.3678861788618)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, 0))), 0.611957994579946)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 0))), 61.1957994579946)
})
test_that("partial auc works with focus on SE", {
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, .9), partial.auc.focus = "se")), 0.0400999322493225)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 90), partial.auc.focus = "se")), 4.00999322493225)
# direction is unspecified
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, 1), partial.auc.focus = "se")), 0.0400999322493225)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 100), partial.auc.focus = "se")), 4.00999322493225)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, .8), partial.auc.focus = "se")), 0.0609953703703703)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 80), partial.auc.focus = "se")), 6.09953703703703)
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.5, 0), partial.auc.focus = "se")), 0.483358739837398)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(50, 0), partial.auc.focus = "se")), 48.3358739837398)
# NDKA
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, .9), partial.auc.focus = "se")), 0.0037940379403794)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 90), partial.auc.focus = "se")), 0.37940379403794)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, 1), partial.auc.focus = "se")), 0.0037940379403794)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 100), partial.auc.focus = "se")), 0.37940379403794)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, .8), partial.auc.focus = "se")), 0.0242547425474255)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 80), partial.auc.focus = "se")), 2.42547425474255)
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.5, 0), partial.auc.focus = "se")), 0.428523035230352)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(50, 0), partial.auc.focus = "se")), 42.8523035230352)
# Full interval == full auc
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, 0), partial.auc.focus = "se")), 0.823678861788618)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 0), partial.auc.focus = "se")), 82.3678861788618)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, 0), partial.auc.focus = "se")), 0.611957994579946)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 0), partial.auc.focus = "se")), 61.1957994579946)
})
test_that("partial auc works with correction enabled", {
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, .9), partial.auc.correct = TRUE)), 0.649693339038653)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 90), partial.auc.correct = TRUE)), 64.9693339038653)
# direction is unspecified
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, 1), partial.auc.correct = TRUE)), 0.649693339038653)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 100), partial.auc.correct = TRUE)), 64.9693339038653)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, .8), partial.auc.correct = TRUE)), 0.763749402199904)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 80), partial.auc.correct = TRUE)), 76.3749402199904)
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.5, 0), partial.auc.correct = TRUE)), 0.952537903757416)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(50, 0), partial.auc.correct = TRUE)), 95.2537903757416)
# NDKA
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, .9), partial.auc.correct = TRUE)), 0.530024247610897)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 90), partial.auc.correct = TRUE)), 53.0024247610897)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, 1), partial.auc.correct = TRUE)), 0.530024247610897)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 100), partial.auc.correct = TRUE)), 53.0024247610897)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, .8), partial.auc.correct = TRUE)), 0.575163398692811)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 80), partial.auc.correct = TRUE)), 57.5163398692811)
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.5, 0), partial.auc.correct = TRUE)), 0.667344173441734)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(50, 0), partial.auc.correct = TRUE)), 66.7344173441734)
# Full interval == full auc
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, 0), partial.auc.correct = TRUE)), 0.823678861788618)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 0), partial.auc.correct = TRUE)), 82.3678861788618)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, 0), partial.auc.correct = TRUE)), 0.611957994579946)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 0), partial.auc.correct = TRUE)), 61.1957994579946)
})
test_that("partial auc works with focus on SE and correction enabled", {
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, .9), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.68473648552275)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 90), partial.auc.focus = "se", partial.auc.correct = TRUE)), 68.473648552275)
# direction is unspecified
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, 1), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.68473648552275)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 100), partial.auc.focus = "se", partial.auc.correct = TRUE)), 68.473648552275)
# Arbitrary intervals
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.9, .8), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.770561002178649)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(90, 80), partial.auc.focus = "se", partial.auc.correct = TRUE)), 77.0561002178649)
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(.5, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.933434959349593)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(50, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 93.3434959349593)
# NDKA
expect_warning(auc(r.ndka, partial.auc = c(1, .9), partial.auc.focus = "se", partial.auc.correct = TRUE))
expect_warning(auc(r.ndka.percent, partial.auc = c(100, 90), partial.auc.focus = "se", partial.auc.correct = TRUE))
expect_warning(expect_identical(as.numeric(auc(r.ndka, partial.auc = c(1, .9), partial.auc.focus = "se", partial.auc.correct = TRUE)), NA_real_))
expect_warning(expect_identical(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 90), partial.auc.focus = "se", partial.auc.correct = TRUE)), NA_real_))
# direction is unspecified
expect_warning(auc(r.ndka, partial.auc = c(.9, 1), partial.auc.focus = "se", partial.auc.correct = TRUE))
expect_warning(auc(r.ndka.percent, partial.auc = c(90, 100), partial.auc.focus = "se", partial.auc.correct = TRUE))
expect_warning(expect_identical(as.numeric(auc(r.ndka, partial.auc = c(.9, 1), partial.auc.focus = "se", partial.auc.correct = TRUE)), NA_real_))
expect_warning(expect_identical(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 100), partial.auc.focus = "se", partial.auc.correct = TRUE)), NA_real_))
# Arbitrary intervals
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.9, .8), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.554439662043679)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(90, 80), partial.auc.focus = "se", partial.auc.correct = TRUE)), 55.4439662043679)
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(.5, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.714092140921409)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(50, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 71.4092140921409)
# Full interval == full auc
expect_equal(as.numeric(auc(r.wfns, partial.auc = c(1, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.823678861788618)
expect_equal(as.numeric(auc(r.wfns.percent, partial.auc = c(100, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 82.3678861788618)
# direction is unspecified
expect_equal(as.numeric(auc(r.ndka, partial.auc = c(1, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 0.611957994579946)
expect_equal(as.numeric(auc(r.ndka.percent, partial.auc = c(100, 0), partial.auc.focus = "se", partial.auc.correct = TRUE)), 61.1957994579946)
})
test_that("auc can create a roc curve", {
expect_equal(as.numeric(auc(aSAH$outcome, aSAH$wfns)), as.numeric(auc(r.wfns)))
expect_equal(as.numeric(auc(aSAH$outcome, aSAH$ndka)), as.numeric(auc(r.ndka)))
# With formula
expect_equal(as.numeric(auc(outcome ~ wfns, aSAH)), as.numeric(auc(r.wfns)))
expect_equal(as.numeric(auc(outcome ~ ndka, aSAH)), as.numeric(auc(r.ndka)))
})
test_that("auc can create a roc curve with percent", {
expect_equal(as.numeric(auc(aSAH$outcome, aSAH$wfns, percent = TRUE)), as.numeric(auc(r.wfns.percent)))
expect_equal(as.numeric(auc(aSAH$outcome, aSAH$ndka, percent = TRUE)), as.numeric(auc(r.ndka.percent)))
# With formula
expect_equal(as.numeric(auc(outcome ~ wfns, aSAH, percent = TRUE)), as.numeric(auc(r.wfns.percent)))
expect_equal(as.numeric(auc(outcome ~ ndka, aSAH, percent = TRUE)), as.numeric(auc(r.ndka.percent)))
})
test_that("auc.formula behaves", {
expect_equal(
as.numeric(auc(outcome ~ wfns, data = aSAH)),
as.numeric(auc(aSAH$outcome, aSAH$wfns))
)
expect_equal(
as.numeric(auc(outcome ~ wfns, data = aSAH, subset = (gender == "Female"))),
as.numeric(auc(aSAH$outcome[aSAH$gender == "Female"], aSAH$wfns[aSAH$gender == "Female"]))
)
# Generate missing values
aSAH.missing <- aSAH
aSAH.missing$ndka[1:20] <- NA
expect_warning(auc1 <- auc(outcome ~ ndka, data = aSAH.missing, na.action = na.omit), "na.omit")
auc2 <- auc(aSAH[21:113, ]$outcome, aSAH[21:113, ]$ndka)
expect_equal(as.numeric(auc1), as.numeric(auc2))
# na.fail should fail
expect_error(auc(outcome ~ ndka, data = aSAH.missing, na.action = na.fail))
# weights should fail too
expect_error(auc(outcome ~ ndka, data = aSAH, weights = seq_len(nrow(aSAH))), regexp = "weights are not supported")
# Both na.action and subset
expect_warning(auc1 <- auc(outcome ~ ndka, data = aSAH.missing, na.action = na.omit, subset = (gender == "Female")), "na.omit")
auc2 <- auc(aSAH[21:113, ]$outcome[aSAH[21:113, ]$gender == "Female"], aSAH[21:113, ]$ndka[aSAH[21:113, ]$gender == "Female"])
expect_equal(as.numeric(auc1), as.numeric(auc2))
})
pROC/tests/testthat/test-ci.se.R 0000644 0001762 0000144 00000002671 15040443562 016171 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.se")
# Only test whether ci.se runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
for (stratified in c(TRUE, FALSE)) {
for (test.roc in list(r.s100b, smooth(r.s100b))) {
test_that("ci.se with default specificities", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.se(test.roc,
boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expect_is(obtained, "ci.se")
expect_is(obtained, "ci")
expect_equal(dim(obtained), c(11, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
test_that("ci.se accepts one specificity", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.se(test.roc,
specificities = 0.9, boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expect_is(obtained, "ci.se")
expect_is(obtained, "ci")
expect_equal(dim(obtained), c(1, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
}
}
pROC/tests/testthat/test-var.R 0000644 0001762 0000144 00000003346 15040443562 015760 0 ustar ligges users library(pROC)
data(aSAH)
test_that("var with delong works", {
expect_equal(var(r.wfns), 0.00146991470882363)
expect_equal(var(r.ndka), 0.0031908105493913)
expect_equal(var(r.s100b), 0.00266868245717244)
})
test_that("var works with auc", {
expect_equal(var(auc(r.wfns)), 0.00146991470882363)
expect_equal(var(auc(r.ndka)), 0.0031908105493913)
expect_equal(var(auc(r.s100b)), 0.00266868245717244)
})
test_that("var with delong and percent works", {
expect_equal(var(r.wfns.percent), 14.6991470882363)
expect_equal(var(r.ndka.percent), 31.908105493913)
expect_equal(var(r.s100b.percent), 26.6868245717244)
})
test_that("var works with auc and percent", {
expect_equal(var(auc(r.wfns.percent)), 14.6991470882363)
expect_equal(var(auc(r.ndka.percent)), 31.908105493913)
expect_equal(var(auc(r.s100b.percent)), 26.6868245717244)
})
test_that("var with delong and percent works", {
expect_equal(var(roc(aSAH$outcome, -aSAH$ndka, percent = TRUE)), 31.908105493913)
expect_equal(var(roc(aSAH$outcome, -aSAH$s100b, percent = TRUE)), 26.6868245717244)
})
# Only test whether var runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
test_that("bootstrap var runs with roc, auc and smooth.roc objects", {
skip_slow()
for (roc1 in list(r.s100b, auc(r.s100b), smooth(r.s100b), r.s100b.partial1, r.s100b.partial1$auc)) {
n <- round(runif(1, 3, 9)) # keep boot.n small
for (stratified in c(TRUE, FALSE)) {
stratified <- sample(c(TRUE, FALSE), 1)
obtained <- var(roc1,
method = "bootstrap",
boot.n = n, boot.stratified = stratified
)
expect_is(obtained, "numeric")
expect_false(is.na(obtained))
}
}
})
pROC/tests/testthat/test-roc.utils.R 0000644 0001762 0000144 00000006053 15040443562 017110 0 ustar ligges users library(pROC)
data(aSAH)
context("roc.utils")
test_that("roc_utils_thr_idx finds correc thresholds with direction=<", {
obtained <- pROC:::roc_utils_thr_idx(r.s100b, c(-Inf, 0.205, 0.055, Inf))
expect_equal(obtained, c(1, 18, 4, 51))
})
test_that("roc_utils_thr_idx finds correc thresholds with direction=>", {
obtained <- pROC:::roc_utils_thr_idx(r.s100b, c(Inf, -Inf, 0.05, 0.055, 0.52, 0.205))
expect_equal(obtained, c(51, 1, 3, 4, 40, 18))
})
test_that("roc_utils_calc_coords works", {
obtained <- pROC:::roc_utils_calc_coords(r.s100b, -1:-4, c(1, .5, .1, 0), c(0, .5, .9, 1), c(12, .9))
expect_equal(obtained, expected_roc_utils_calc_coords)
})
test_that("roc_utils_calc_coords works with percent", {
obtained <- pROC:::roc_utils_calc_coords(r.s100b.percent, -1:-4, c(100, 50, 10, 0), c(0, 50, 90, 100), c(12, .9))
expect_equal(obtained, expected_roc_utils_calc_coords.percent)
})
test_that("roc_utils_match_coords_input_args works", {
expect_equal(pROC:::roc_utils_match_coords_input_args("t"), "threshold")
expect_equal(pROC:::roc_utils_match_coords_input_args("threshold"), "threshold")
expect_equal(pROC:::roc_utils_match_coords_input_args("fp"), "fp")
expect_equal(pROC:::roc_utils_match_coords_input_args("1-se"), "1-sensitivity")
for (coord in names(which(pROC:::coord.is.monotone))) {
expect_equal(pROC:::roc_utils_match_coords_input_args(coord), coord)
}
# Errors
# t with threshold=False
expect_error(pROC:::roc_utils_match_coords_input_args("t", threshold = FALSE))
# all only for ret
expect_error(pROC:::roc_utils_match_coords_input_args("all"))
# Only one allowed
expect_error(pROC:::roc_utils_match_coords_input_args(c("specificity", "sensitivity")))
# Invalid arg
expect_error(pROC:::roc_utils_match_coords_input_args("blah"))
# Not monotone
expect_error(pROC:::roc_utils_match_coords_input_args("npe"))
expect_error(pROC:::roc_utils_match_coords_input_args("accuracy"))
})
test_that("roc_utils_match_coords_ret_args works", {
expect_equal(pROC:::roc_utils_match_coords_ret_args("t"), "threshold")
expect_equal(pROC:::roc_utils_match_coords_ret_args("threshold"), "threshold")
expect_equal(pROC:::roc_utils_match_coords_ret_args("fp"), "fp")
expect_equal(pROC:::roc_utils_match_coords_ret_args("1-se"), "1-sensitivity")
expect_equal(pROC:::roc_utils_match_coords_ret_args("npe"), "1-npv")
for (coord in pROC:::roc.utils.valid.coords) {
expect_equal(pROC:::roc_utils_match_coords_ret_args(coord), coord)
}
expect_equal(pROC:::roc_utils_match_coords_ret_args(pROC:::roc.utils.valid.coords), pROC:::roc.utils.valid.coords)
# Errors
# t with threshold=False
expect_error(pROC:::roc_utils_match_coords_ret_args("t", threshold = FALSE))
# Invalid arg
expect_error(pROC:::roc_utils_match_coords_ret_args("blah"))
# The following should be invalid but somehow it seems valid to say:
# match.arg(c("sensitivity", "blah"), "sensitivity", TRUE)
# and the extra 'blah' arg is ignored by match.arg.
# Ignoring for now
# expect_error(pROC:::roc_utils_match_coords_ret_args(c("sensitivity", "blah")))
})
pROC/tests/testthat/test-deLongPlacementsCpp.R 0000644 0001762 0000144 00000003205 15040443562 021051 0 ustar ligges users library(pROC)
data(aSAH)
context("DeLong Placements C++ code works")
for (percent in c(FALSE, TRUE)) {
for (marker in c("ndka", "wfns", "s100b")) {
desc <- sprintf("delongPlacementsCpp runs with %s (percent = %s)", marker, percent)
r <- roc(aSAH$outcome, aSAH[[marker]], percent = percent)
test_that(desc, {
placements <- pROC:::delongPlacementsCpp(r)
expect_equal(placements, expected.placements[[marker]][["forward"]])
})
}
for (marker in c("ndka", "wfns", "s100b")) {
desc <- sprintf("delongPlacementsCpp runs with reversed levels and %s (percent = %s)", marker, percent)
r <- roc(aSAH$outcome, aSAH[[marker]], levels = c("Poor", "Good"), percent = percent)
test_that(desc, {
placements <- pROC:::delongPlacementsCpp(r)
expect_identical(names(placements), c("theta", "X", "Y"))
})
}
for (marker in c("ndka", "wfns", "s100b")) {
desc <- sprintf("delongPlacementsCpp runs with reversed direction and %s (percent = %s)", marker, percent)
r <- roc(aSAH$outcome, aSAH[[marker]], direction = ">", percent = percent)
test_that(desc, {
placements <- pROC:::delongPlacementsCpp(r)
expect_identical(names(placements), c("theta", "X", "Y"))
})
}
for (marker in c("ndka", "wfns", "s100b")) {
desc <- sprintf("delongPlacementsCpp runs with reversed levels reversed direction and %s (percent = %s)", marker, percent)
r <- roc(aSAH$outcome, aSAH[[marker]], levels = c("Poor", "Good"), direction = ">", percent = percent)
test_that(desc, {
placements <- pROC:::delongPlacementsCpp(r)
expect_identical(names(placements), c("theta", "X", "Y"))
})
}
}
pROC/tests/testthat/test-numeric-accuracy.R 0000644 0001762 0000144 00000012346 15040443562 020422 0 ustar ligges users library(pROC)
data(aSAH)
numacc.response <- c(2, 1, 1, 2, 2, 1, 2, 2, 1, 1, 1, 2, 1, 2, 2, 2, 2, 2)
numacc.predictor <- c(
0.960602681556147, 0.0794407386056549, 0.144842404246611,
0.931816485855784, 0.931816485855784, 0.97764041048215, 0.653549466997938699464,
0.796401132206396, 0.427720540184519, 0.811278021288732, 0.0188323116581187,
0.653549466997938588442, 0.653549466997938477419, 0.959111701445925, 0.931816485855784,
0.663663279418747, 0.800100838413179, 0.780456095511079
)
expected.auc <- 0x1.8ef606a63bd82p-1
# Predictor has near-ties that can break numerical comparisons
test_that("AUC is consistent with numerical near-ties", {
r2 <- roc(numacc.response, numacc.predictor, algorithm = 2)
expect_equal(expected.auc, as.numeric(auc(r2)))
})
test_that("AUC is consistent with numerical near-ties and direction = >", {
r2 <- roc(2 - numacc.response, numacc.predictor, algorithm = 2)
expect_equal(expected.auc, as.numeric(auc(r2)))
})
test_that("delong theta is consistent with auc", {
r2 <- roc(numacc.response, numacc.predictor, algorithm = 2)
expect_equal(pROC:::delongPlacements(r2)$theta, as.numeric(auc(r2)))
})
test_that("delong theta is consistent with auc and direction = >", {
r2 <- roc(2 - numacc.response, numacc.predictor, algorithm = 2)
expect_equal(pROC:::delongPlacements(r2)$theta, as.numeric(auc(r2)))
})
# Test some crazy values
# Multiple sequencial near-tie that will break the thresholding algorithm at the limits close to +-Inf or 0
# Compare that with an "easy" curve with values with well defined intermediate averages
test_that("Hard predictor has same results as easy one", {
numacc.predictor.hard <- c(
-0x1.fffffffffffffp+1023, -0x1.ffffffffffffep+1023, -0x1.ffffffffffffdp+1023, # Close to -Inf
-0x1.249ad2594c37fp+332, -0x1.249ad2594c37ep+332, -0x1.249ad2594c37dp+332, -0x1.249ad2594c37cp+332, -0x1.249ad2594c37bp+332, -0x1.249ad2594c37ap+332, # Close to -1e100
-0x0.0000000000003p-1022, -0x0.0000000000002p-1022, -0x0.0000000000001p-1022, -0x0p+0, # Close to -0
0x0p+0, 0x0.0000000000001p-1022, 0x0.0000000000002p-1022, 0x0.0000000000003p-1022, # Close to +0
0x1.249ad2594c37ap+332, 0x1.249ad2594c37bp+332, 0x1.249ad2594c37cp+332, 0x1.249ad2594c37dp+332, 0x1.249ad2594c37ep+332, 0x1.249ad2594c37fp+332, # Close to +1e100
0x1.ffffffffffffdp+1023, 0x1.ffffffffffffep+1023, 0x1.fffffffffffffp+1023
) # Close to +Inf
numacc.predictor.easy <- c(
-103, -102, -101,
-10, -9, -8, -7, -6, -5,
-0.1, -0.01, -0.001, 0,
0, 0.001, 0.01, 0.1,
5, 6, 7, 8, 9, 10,
101, 102, 103
)
response <- rbinom(length(numacc.predictor.easy), 1, 0.5)
roc.hard <- roc(response, numacc.predictor.hard, direction = "<")
roc.easy <- roc(response, numacc.predictor.easy, direction = "<")
expect_equal(roc.hard$sensitivities, roc.easy$sensitivities, info = paste("Random response: ", paste(response, collapse = ",")))
expect_equal(roc.hard$specificities, roc.easy$specificities, info = paste("Random response: ", paste(response, collapse = ",")))
expect_equal(roc.hard$direction, roc.easy$direction, info = paste("Random response: ", paste(response, collapse = ",")))
})
test_that("Hard predictor has same results as easy one, random sampling", {
skip_slow()
numacc.predictor.hard <- c(
-0x1.fffffffffffffp+1023, -0x1.ffffffffffffep+1023, -0x1.ffffffffffffdp+1023, # Close to -Inf
-0x1.249ad2594c37fp+332, -0x1.249ad2594c37ep+332, -0x1.249ad2594c37dp+332, -0x1.249ad2594c37cp+332, -0x1.249ad2594c37bp+332, -0x1.249ad2594c37ap+332, # Close to -1e100
-0x0.0000000000003p-1022, -0x0.0000000000002p-1022, -0x0.0000000000001p-1022, -0x0p+0, # Close to -0
0x0p+0, 0x0.0000000000001p-1022, 0x0.0000000000002p-1022, 0x0.0000000000003p-1022, # Close to +0
0x1.249ad2594c37ap+332, 0x1.249ad2594c37bp+332, 0x1.249ad2594c37cp+332, 0x1.249ad2594c37dp+332, 0x1.249ad2594c37ep+332, 0x1.249ad2594c37fp+332, # Close to +1e100
0x1.ffffffffffffdp+1023, 0x1.ffffffffffffep+1023, 0x1.fffffffffffffp+1023
) # Close to +Inf
numacc.predictor.easy <- c(
-103, -102, -101,
-10, -9, -8, -7, -6, -5,
-0.1, -0.01, -0.001, 0,
0, 0.001, 0.01, 0.1,
5, 6, 7, 8, 9, 10,
101, 102, 103
)
a <- replicate(100, {
response <- rbinom(length(numacc.predictor.easy), 1, 0.5)
sample.vector <- sample(length(numacc.predictor.easy), replace = as.logical(rbinom(1, 1, 0.5)))
expect_message(roc.hard <- roc(response, numacc.predictor.hard[sample.vector], direction = "<"))
expect_message(roc.easy <- roc(response, numacc.predictor.easy[sample.vector], direction = "<"))
expect_equal(roc.hard$sensitivities, roc.easy$sensitivities,
info =
c(
paste("Random response: ", paste(response, collapse = ",")),
paste("Random sample:", paste(sample.vector, collapse = ","))
)
)
expect_equal(roc.hard$specificities, roc.easy$specificities,
info =
c(
paste("Random response: ", paste(response, collapse = ",")),
paste("Random sample:", paste(sample.vector, collapse = ","))
)
)
expect_equal(roc.hard$direction, roc.easy$direction,
info =
c(
paste("Random response: ", paste(response, collapse = ",")),
paste("Random sample:", paste(sample.vector, collapse = ","))
)
)
})
})
pROC/tests/testthat/helper-deLongPlacementsCpp-expected.R 0000644 0001762 0000144 00000033464 15040443562 023162 0 ustar ligges users expected.placements <- list(
"ndka" = list(
"forward" = structure(list(theta = 0.611957994579946, X = c(
0.805555555555556,
0.625, 0.680555555555556, 0.763888888888889, 0.0416666666666667,
0.277777777777778, 0.513888888888889, 0.930555555555556, 0.972222222222222,
0.930555555555556, 0.930555555555556, 0.402777777777778, 0.722222222222222,
0.861111111111111, 0.166666666666667, 0.25, 0.708333333333333,
0.0138888888888889, 1, 0.861111111111111, 0.430555555555556,
0.513888888888889, 0.555555555555556, 0.708333333333333, 0.888888888888889,
0.645833333333333, 0.861111111111111, 0.25, 0.986111111111111,
0.756944444444444, 0.0416666666666667, 0.340277777777778, 0.861111111111111,
0.0416666666666667, 0.333333333333333, 0.930555555555556, 0.527777777777778,
0.722222222222222, 0.958333333333333, 0.513888888888889, 0.763888888888889
), Y = c(
1, 0.829268292682927, 0.878048780487805, 0.707317073170732,
0.902439024390244, 0.402439024390244, 0.902439024390244, 0.317073170731707,
0.51219512195122, 0.317073170731707, 0.341463414634146, 0.0731707317073171,
0.804878048780488, 0.902439024390244, 0.585365853658537, 0.902439024390244,
0.902439024390244, 0.024390243902439, 0.560975609756098, 0.75609756097561,
0.75609756097561, 0.317073170731707, 0.975609756097561, 0.878048780487805,
0.902439024390244, 0.768292682926829, 0.536585365853659, 0.878048780487805,
0.414634146341463, 0.0975609756097561, 0.878048780487805, 0.902439024390244,
0.585365853658537, 0.804878048780488, 0.878048780487805, 0.536585365853659,
0.195121951219512, 0.219512195121951, 0.731707317073171, 0.609756097560976,
0.0487804878048781, 0.902439024390244, 0.341463414634146, 0.75609756097561,
0.707317073170732, 0.707317073170732, 0.414634146341463, 0.975609756097561,
0.341463414634146, 0.585365853658537, 0.804878048780488, 0.707317073170732,
0.317073170731707, 0.707317073170732, 0.609756097560976, 0.878048780487805,
0.75609756097561, 0.707317073170732, 0.195121951219512, 0.829268292682927,
0.585365853658537, 0.548780487804878, 0.0975609756097561, 0.634146341463415,
0.585365853658537, 0.804878048780488, 0.195121951219512, 0.731707317073171,
0.463414634146341, 0.219512195121951, 0.902439024390244, 0.51219512195122
)), .Names = c("theta", "X", "Y")),
"reverse" = structure(list(theta = 0.388042005420054, X = c(
0, 0.170731707317073,
0.121951219512195, 0.292682926829268, 0.0975609756097561, 0.597560975609756,
0.0975609756097561, 0.682926829268293, 0.48780487804878, 0.682926829268293,
0.658536585365854, 0.926829268292683, 0.195121951219512, 0.0975609756097561,
0.414634146341463, 0.0975609756097561, 0.0975609756097561, 0.975609756097561,
0.439024390243902, 0.24390243902439, 0.24390243902439, 0.682926829268293,
0.024390243902439, 0.121951219512195, 0.0975609756097561, 0.231707317073171,
0.463414634146341, 0.121951219512195, 0.585365853658537, 0.902439024390244,
0.121951219512195, 0.0975609756097561, 0.414634146341463, 0.195121951219512,
0.121951219512195, 0.463414634146341, 0.804878048780488, 0.780487804878049,
0.268292682926829, 0.390243902439024, 0.951219512195122, 0.0975609756097561,
0.658536585365854, 0.24390243902439, 0.292682926829268, 0.292682926829268,
0.585365853658537, 0.024390243902439, 0.658536585365854, 0.414634146341463,
0.195121951219512, 0.292682926829268, 0.682926829268293, 0.292682926829268,
0.390243902439024, 0.121951219512195, 0.24390243902439, 0.292682926829268,
0.804878048780488, 0.170731707317073, 0.414634146341463, 0.451219512195122,
0.902439024390244, 0.365853658536585, 0.414634146341463, 0.195121951219512,
0.804878048780488, 0.268292682926829, 0.536585365853659, 0.780487804878049,
0.0975609756097561, 0.48780487804878
), Y = c(
0.194444444444444,
0.375, 0.319444444444444, 0.236111111111111, 0.958333333333333,
0.722222222222222, 0.486111111111111, 0.0694444444444444, 0.0277777777777778,
0.0694444444444444, 0.0694444444444444, 0.597222222222222, 0.277777777777778,
0.138888888888889, 0.833333333333333, 0.75, 0.291666666666667,
0.986111111111111, 0, 0.138888888888889, 0.569444444444444, 0.486111111111111,
0.444444444444444, 0.291666666666667, 0.111111111111111, 0.354166666666667,
0.138888888888889, 0.75, 0.0138888888888889, 0.243055555555556,
0.958333333333333, 0.659722222222222, 0.138888888888889, 0.958333333333333,
0.666666666666667, 0.0694444444444444, 0.472222222222222, 0.277777777777778,
0.0416666666666667, 0.486111111111111, 0.236111111111111
)), .Names = c(
"theta",
"X", "Y"
))
),
"wfns" = list(
"forward" = structure(list(theta = 0.823678861788618, X = c(
0.8125, 0.652777777777778,
0.888888888888889, 0.972222222222222, 0.972222222222222, 0.972222222222222,
0.972222222222222, 0.652777777777778, 0.972222222222222, 0.652777777777778,
0.256944444444444, 0.652777777777778, 0.972222222222222, 0.888888888888889,
0.888888888888889, 0.652777777777778, 0.972222222222222, 0.972222222222222,
0.972222222222222, 0.652777777777778, 0.972222222222222, 0.652777777777778,
0.972222222222222, 0.652777777777778, 0.888888888888889, 0.972222222222222,
0.888888888888889, 0.888888888888889, 0.256944444444444, 0.888888888888889,
0.888888888888889, 0.652777777777778, 0.652777777777778, 0.972222222222222,
0.972222222222222, 0.652777777777778, 0.652777777777778, 0.972222222222222,
0.972222222222222, 0.972222222222222, 0.972222222222222
), Y = c(
0.975609756097561,
0.975609756097561, 0.975609756097561, 0.975609756097561, 0.219512195121951,
0.975609756097561, 0.804878048780488, 0.804878048780488, 0.975609756097561,
0.804878048780488, 0.804878048780488, 0.975609756097561, 0.975609756097561,
0.975609756097561, 0.804878048780488, 0.975609756097561, 0.804878048780488,
0.975609756097561, 0.975609756097561, 0.646341463414634, 0.536585365853659,
0.975609756097561, 0.536585365853659, 0.975609756097561, 0.219512195121951,
0.219512195121951, 0.975609756097561, 0.975609756097561, 0.804878048780488,
0.536585365853659, 0.975609756097561, 0.975609756097561, 0.804878048780488,
0.804878048780488, 0.975609756097561, 0.804878048780488, 0.975609756097561,
0.804878048780488, 0.804878048780488, 0.975609756097561, 0.975609756097561,
0.975609756097561, 0.975609756097561, 0.804878048780488, 0.975609756097561,
0.804878048780488, 0.975609756097561, 0.975609756097561, 0.646341463414634,
0.804878048780488, 0.536585365853659, 0.804878048780488, 0.975609756097561,
0.536585365853659, 0.975609756097561, 0.975609756097561, 0.219512195121951,
0.536585365853659, 0.804878048780488, 0.804878048780488, 0.975609756097561,
0.975609756097561, 0.975609756097561, 0.646341463414634, 0.975609756097561,
0.804878048780488, 0.804878048780488, 0.536585365853659, 0.536585365853659,
0.975609756097561, 0.975609756097561, 0.975609756097561
)), .Names = c(
"theta",
"X", "Y"
)),
"reverse" = structure(list(theta = 0.176321138211382, X = c(
0.024390243902439,
0.024390243902439, 0.024390243902439, 0.024390243902439, 0.780487804878049,
0.024390243902439, 0.195121951219512, 0.195121951219512, 0.024390243902439,
0.195121951219512, 0.195121951219512, 0.024390243902439, 0.024390243902439,
0.024390243902439, 0.195121951219512, 0.024390243902439, 0.195121951219512,
0.024390243902439, 0.024390243902439, 0.353658536585366, 0.463414634146341,
0.024390243902439, 0.463414634146341, 0.024390243902439, 0.780487804878049,
0.780487804878049, 0.024390243902439, 0.024390243902439, 0.195121951219512,
0.463414634146341, 0.024390243902439, 0.024390243902439, 0.195121951219512,
0.195121951219512, 0.024390243902439, 0.195121951219512, 0.024390243902439,
0.195121951219512, 0.195121951219512, 0.024390243902439, 0.024390243902439,
0.024390243902439, 0.024390243902439, 0.195121951219512, 0.024390243902439,
0.195121951219512, 0.024390243902439, 0.024390243902439, 0.353658536585366,
0.195121951219512, 0.463414634146341, 0.195121951219512, 0.024390243902439,
0.463414634146341, 0.024390243902439, 0.024390243902439, 0.780487804878049,
0.463414634146341, 0.195121951219512, 0.195121951219512, 0.024390243902439,
0.024390243902439, 0.024390243902439, 0.353658536585366, 0.024390243902439,
0.195121951219512, 0.195121951219512, 0.463414634146341, 0.463414634146341,
0.024390243902439, 0.024390243902439, 0.024390243902439
), Y = c(
0.1875,
0.347222222222222, 0.111111111111111, 0.0277777777777778, 0.0277777777777778,
0.0277777777777778, 0.0277777777777778, 0.347222222222222, 0.0277777777777778,
0.347222222222222, 0.743055555555556, 0.347222222222222, 0.0277777777777778,
0.111111111111111, 0.111111111111111, 0.347222222222222, 0.0277777777777778,
0.0277777777777778, 0.0277777777777778, 0.347222222222222, 0.0277777777777778,
0.347222222222222, 0.0277777777777778, 0.347222222222222, 0.111111111111111,
0.0277777777777778, 0.111111111111111, 0.111111111111111, 0.743055555555556,
0.111111111111111, 0.111111111111111, 0.347222222222222, 0.347222222222222,
0.0277777777777778, 0.0277777777777778, 0.347222222222222, 0.347222222222222,
0.0277777777777778, 0.0277777777777778, 0.0277777777777778, 0.0277777777777778
)), .Names = c("theta", "X", "Y"))
),
"s100b" = list(
"forward" = structure(list(theta = 0.731368563685637, X = c(
0.5625, 0.4375,
0.715277777777778, 0.541666666666667, 0.902777777777778, 1, 0.972222222222222,
0.180555555555556, 0.854166666666667, 0.347222222222222, 0.180555555555556,
0.888888888888889, 0.875, 0.965277777777778, 1, 0.819444444444444,
1, 1, 1, 0.180555555555556, 1, 0.833333333333333, 0, 0.347222222222222,
0.805555555555556, 1, 0.819444444444444, 1, 0.263888888888889,
0.819444444444444, 0.5625, 0.4375, 0.513888888888889, 0.805555555555556,
1, 0.611111111111111, 1, 0.840277777777778, 1, 1, 0.902777777777778
), Y = c(
0.707317073170732, 0.670731707317073, 0.804878048780488,
0.975609756097561, 0.341463414634146, 0.634146341463415, 0.804878048780488,
0.804878048780488, 0.975609756097561, 0.890243902439024, 0.975609756097561,
0.853658536585366, 0.768292682926829, 0.939024390243902, 0.634146341463415,
0.939024390243902, 0.768292682926829, 0.707317073170732, 0.634146341463415,
0.975609756097561, 0.646341463414634, 0.670731707317073, 0.439024390243902,
0.853658536585366, 0.292682926829268, 0.341463414634146, 0.646341463414634,
0.939024390243902, 0.390243902439024, 0.341463414634146, 0.768292682926829,
0.890243902439024, 0.853658536585366, 0.890243902439024, 0.975609756097561,
0.707317073170732, 0.804878048780488, 0.670731707317073, 0.658536585365854,
0.975609756097561, 0.975609756097561, 0.853658536585366, 0.975609756097561,
0.853658536585366, 0.890243902439024, 0.646341463414634, 0.853658536585366,
0.890243902439024, 0.451219512195122, 0.768292682926829, 0.51219512195122,
0.939024390243902, 0.804878048780488, 0.475609756097561, 0.939024390243902,
0.975609756097561, 0.585365853658537, 0.414634146341463, 0.804878048780488,
0.658536585365854, 0.890243902439024, 0.670731707317073, 0.804878048780488,
0.939024390243902, 0.975609756097561, 0.634146341463415, 0.658536585365854,
0.341463414634146, 0.634146341463415, 0.658536585365854, 0.292682926829268,
0.329268292682927
)), .Names = c("theta", "X", "Y")),
"reverse" = structure(list(theta = 0.268631436314363, X = c(
0.292682926829268,
0.329268292682927, 0.195121951219512, 0.024390243902439, 0.658536585365854,
0.365853658536585, 0.195121951219512, 0.195121951219512, 0.024390243902439,
0.109756097560976, 0.024390243902439, 0.146341463414634, 0.231707317073171,
0.0609756097560976, 0.365853658536585, 0.0609756097560976, 0.231707317073171,
0.292682926829268, 0.365853658536585, 0.024390243902439, 0.353658536585366,
0.329268292682927, 0.560975609756098, 0.146341463414634, 0.707317073170732,
0.658536585365854, 0.353658536585366, 0.0609756097560976, 0.609756097560976,
0.658536585365854, 0.231707317073171, 0.109756097560976, 0.146341463414634,
0.109756097560976, 0.024390243902439, 0.292682926829268, 0.195121951219512,
0.329268292682927, 0.341463414634146, 0.024390243902439, 0.024390243902439,
0.146341463414634, 0.024390243902439, 0.146341463414634, 0.109756097560976,
0.353658536585366, 0.146341463414634, 0.109756097560976, 0.548780487804878,
0.231707317073171, 0.48780487804878, 0.0609756097560976, 0.195121951219512,
0.524390243902439, 0.0609756097560976, 0.024390243902439, 0.414634146341463,
0.585365853658537, 0.195121951219512, 0.341463414634146, 0.109756097560976,
0.329268292682927, 0.195121951219512, 0.0609756097560976, 0.024390243902439,
0.365853658536585, 0.341463414634146, 0.658536585365854, 0.365853658536585,
0.341463414634146, 0.707317073170732, 0.670731707317073
), Y = c(
0.4375,
0.5625, 0.284722222222222, 0.458333333333333, 0.0972222222222222,
0, 0.0277777777777778, 0.819444444444444, 0.145833333333333,
0.652777777777778, 0.819444444444444, 0.111111111111111, 0.125,
0.0347222222222222, 0, 0.180555555555556, 0, 0, 0, 0.819444444444444,
0, 0.166666666666667, 1, 0.652777777777778, 0.194444444444444,
0, 0.180555555555556, 0, 0.736111111111111, 0.180555555555556,
0.4375, 0.5625, 0.486111111111111, 0.194444444444444, 0, 0.388888888888889,
0, 0.159722222222222, 0, 0, 0.0972222222222222
)), .Names = c(
"theta",
"X", "Y"
))
),
list
)
pROC/tests/testthat/test-ci.thresholds.R 0000644 0001762 0000144 00000005552 15040443562 017742 0 ustar ligges users library(pROC)
data(aSAH)
context("ci.thresholds")
# Only test whether ci.thresholds runs and returns without error.
# Uses a very small number of iterations for speed
# Doesn't test whether the results are correct.
for (stratified in c(TRUE, FALSE)) {
test_that("ci.threshold accepts thresholds=best", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.thresholds(r.wfns,
thresholds = "best", boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expect_is(obtained, "ci.thresholds")
expect_is(obtained, "ci")
expect_equal(names(obtained), c("specificity", "sensitivity"))
expect_equal(dim(obtained$specificity), c(1, 3))
expect_equal(dim(obtained$sensitivity), c(1, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained$specificity), c("4.5%", "50%", "95.5%"))
expect_equal(colnames(obtained$sensitivity), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
test_that("ci.threshold accepts thresholds=best", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.thresholds(r.ndka,
thresholds = "local maximas", boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expected.thresholds <- coords(r.ndka, x = "l", ret = "t", transpose = FALSE)$threshold
expect_is(obtained, "ci.thresholds")
expect_is(obtained, "ci")
expect_equal(names(obtained), c("specificity", "sensitivity"))
expect_equal(dim(obtained$specificity), c(length(expected.thresholds), 3))
expect_equal(dim(obtained$sensitivity), c(length(expected.thresholds), 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained$specificity), c("4.5%", "50%", "95.5%"))
expect_equal(colnames(obtained$sensitivity), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
test_that("ci.threshold accepts numeric thresholds", {
n <- round(runif(1, 3, 9)) # keep boot.n small
obtained <- ci.thresholds(r.ndka,
thresholds = c(0.5, 0.2), boot.n = n,
boot.stratified = stratified, conf.level = .91
)
expected.thresholds <- coords(r.ndka, x = "l", ret = "t", transpose = FALSE)$threshold
expect_is(obtained, "ci.thresholds")
expect_is(obtained, "ci")
expect_equal(names(obtained), c("specificity", "sensitivity"))
expect_equal(dim(obtained$specificity), c(2, 3))
expect_equal(dim(obtained$sensitivity), c(2, 3))
expect_equal(attr(obtained, "conf.level"), .91)
expect_equal(attr(obtained, "boot.n"), n)
expect_equal(colnames(obtained$specificity), c("4.5%", "50%", "95.5%"))
expect_equal(colnames(obtained$sensitivity), c("4.5%", "50%", "95.5%"))
expect_equal(attr(obtained, "boot.stratified"), stratified)
})
}
pROC/tests/testthat/test-power.roc.test.R 0000644 0001762 0000144 00000025021 15040443562 020056 0 ustar ligges users library(pROC)
data(aSAH)
context("power.roc.test")
# define variables shared among multiple tests here
test_that("power.roc.test basic function", {
res <- power.roc.test(r.s100b)
expect_equal(as.numeric(res$auc), as.numeric(r.s100b$auc))
expect_equal(res$ncases, length(r.s100b$cases))
expect_equal(res$ncontrols, length(r.s100b$controls))
expect_equal(res$sig.level, 0.05)
expect_equal(res$power, 0.9904833, tolerance = 0.000001)
})
test_that("power.roc.test with percent works", {
res <- power.roc.test(r.s100b.percent)
expect_equal(as.numeric(res$auc), as.numeric(r.s100b$auc))
expect_equal(res$ncases, length(r.s100b$cases))
expect_equal(res$ncontrols, length(r.s100b$controls))
expect_equal(res$sig.level, 0.05)
expect_equal(res$power, 0.9904833, tolerance = 0.000001)
})
test_that("power.roc.test with given auc function", {
res <- power.roc.test(ncases = 41, ncontrols = 72, auc = 0.73, sig.level = 0.05)
expect_equal(as.numeric(res$auc), 0.73)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(res$sig.level, 0.05)
expect_equal(res$power, 0.9897453, tolerance = 0.000001)
})
test_that("power.roc.test sig.level can be omitted", {
res <- power.roc.test(ncases = 41, ncontrols = 72, auc = 0.73)
expect_equal(res$sig.level, 0.05)
expect_equal(res$power, 0.9897453, tolerance = 0.000001)
})
test_that("power.roc.test can determine ncases & ncontrols", {
res <- power.roc.test(auc = r.s100b$auc, sig.level = 0.05, power = 0.95, kappa = 1.7)
expect_equal(as.numeric(res$auc), as.numeric(r.s100b$auc))
expect_equal(res$sig.level, 0.05)
expect_equal(res$power, 0.95)
expect_equal(res$ncases, 29.29764, tolerance = 0.000001)
expect_equal(res$ncontrols, 49.806, tolerance = 0.000001)
})
test_that("power.roc.test can determine sig.level", {
res <- power.roc.test(ncases = 41, ncontrols = 72, auc = 0.73, power = 0.95, sig.level = NULL)
expect_equal(as.numeric(res$auc), 0.73)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(res$power, 0.95)
expect_equal(res$sig.level, 0.009238584, tolerance = 0.000001)
})
test_that("power.roc.test can determine AUC", {
res <- power.roc.test(ncases = 41, ncontrols = 72, sig.level = 0.05, power = 0.95)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(res$power, 0.95)
expect_equal(res$sig.level, 0.05)
expect_equal(as.numeric(res$auc), 0.6961054, tolerance = 0.000001)
})
test_that("power.roc.test can take 2 ROC curves with DeLong variance", {
res <- power.roc.test(r.ndka, r.wfns)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.7131594, tolerance = 0.000001)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test can take 2 percent ROC curves with DeLong variance", {
res <- power.roc.test(r.ndka.percent, r.wfns.percent)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.7131594, tolerance = 0.000001)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test can take 2 ROC curves with Obuchowski variance", {
res <- power.roc.test(r.ndka, r.wfns, method = "obuchowski")
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.8061004, tolerance = 0.000001)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test ncases/ncontrols can take 2 ROC curves with DeLong variance", {
res <- power.roc.test(r.ndka, r.wfns, power = 0.9)
expect_equal(res$ncases, 64.77777, tolerance = 0.000001)
expect_equal(res$ncontrols, 113.7561, tolerance = 0.000001)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.9)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test ncases/ncontrols can take 2 ROC curves with Obuchowski variance", {
res <- power.roc.test(r.ndka, r.wfns, power = 0.9, method = "obuchowski")
expect_equal(res$ncases, 53.23685, tolerance = 0.000001)
expect_equal(res$ncontrols, 93.48911, tolerance = 0.000001)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.9)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test sig.level can take 2 ROC curves with DeLong variance", {
res <- power.roc.test(r.ndka, r.wfns, power = 0.9, sig.level = NULL)
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.9)
expect_equal(res$sig.level, 0.1836639, tolerance = 0.000001)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test sig.level can take 2 ROC curves with Obuchowski variance", {
res <- power.roc.test(r.ndka, r.wfns, power = 0.9, sig.level = NULL, method = "obuchowski")
expect_equal(res$ncases, 41)
expect_equal(res$ncontrols, 72)
expect_equal(as.numeric(res$auc1), as.numeric(r.ndka$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.wfns$auc))
expect_equal(res$power, 0.9)
expect_equal(res$sig.level, 0.1150686, tolerance = 0.000001)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test works with partial AUC", {
skip_slow()
skip("Bootstrap cannot be tested yet")
r.wfns.partial <- roc(aSAH$outcome, aSAH$wfns, quiet = TRUE, partial.auc = c(1, 0.9))
r.ndka.partial <- roc(aSAH$outcome, aSAH$ndka, quiet = TRUE, partial.auc = c(1, 0.9))
power.roc.test(r.wfns.partial, r.ndka.partial, power = 0.9)
})
test_that("power.roc.test works with partial AUC", {
r.wfns.partial <- roc(aSAH$outcome, aSAH$wfns, quiet = TRUE, partial.auc = c(1, 0.9))
r.ndka.partial <- roc(aSAH$outcome, aSAH$ndka, quiet = TRUE, partial.auc = c(1, 0.9))
res <- power.roc.test(r.wfns.partial, r.ndka.partial, power = 0.9, method = "obuchowski")
expect_equal(res$ncases, 0.5061498, tolerance = 0.000001)
expect_equal(res$ncontrols, 0.8888484, tolerance = 0.000001)
expect_equal(as.numeric(res$auc1), as.numeric(r.wfns.partial$auc))
expect_equal(as.numeric(res$auc2), as.numeric(r.ndka.partial$auc))
expect_equal(res$power, 0.9)
expect_equal(res$sig.level, 0.05)
expect_equal(res$alternative, "two.sided")
})
test_that("power.roc.test works with binormal parameters", {
ob.params <- list(
A1 = 2.6, B1 = 1, A2 = 1.9, B2 = 1, rn = 0.6, ra = 0.6, FPR11 = 0,
FPR12 = 0.2, FPR21 = 0, FPR22 = 0.2, delta = 0.037
)
res1 <- power.roc.test(ob.params, power = 0.8, sig.level = 0.05)
expect_equal(res1$ncases, 107.0238, tolerance = 0.000001)
expect_equal(res1$ncontrols, 107.0238, tolerance = 0.000001)
expect_equal(res1$power, 0.8)
expect_equal(res1$sig.level, 0.05)
res2 <- power.roc.test(ob.params, power = 0.8, sig.level = NULL, ncases = 107)
expect_equal(res2$ncases, 107)
expect_equal(res2$ncontrols, 107)
expect_equal(res2$power, 0.8)
expect_equal(res2$sig.level, 0.05004012, tolerance = 0.000001)
res3 <- power.roc.test(ob.params, power = NULL, sig.level = 0.05, ncases = 107)
expect_equal(res3$ncases, 107)
expect_equal(res3$ncontrols, 107)
expect_equal(res3$sig.level, 0.05)
expect_equal(res3$power, 0.7999286, tolerance = 0.000001)
})
## With only binormal parameters given
# From example 2 of Obuchowski and McClish, 1997.
test_that("power.roc.test returns correct results from litterature", {
context("Check results in Obuchowski 2004 Table 4")
# Note: the table reports at least 10 in each cell, and adapts
# the complement value to match kappa. So in 0.25/0.95 we have 10/40
# although both values are < 10.
# Note2: some values don't match exactly, specifically
# expected.ncases[0.5, 0.6] and expected.ncontrols[4, 0.6]
# are off by 1 (< 1%).
kappas <- c(0.25, 0.5, 1, 2, 4)
thetas <- c(0.6, 0.7, 0.8, 0.9, 0.95)
expected.ncontrols <- matrix(
c(
84, 20, 10, 10, 10,
101, 25, 10, 10, 10,
135, 33, 14, 10, 10,
203, 50, 21, 20, 20,
# 339, 84, 40, 40, 40
340, 84, 40, 40, 40 # Fixed
),
nrow = 5, byrow = TRUE,
dimnames = list(kappas, thetas)
)
expected.ncases <- matrix(
c(
334, 80, 40, 40, 40,
# 201, 49, 20, 20, 20,
202, 49, 20, 20, 20, # Fixed
135, 33, 14, 10, 10,
102, 25, 11, 10, 10,
85, 21, 10, 10, 10
),
nrow = 5, byrow = TRUE,
dimnames = list(kappas, thetas)
)
for (kappa in kappas) {
for (theta in thetas) {
context(sprintf("kappa: %s, theta: %s", kappa, theta))
pr <- power.roc.test(auc = theta, sig.level = 0.05, power = 0.9, kappa = kappa, alternative = "one.sided")
expect_equal(max(10, ifelse(ceiling(pr$ncases) < 10, 10, 0) * kappa, ceiling(pr$ncontrols)), expected.ncontrols[as.character(kappa), as.character(theta)])
expect_equal(max(10, ifelse(ceiling(pr$ncontrols) < 10, 10, 0) / kappa, ceiling(pr$ncases)), expected.ncases[as.character(kappa), as.character(theta)])
}
}
})
test_that("kappa works with a single ROC curve", {
# kappa from data
res <- power.roc.test(r.s100b, sig.level = 0.05, power = 0.9)
expect_equal(res$ncases, 23.5598674)
expect_equal(res$ncontrols, 41.3734257)
expect_equal(res$ncases / res$ncontrols, length(r.s100b$cases) / length(r.s100b$controls))
# set kappa
res <- power.roc.test(r.s100b, sig.level = 0.05, power = 0.9, kappa = 1)
expect_equal(res$ncases, 29.5697422)
expect_equal(res$ncontrols, 29.5697422)
})
test_that("kappa works with two ROC curves", {
# kappa from data
res <- power.roc.test(r.s100b, r.ndka, sig.level = 0.05, power = 0.9)
expect_equal(res$ncases, 213.117677)
expect_equal(res$ncontrols, 374.255432)
expect_equal(res$ncases / res$ncontrols, length(r.s100b$cases) / length(r.s100b$controls))
# set kappa
res <- power.roc.test(r.s100b, r.ndka, sig.level = 0.05, power = 0.9, kappa = 1)
expect_equal(res$ncases, 213.117677)
expect_equal(res$ncases, 213.117677)
# ...
})
pROC/tests/testthat.R 0000644 0001762 0000144 00000000077 15040443562 014211 0 ustar ligges users library(testthat)
library(pROC)
data(aSAH)
test_check("pROC")
pROC/MD5 0000644 0001762 0000144 00000031430 15042637256 011400 0 ustar ligges users e7d1ad5e4434c8b181133d051518f697 *DESCRIPTION
e3e5f90ccd247705d1ca21aff87c1b1c *NAMESPACE
c5988dc120e88057f9f70d18084c4d21 *NEWS
c84a5ad30c654c7e60aab479040949b7 *R/RcppExports.R
879bcd23716b7496bc65d5065846b37e *R/are.paired.R
4d2d72d558dd05a3a19bb897c338939c *R/auc.R
797a9528138b6d8c667188ebf35c632c *R/bootstrap.R
4b701813022299e42230de52a49a07e4 *R/ci.R
ed7cfeed4acbe29ba9ff0a793b05474b *R/ci.auc.R
23fc8535dd5ac5498d287c1ac620f147 *R/ci.coords.R
736ed321db8535416827eb599c61a96c *R/ci.se.R
415dad083777eb7893f24e91a4e7a168 *R/ci.sp.R
5693269b7c192e2f13f538ea86cbe6c4 *R/ci.thresholds.R
0e7e2a6ac1290448b4808c92fabdeb56 *R/coords.R
daebf1c56caa99f811bba427915f3f14 *R/cov.R
7ea39f37de50a5ad2f67a64fb31d59c3 *R/delong.R
43a18f9632772aa4402d26855b368bbc *R/geom_polygon_auc.R
de945bf80e64479637aa4681dbb77fc0 *R/ggroc.R
82ae5c0de3d5d4ca512d1abfbbcff453 *R/groupGeneric.R
947cb4d863db89a922a26f133ed8eff2 *R/has.partial.auc.R
3c108c72e0baccc2cf42dfa95b4dba52 *R/lines.roc.R
5573fbd34bffd87205572eb4a2a934b5 *R/multiclass.R
436a84af90571e541e18d18c13996813 *R/null.roc.R
9211b1dd8db8e9dd02150ed74b9c8005 *R/obuchowski.R
fc369c265ac5e5f23dfa9ae757dc73bb *R/onLoad.R
6f28722592f0f48406794e11f6b5a77f *R/plot.ci.R
788ca5db85dc27b714d3f6bd485b3d41 *R/plot.roc.R
121dca411ec96c888e67e99beb3c6d57 *R/power.roc.test.R
ac19fd2e385c10edc92009e48931fa29 *R/print.R
89cdc9efb51febf28488b892bad21455 *R/roc.R
5839ab5d4fe7a9c6a8111bef1612bd58 *R/roc.test.R
b6328d03b06dbaef553aeb502a6971ee *R/roc.utils.R
5c44a40872ece6c831ccc37cfbe2297b *R/roc.utils.percent.R
a0eb16df239373c9ed9f5200fe1745e3 *R/smooth.R
27427f06c31f95306ed3420d236c729f *R/var.R
c501dd3c8a3779876b4f41e954809d68 *R/venkatraman.R
2991180cbf88890bfd2257245bcab56e *README.md
533839446f70bde34a1050627ce80586 *build/partial.rdb
e33e5e7b38d7ed92fcc33e9b0bea30ff *data/aSAH.RData
9afeef64698795744899eacd1d22da6c *inst/CITATION
e5368b578a5f3e3ab7cb3d0425622c24 *inst/extra/bench/fig-unnamed-chunk-13-1.png
56b79d4a84df3d49a4074813565293fa *inst/extra/bench/fig-unnamed-chunk-5-1.png
633884dd445cf047b71c8dc1f32d2b11 *inst/extra/bench/fig-unnamed-chunk-9-1.png
abdc9962c9d7d0b5455fadb91b9499eb *inst/extra/benchmark.Rmd
264e005a23e243383c0282c3b276143a *inst/extra/benchmark.md
9be90c08a789f9c93188d4317b2a3681 *inst/extra/sos_clashes.R
b0feb80ddf533630709b900b5303bbcb *man/aSAH.Rd
a9ae4bf26bf6a740bf9dc0129eea6c64 *man/are.paired.Rd
74a315e2be9a0042eee55925ab9628d0 *man/auc.Rd
a6d7b0aa3436e05aa3ea505f018f24d5 *man/ci.Rd
8bf871aa3c794a8372e34cf93b562229 *man/ci.auc.Rd
692ea78725fe3ac644d95d12727663cd *man/ci.coords.Rd
a390e80218959706d88fa1eeae7feb46 *man/ci.se.Rd
7f0850ae9b6419e8f036727e65278707 *man/ci.sp.Rd
8b2407017e05b74c89b1aa685132f11e *man/ci.thresholds.Rd
c1bd0c14984af44a35d3ade927f37069 *man/coords.Rd
44dbe45a79f720de587e5d308e19f000 *man/coords_transpose.Rd
6e20df4899f43ee8474e81c3d7a53700 *man/cov.Rd
20ff31c0008c1ff621307355309dd4aa *man/geom_polygon_auc.roc.Rd
b07cd07c3ed83c00c3e7c6dd94d4371f *man/ggroc.Rd
413f7b80f60d02f9406d5148bb599d31 *man/groupGeneric.Rd
048bc5f42aa77f0da8dbf0273d44ca30 *man/has.partial.auc.Rd
84c33e9f954442a44d4294c20827434b *man/lines.roc.Rd
f503f5856fb0932df9969985b67a07ea *man/multiclass.Rd
356aa453ca5b6c2e6eb6b58d72f46b44 *man/pROC-package.Rd
39a4298af34c9a818a99f8fbef4c8dca *man/plot.ci.Rd
6c23cbced2b45db8c753f7d463cc914c *man/plot.roc.Rd
e71db6dcf07f8d2372ea0665f1fd666f *man/power.roc.test.Rd
64552950ff21b8eb7f5cc75f37ca4567 *man/print.Rd
d272a543404eafb61dceff2b3b909f64 *man/roc.Rd
920af988ea4f58fef80e919ec7d8585a *man/roc.test.Rd
f331bfc2d5286777ebd2934bac27bea9 *man/smooth.Rd
8010a05ff5fe353286bc49998d2ca3e6 *man/var.Rd
3b6454ac491393bde4893b77c991c411 *src/RcppExports.cpp
7770ca48e5f75bfd93282a6708d55701 *src/RcppVersion.cpp
9883349305bdff6faa8bbaea422cdfe7 *src/delong.cpp
b0e5c523f62c74c9afeea3e788fdbc03 *tests/testthat.R
c1c74300a5514bfaf524269308be10a3 *tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-partial-screenshot.svg
1b68154b222a109849f334f866e34f02 *tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-percent-legacy-screenshot.svg
4799affe29e5a9d75ecd8c1c207dda3b *tests/testthat/_snaps/geom_polygon_auc/geom-polygon-auc-screenshot.svg
b41954a07c214f58f46a21b987e3f575 *tests/testthat/_snaps/ggroc/ggroc-list-colour.svg
c6ef339954d6da92a38de4b8ec1aced1 *tests/testthat/_snaps/ggroc/ggroc-list-extra-aes-screenshot.svg
d7bafa111b2d099392370ee2fa3ca8f1 *tests/testthat/_snaps/ggroc/ggroc-list-group-facet-screenshot.svg
74711578c03085a99d34bbf5315138e5 *tests/testthat/_snaps/ggroc/ggroc-list-multi-aes.svg
53ada663946515b9d1a513b6ac78286b *tests/testthat/_snaps/ggroc/ggroc-list-scale-colour-manual.svg
017bf68442684bf97d275723940c81e2 *tests/testthat/_snaps/ggroc/ggroc-list-screenshot.svg
a394381842ece5f3668980452094e297 *tests/testthat/_snaps/ggroc/ggroc-screenshot-base.svg
2f19c41b005340044998f75bd938b1e5 *tests/testthat/_snaps/ggroc/ggroc-screenshot-legacy.svg
25e47d97e1a409777742a73a4534cd05 *tests/testthat/_snaps/ggroc/ggroc-screenshot-percent-legacy.svg
52b96981015578346a84d8148c36fbab *tests/testthat/_snaps/ggroc/ggroc-screenshot-percent.svg
27d5b966dfaa5cffbb1a39b55b769546 *tests/testthat/_snaps/ggroc/ggroc-screenshot.svg
0a34ecd69c8d9247fa81e1fee5747acc *tests/testthat/_snaps/ggroc/ggroc-smooth-list-screenshot.svg
88e4c16d36f6fba35ac748ef206b529b *tests/testthat/_snaps/ggroc/ggroc-smooth-screenshot.svg
1204cc9e05748e7127e11f60c29ad0dd *tests/testthat/_snaps/plot/advanced-screenshot-1.svg
e4215f61b97f978d0528c6d9319d6dd6 *tests/testthat/_snaps/plot/advanced-screenshot-2.svg
865af564505b0d5e439f02cfb496b104 *tests/testthat/_snaps/plot/advanced-screenshot-3.svg
76abaab2f0d6dc2347fc2bb142091133 *tests/testthat/_snaps/plot/advanced-screenshot-4.svg
cce358a70f652ddc5788594abe895044 *tests/testthat/_snaps/plot/advanced-screenshot-5.svg
03099a56c0fc23d021a42882e2179a1f *tests/testthat/_snaps/plot/advanced-screenshot-6.svg
6627a5f530f2843b6ff181c6c250164d *tests/testthat/_snaps/plot/basic-ndka.svg
14fbf6c3fdbb43a7f423dab9502f5f2d *tests/testthat/_snaps/plot/basic-s100b.svg
8b1c3c60dc4410eec7de44adb33d24c8 *tests/testthat/_snaps/plot/basic-wfns.svg
955651dfae72dffdaee4b05940da566f *tests/testthat/_snaps/plot/legacy-axes.svg
7a4067addce2194c51e09a3063f7fb5b *tests/testthat/_snaps/plot/plot-formula.svg
9e38916021d4c0717d2f7304daeed715 *tests/testthat/_snaps/plot/plot-pr.svg
0f181a73fbb34df9e50954c04f2a83a6 *tests/testthat/helper-coords-expected-smooth.R
c9478d04345fe0b0709bde2919afe260 *tests/testthat/helper-coords-expected.R
784f2abe81d2123477261a82da9bee90 *tests/testthat/helper-deLongPlacementsCpp-expected.R
40a1c95836cf8345fb99570992d9a9c1 *tests/testthat/helper-expect_equal_roc.R
c6d9290b4580aa92d05929b3a27e549c *tests/testthat/helper-expectations.R
6e2bcda752cd107b235c3ba42cf35277 *tests/testthat/helper-roc-expected.R
720dc9f1ecd420139c864f26aeb77c43 *tests/testthat/helper-roc.utils-expected.R
1873ca53879679a6987dfa2391371b03 *tests/testthat/helper-rocs.R
1a647bcc8ebf7aad3033d177f9490bd6 *tests/testthat/helper-skip.R
07e18c1aff756a8add7d6a7f9ab0e330 *tests/testthat/helper-vdiffr.R
2b8602ea23b78a56dd3b29f9fcaa4f51 *tests/testthat/print_output/multiclass
6bc0e1d2ad3376febd8296686d5edefd *tests/testthat/print_output/multiclass_levels
31af3ad2dd3035baf35bcda5eb79317c *tests/testthat/print_output/multiclass_partial
a8e4e4d73b76c0b3fc0bec9fbddad331 *tests/testthat/print_output/multiclass_partial_correct
6e1247aa7c490c815a2226d0a2fe445b *tests/testthat/print_output/multiclass_partial_se
a8ce6079f350b8a14f13485819503b75 *tests/testthat/print_output/multiclass_percent
3bda4031928d90f76cfc4c89d7e1de98 *tests/testthat/print_output/mv_multiclass
52f008f68c41fd7753cd0afcbcf66d91 *tests/testthat/print_output/mv_multiclass.ndka.formula
66221dee8271f01de6be63bc5ddfbe29 *tests/testthat/print_output/mv_multiclass_levels
e6862becc5d3104df16b8f4ea11c2524 *tests/testthat/print_output/mv_multiclass_partial
6ae718b44b2f1c7797590b6793df3b55 *tests/testthat/print_output/mv_multiclass_partial_correct
d112684a2b35e3574aaf81bc894b2299 *tests/testthat/print_output/mv_multiclass_partial_se
8b6217a308e31e3ae19c551569ff4f3d *tests/testthat/print_output/mv_multiclass_percent
20e3da54e8241e9d68297d5e43d4eb55 *tests/testthat/print_output/ndka_formula
07897b92d7caf25b27d8a490b7c0fa46 *tests/testthat/print_output/ndka_formula_attached
2c095837491fbe5a2dcc3b80d4969543 *tests/testthat/print_output/ndka_formula_var
06bc92d6fae6a4b6e45c712f3de363cb *tests/testthat/print_output/ndka_formula_var_attached
73c9ec8b06f2d2887001e54bfc603979 *tests/testthat/print_output/r.ndka
76bf9f0985367ec0a0ca4412010e4731 *tests/testthat/print_output/r.ndka.ci.auc
8921688704cc5296a910aee6653764ec *tests/testthat/print_output/r.ndka.ci.coords
c15919964b241d810bd9d5a1282cab2a *tests/testthat/print_output/r.ndka.ci.se
9a268b3ba056f2f04fd3a0db7ffd5dcd *tests/testthat/print_output/r.ndka.ci.sp
38a613d2ee6d9098b6c8b4521cb3c37a *tests/testthat/print_output/r.ndka.ci.thresholds
20e3da54e8241e9d68297d5e43d4eb55 *tests/testthat/print_output/r.ndka.formula
4f3538d3e8ae303c94cc0a40bb0cb27f *tests/testthat/print_output/r.ndka.formula.ci
09109ef75c67aaaf10ab85f32ab6e2bd *tests/testthat/print_output/r.ndka.formula.no_auc
5965132d3e6f618c029a326c68924060 *tests/testthat/print_output/r.ndka.partial1
36eaeccfc6296c322da47940e22aa01a *tests/testthat/print_output/r.ndka.percent
56321410b6cd60808ae6081ab26797ca *tests/testthat/print_output/r.ndka.percent.partial1
599d32a7c7ea10cbf012e66cd5dd5e9a *tests/testthat/print_output/r.s100b
22dadd712f7973e66997b668ba881894 *tests/testthat/print_output/r.s100b.partial1
648065fec1305aa8ea30a192de184a56 *tests/testthat/print_output/r.s100b.partial2
b7dcfd2a88f46ef319e897ef7ea8765d *tests/testthat/print_output/r.s100b.percent
416f3b5dc6f4e4b35eca621f7eb37c44 *tests/testthat/print_output/r.s100b.percent.partial1
e33cc698639a196bf10c759f55e23d80 *tests/testthat/print_output/r.wfns
6ee5cd4c7d51beebc08b49f3634e50d8 *tests/testthat/print_output/r.wfns.partial1
0501b1ea0951d6a233ca90082c35c706 *tests/testthat/print_output/r.wfns.percent
9d48383eed9176489894b0084a7044f3 *tests/testthat/print_output/r.wfns.percent.partial1
9102a55eb23ed8f566a49c4b33b5218c *tests/testthat/print_output/roc.test-venkatraman.paired
95f3320c74b0d7814093e1eb52033ac8 *tests/testthat/print_output/roc.test-venkatraman.unpaired
810e400cee477f8f99d29889975ac1e5 *tests/testthat/print_output/roc.test-venkatraman.unpaired.unstratified
4739552933356b33bb8754a48dfc06ea *tests/testthat/print_output/roc.test-venkatraman.unstratified
0a9ef7042d272331a0ba9ea3e07a18ca *tests/testthat/print_output/smooth.ndka
878b083364c3cbef619c0d1e31f55487 *tests/testthat/print_output/smooth.s100b.binormal
30141f3564d0dceb73d0b200698fca56 *tests/testthat/print_output/smooth.s100b.density
d70e2e82e3876d5c110e7d0cd2a7d86a *tests/testthat/print_output/smooth.s100b.fitdistr
0251d65a00ce5834b6fc55be885d4f06 *tests/testthat/print_output/smooth.s100b.formula
10b169570249e00adad5260d8843822b *tests/testthat/print_output/smooth.s100b.logcondens
51b720a8cb79f1263a54037213925c93 *tests/testthat/print_output/smooth.s100b.logcondens.smooth
0a9ef7042d272331a0ba9ea3e07a18ca *tests/testthat/print_output/smooth.wfns
f8eeb3cfa3839dad4e94da946c099399 *tests/testthat/test-Ops.R
aa95b2ceaacd20b96579da14fbfcd511 *tests/testthat/test-are-paired.R
960eee40b071bd5ae36de57a431cb925 *tests/testthat/test-auc.R
3249207ae91a54aa93cf5b4144f97b39 *tests/testthat/test-ci.auc.R
64a3a941efc435442604e49ffaa237f2 *tests/testthat/test-ci.coords.R
36f9d04c365e6c675af9cf3b45697540 *tests/testthat/test-ci.formula.R
96a52544467c7dcbfc6b32760d914693 *tests/testthat/test-ci.se.R
c97000a6239bc8fa838597c404bf3033 *tests/testthat/test-ci.sp.R
2839933e8ef44a8d69363a4a40af525b *tests/testthat/test-ci.thresholds.R
60a2cdf77cde9591c24258a1526875ad *tests/testthat/test-coords.R
b6526e5952ec3709a5576af37574622b *tests/testthat/test-cov.R
0adf9945fbf6122ed88feb773498da81 *tests/testthat/test-deLongPlacementsCpp.R
d6057901356f06f30af31c23b223c3e4 *tests/testthat/test-geom_polygon_auc.R
15de75922e257a58f9e59d4bfea5fa61 *tests/testthat/test-ggroc.R
910ea339e78263d181b75328325a9252 *tests/testthat/test-large.R
ab95d57626453d8cda9666323547b0e3 *tests/testthat/test-multiclass.R
0b950a7a3acd329377f4793c99956b9b *tests/testthat/test-numeric-Inf.R
5360314ff8659cb282f70fb296ceedf3 *tests/testthat/test-numeric-accuracy.R
bd4a476a019101cb3d700140d47e956a *tests/testthat/test-onload.R
30d5e3a94d4d56fc7379c0bb38a6ce10 *tests/testthat/test-plot.R
953c794c324c3a45b16cff8feac3a723 *tests/testthat/test-power.roc.test.R
5b7c83f881f37445db0da7b8bfbce403 *tests/testthat/test-print.R
fe7e2ce1c0a2ae5c1758556ac8b1b544 *tests/testthat/test-roc.R
5bd523585a27e036a8c81b6099d63176 *tests/testthat/test-roc.test-venkatraman.R
08f42f4dd167452df47ddd5237f92b78 *tests/testthat/test-roc.test.R
3a9dc100af51c8abe675c351f0932693 *tests/testthat/test-roc.utils.R
741eb27795ae96a10c586b236cd99341 *tests/testthat/test-roc.utils.percent.R
ba438d500665bd936e6759841aac23e9 *tests/testthat/test-smooth.R
d516a78b9e79f62af848d810cf913d9b *tests/testthat/test-var.R
pROC/R/ 0000755 0001762 0000144 00000000000 15042617211 011255 5 ustar ligges users pROC/R/geom_polygon_auc.R 0000644 0001762 0000144 00000003056 15040443562 014736 0 ustar ligges users geom_polygon_auc <- function(data, ...) {
UseMethod("geom_polygon_auc")
}
geom_polygon_auc.auc <- function(data, legacy.axes = FALSE, ...) {
# Get the roc data with coords
roc <- attr(data, "roc")
roc$auc <- data
df <- get.coords.for.ggplot(roc, ignore.partial.auc = FALSE)
# Add bottom-right point
partial.auc <- attr(data, "partial.auc")
one.or.hundred <- ifelse(attr(data, "percent"), 100, 1)
if (legacy.axes) {
if (identical(partial.auc, FALSE)) {
df[nrow(df) + 1, ] <- c(NA, one.or.hundred, 0, one.or.hundred)
} else if (attr(data, "partial.auc.focus") == "sensitivity") {
df[nrow(df) + c(1, 2), ] <- c(NA, NA, one.or.hundred, one.or.hundred, partial.auc, one.or.hundred, one.or.hundred)
} else { # partial.auc.focus == "specificity"
df[nrow(df) + c(1, 2), ] <- c(NA, NA, rev(partial.auc), 0, 0, one.or.hundred - rev(partial.auc))
}
} else {
if (identical(partial.auc, FALSE)) {
df[nrow(df) + 1, ] <- c(NA, 0, 0, 0)
} else if (attr(data, "partial.auc.focus") == "sensitivity") {
df[nrow(df) + c(1, 2), ] <- c(NA, NA, 0, 0, partial.auc, 0, 0)
} else { # partial.auc.focus == "specificity"
df[nrow(df) + c(1, 2), ] <- c(NA, NA, rev(partial.auc), 0, 0, one.or.hundred - rev(partial.auc))
}
}
# Prepare the aesthetics
aes <- get.aes.for.ggplot(attr(data, "roc"), legacy.axes)
# Do the plotting
ggplot2::geom_polygon(aes$aes, data = df, ...)
}
geom_polygon_auc.roc <- function(data, ...) {
geom_polygon_auc(data$auc, ...)
}
geom_polygon_auc.smooth.roc <- geom_polygon_auc.roc
pROC/R/ci.thresholds.R 0000644 0001762 0000144 00000010301 15040443562 014150 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci.thresholds <- function(...) {
UseMethod("ci.thresholds")
}
ci.thresholds.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci.thresholds'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.thresholds(roc(response, predictor, ci = FALSE, ...), ...)
}
ci.thresholds.default <- function(response, predictor, ...) {
if (methods::is(response, "multiclass.roc") || methods::is(response, "multiclass.auc")) {
stop("'ci.thresholds' not available for multiclass ROC curves.")
}
ci.thresholds(roc.default(response, predictor, ci = FALSE, ...), ...)
}
ci.thresholds.smooth.roc <- function(smooth.roc, ...) {
stop("'ci.thresholds' is not available for smoothed ROC curves.")
}
ci.thresholds.roc <- function(roc,
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
thresholds = "local maximas",
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(roc)) {
warning("ci.thresholds() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# Check and prepare thresholds
if (is.character(thresholds)) {
if (length(thresholds) != 1) {
stop("'thresholds' of class character must be of length 1.")
}
thresholds <- match.arg(thresholds, c("all", "best", "local maximas"))
thresholds.num <- coords(roc, x = thresholds, input = "threshold", ret = "threshold", ...)[, 1]
attr(thresholds.num, "coords") <- thresholds
} else if (is.logical(thresholds)) {
thresholds.num <- roc$thresholds[thresholds]
attr(thresholds.num, "logical") <- thresholds
} else if (!is.numeric(thresholds)) {
stop("'thresholds' is not character, logical or numeric.")
} else {
thresholds.num <- thresholds
}
perfs_shape <- matrix(NA_real_, nrow = 2L, ncol = length(thresholds.num))
bootstrap_fun <- if (boot.stratified) stratified.ci.thresholds else nonstratified.ci.thresholds
perfs <- vapply(seq_len(boot.n), bootstrap_fun, FUN.VALUE = perfs_shape, roc = roc, thresholds = thresholds.num)
probs <- c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)
# output is length(probs) x 2 x length(thresholds.num)
perf_quantiles <- apply(perfs, 1:2, quantile, probs = probs)
sp <- t(perf_quantiles[, 1L, ])
se <- t(perf_quantiles[, 2L, ])
rownames(se) <- rownames(sp) <- thresholds.num
if (roc$percent) {
se <- se * 100
sp <- sp * 100
}
ci <- list(specificity = sp, sensitivity = se)
class(ci) <- c("ci.thresholds", "ci", "list")
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "thresholds") <- thresholds.num
attr(ci, "roc") <- roc
return(ci)
}
pROC/R/multiclass.R 0000644 0001762 0000144 00000021353 15040443562 013570 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2019 Xavier Robin, Matthias Doering,
# Alexandre Hainard, Natacha Turck, Natalia Tiberti,
# Frédérique Lisacek, Jean-Charles Sanchez and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
multiclass.roc <- function(...) {
UseMethod("multiclass.roc")
}
multiclass.roc.formula <- function(formula, data, ...) {
data.missing <- missing(data)
call <- match.call()
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = call
)
response <- roc.data$response
predictors <- roc.data$predictors
if (ncol(predictors) == 1) {
predictors <- predictors[, 1]
}
multiclass.roc <- multiclass.roc.default(response, predictors, ...)
multiclass.roc$call <- call
if (!data.missing) {
multiclass.roc$data <- data
}
return(multiclass.roc)
}
multiclass_roc_univariate <- function(response, predictor,
levels = base::levels(as.factor(response)),
percent = FALSE, # Must sensitivities, specificities and AUC be reported in percent? Note that if TRUE, and you want a partial area, you must pass it in percent also (partial.area=c(100, 80))
direction,
# what computation must be done
# auc=TRUE, # call auc.roc on the current object
# ci=FALSE, # call ci.roc on the current object
...) {
multiclass.roc <- list(
response = response,
predictor = predictor,
percent = percent
)
class(multiclass.roc) <- "multiclass.roc"
if (is.factor(response) && any(names(table(response))[table(response) == 0] %in% levels)) {
missing.levels <- names(table(response))[table(response) == 0]
missing.levels.requested <- missing.levels[missing.levels %in% levels]
warning(paste("No observation for response level(s):", paste(missing.levels.requested, collapse = ", ")))
levels <- levels[!(levels %in% missing.levels.requested)]
}
multiclass.roc$levels <- levels
rocs <- utils::combn(levels, 2, function(X, response, predictor, percent, ...) {
roc(response, predictor, levels = X, percent = percent, auc = FALSE, ci = FALSE, ...)
}, simplify = FALSE, response = response, predictor = predictor, percent = percent, direction = direction, ...)
multiclass.roc$rocs <- rocs
# Makes no sense to turn auc off, so remove this option
# if (auc)
multiclass.roc$auc <- auc.multiclass.roc(multiclass.roc, ...)
# CI is not implemented yet.
# if (ci)
# multiclass.roc$ci <- ci.multiclass.roc(multiclass.roc, ...)
return(multiclass.roc)
}
compute.pair.AUC <- function(pred.matrix, i, j, ref.outcome, levels, percent, direction, ...) {
# computes A(i|j), the probability that a randomly
# chosen member of class j has a lower estimated probability (or score)
# of belonging to class i than a randomly chosen member of class i
pred.i <- pred.matrix[which(ref.outcome == i), i] # p(G = i) assigned to class i observations
pred.j <- pred.matrix[which(ref.outcome == j), i] # p(G = i) assigned to class j observations
classes <- factor(c(rep(i, length(pred.i)), rep(j, length(pred.j))))
# override levels argument by new levels
levels <- unique(classes)
predictor <- c(pred.i, pred.j)
auc <- roc(classes, predictor, levels = levels, percent = percent, auc = FALSE, ci = FALSE, direction = direction, ...)
return(auc)
}
multiclass_roc_multivariate <- function(response, predictor, levels, percent, direction, ...) {
# Reference: "A Simple Generalisation of the Area Under the ROC
# Curve for Multiple Class Classification Problems" (Hand and Till, 2001)
if (!methods::is(predictor, "matrix") && !methods::is(predictor, "data.frame")) {
stop("Please provide a matrix or data frame via 'predictor'.")
}
if (nrow(predictor) != length(response)) {
stop("Number of rows in 'predictor' does not agree with 'response'")
}
if (direction == "auto") {
stop("'direction=\"auto\"' not available for multivariate multiclass.roc")
}
if (is.factor(response) && any(names(table(response))[table(response) == 0] %in% levels)) {
missing.levels <- names(table(response))[table(response) == 0]
missing.levels.requested <- missing.levels[missing.levels %in% levels]
warning(paste("No observation for response level(s):", paste(missing.levels.requested, collapse = ", ")))
levels <- levels[!(levels %in% missing.levels.requested)]
}
# check whether the columns of the prediction matrix agree with the factors in 'response'
m <- match(colnames(predictor), levels)
missing.classes <- levels[setdiff(seq_along(levels), m)]
levels <- colnames(predictor)[!is.na(m)]
if (length(levels) == 1) {
stop("For a single decision value, please provide 'predictor' as a vector.")
} else if (length(levels) == 0) {
stop("The column names of 'predictor' could not be matched to the levels of 'response'.")
}
if (length(missing.classes) != 0) {
out.classes <- paste0(missing.classes, collapse = ",")
if (length(missing.classes) == length(levels)) {
# no decision values found
stop(paste0(
"Could not find any decision values in 'predictor' matching the 'response' levels.",
" Could not find the following classes: ", out.classes, ". Check your column names!"
))
} else {
# some decision values not found
warning("You did not provide decision values for the following classes: ", out.classes, ".")
}
}
additional.classes <- colnames(predictor)[which(is.na(m))]
if (length(additional.classes) != 0) {
out.classes <- paste0(additional.classes, collapse = ",")
warning("The following classes were not found in 'response': ", out.classes, ".")
}
multiclass.roc <- list(
response = response,
predictor = predictor,
percent = percent
)
class(multiclass.roc) <- "mv.multiclass.roc"
multiclass.roc$levels <- levels
rocs <- utils::combn(levels, 2, function(x, predictor, response, levels, percent, direction, ...) {
A1 <- compute.pair.AUC(predictor, x[1], x[2], response, levels, percent, direction, ...)
A2 <- compute.pair.AUC(predictor, x[2], x[1], response, levels, percent, direction, ...)
# merging A1 and A2 is infeasible as auc() would not be well-defined
A <- list(A1, A2)
return(A)
},
simplify = FALSE, predictor = predictor, response = response,
levels = levels, percent = percent, direction, ...
)
pairs <- unlist(lapply(
utils::combn(levels, 2, simplify = FALSE),
function(x) paste(x, collapse = "/")
))
names(rocs) <- pairs
multiclass.roc$rocs <- rocs
multiclass.roc$auc <- auc.mv.multiclass.roc(multiclass.roc, ...)
return(multiclass.roc)
}
multiclass.roc.default <- function(response, predictor,
levels = base::levels(as.factor(response)),
percent = FALSE, # Must sensitivities, specificities and AUC be reported in percent? Note that if TRUE, and you want a partial area, you must pass it in percent also (partial.area=c(100, 80)),
direction = c("auto", "<", ">"),
...) {
# We need at least two levels in response
if (length(unique(response)) < 2) {
stop("'response' must have at least two levels")
}
# implements the approach from Hand & Till (2001)
if (methods::is(predictor, "matrix") || methods::is(predictor, "data.frame")) {
# for decision values for multiple classes (e.g. probabilities of individual classes)
if (missing("direction")) {
# need to have uni-directional decision values for consistency
direction <- ">"
} else {
direction <- match.arg(direction)
}
mc.roc <- multiclass_roc_multivariate(response, predictor, levels, percent, direction, ...)
} else {
# for a single decision value for separating the classes
direction <- match.arg(direction)
mc.roc <- multiclass_roc_univariate(response, predictor, levels, percent, direction, ...)
}
mc.roc$call <- match.call()
return(mc.roc)
}
pROC/R/RcppExports.R 0000644 0001762 0000144 00000000423 15040443562 013674 0 ustar ligges users # Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
RcppVersion <- function() {
.Call(`_pROC_RcppVersion`)
}
delongPlacementsCpp <- function(roc) {
.Call(`_pROC_delongPlacementsCpp`, roc)
}
pROC/R/print.R 0000644 0001762 0000144 00000025074 15040443562 012550 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
print.smooth.roc <- function(x, digits = max(3, getOption("digits") - 3), call = TRUE, ...) {
# do we print the call?
if (call) {
cat("\nCall:\n", deparse(x$call), "\n\n", sep = "")
}
# Always print number of patients, controls, thresholds, levels?
print_dataline(attr(x, "roc")) # take this from original roc
# Smoothing
cat("Smoothing: ")
if (is.null(x$smoothing.args)) {
cat("density with controls: ", as.character(x$call[match("density.controls", names(x$call))]), "; and cases: ", as.character(x$call[match("density.cases", names(x$call))]), "\n", sep = "")
} else if (x$smoothing.args$method == "density") {
cat("density (bandwidth: ", x$smoothing.args$bw, "; adjust: ", ifelse(is.null(x$smoothing.args$adjust), 1, x$smoothing.args$adjust), ")\n", sep = "")
} else if (x$smoothing.args$method == "density") {
cat("fitting ", x$fit.controls$densfun, " distribution for controls:\n", sep = "")
print(x$fit.controls$estimate)
cat("fitting ", x$fit.cases$densfun, " distribution for cases:\n", sep = "")
print(x$fit.cases$estimate)
} else {
cat(x$smoothing.args$method, "\n")
}
# AUC if exists
if (!is.null(x$auc)) {
print(x$auc, digits = digits, ...)
} else {
cat("Area under the curve not computed.\n")
}
# CI if exists, print it
if (!is.null(x$ci)) {
print(x$ci, digits = digits, ...)
}
invisible(x)
}
print.multiclass.roc <- function(x, digits = max(3, getOption("digits") - 3), call = TRUE, ...) {
# do we print the call?
if (call) {
cat("\nCall:\n", deparse(x$call), "\n\n", sep = "")
}
# get predictor name
if ("predictor" %in% names(x$call)) {
predictor.name <- as.character(x$call[match("predictor", names(x$call))])
} else if (!is.null(x$call$formula)) {
predictor.name <- attr(terms(as.formula(x$call$formula), data = x$data), "term.labels")
}
# Get response
if ("response" %in% names(x$call)) {
response.name <- as.character(x$call[match("response", names(x$call))])
} else if (!is.null(x$call$formula)) {
formula.attrs <- attributes(terms(as.formula(x$call$formula), data = x$data))
response.name <- rownames(formula.attrs$factors)[formula.attrs$response]
}
cat("Data: ", predictor.name, " with ", length(x$levels), " levels of ", response.name, ": ", paste(x$levels, collapse = ", "), ".\n", sep = "")
# AUC if exists
if (!is.null(x$auc)) {
print(x$auc, digits = digits, ...)
} else {
cat("Multi-class area under the curve not computed.\n")
}
# CI if exists, print it
if (!is.null(x$ci)) {
print(x$ci, digits = digits, ...)
}
invisible(x)
}
print.mv.multiclass.roc <- function(x, digits = max(3, getOption("digits") - 3), call = TRUE, ...) {
# do we print the call?
if (call) {
cat("\nCall:\n", deparse(x$call), "\n\n", sep = "")
}
# get predictor name
if ("predictor" %in% names(x$call)) {
predictor.name <- as.character(x$call[match("predictor", names(x$call))])
} else if (!is.null(x$call$formula)) {
predictor.name <- attr(terms(as.formula(x$call$formula), data = x$data), "term.labels")
}
# Get response
if ("response" %in% names(x$call)) {
response.name <- as.character(x$call[match("response", names(x$call))])
} else if (!is.null(x$call$formula)) {
formula.attrs <- attributes(terms(as.formula(x$call$formula), data = x$data))
response.name <- rownames(formula.attrs$factors)[formula.attrs$response]
}
cat("Data: multivariate predictor ", predictor.name, " with ", length(x$levels), " levels of ", response.name, ": ", paste(x$levels, collapse = ", "), ".\n", sep = "")
# AUC if exists
if (!is.null(x$auc)) {
print(x$auc, digits = digits, ...)
} else {
cat("Multi-class area under the curve not computed.\n")
}
# CI if exists, print it
if (!is.null(x$ci)) {
print(x$ci, digits = digits, ...)
}
invisible(x)
}
print.roc <- function(x, digits = max(3, getOption("digits") - 3), call = TRUE, ...) {
# do we print the call?
if (call) {
cat("\nCall:\n", deparse(x$call), "\n\n", sep = "")
}
# Always print number of patients, controls, thresholds, levels?
print_dataline(x)
# AUC if exists
if (!is.null(x$auc)) {
print(x$auc, digits = digits, ...)
} else {
cat("Area under the curve not computed.\n")
}
# CI if exists, print it
if (!is.null(x$ci)) {
print(x$ci, digits = digits, ...)
}
invisible(x)
}
print.auc <- function(x, digits = max(3, getOption("digits") - 3), ...) {
if (identical(attr(x, "partial.auc"), FALSE)) {
cat("Area under the curve: ", signif(x, digits = digits), ifelse(attr(x, "percent"), "%", ""), "\n", sep = "")
} else {
cat(ifelse(identical(attr(x, "partial.auc.correct"), TRUE), "Corrected p", "P"), "artial area under the curve", sep = "")
cat(" (", attr(x, "partial.auc.focus"), " ", attr(x, "partial.auc")[1], ifelse(attr(x, "percent"), "%", ""), "-", attr(x, "partial.auc")[2], ifelse(attr(x, "percent"), "%", ""), ")", sep = "")
cat(": ", signif(x, digits = digits), ifelse(attr(x, "percent"), "%", ""), "\n", sep = "")
}
invisible(x)
}
print.multiclass.auc <- function(x, digits = max(3, getOption("digits") - 3), ...) {
if (identical(attr(x, "partial.auc"), FALSE)) {
cat("Multi-class area under the curve: ", signif(x, digits = digits), ifelse(attr(x, "percent"), "%", ""), "\n", sep = "")
} else {
cat("Multi-class ", ifelse(identical(attr(x, "partial.auc.correct"), TRUE), "corrected ", ""), "partial area under the curve", sep = "")
cat(" (", attr(x, "partial.auc.focus"), " ", attr(x, "partial.auc")[1], ifelse(attr(x, "percent"), "%", ""), "-", attr(x, "partial.auc")[2], ifelse(attr(x, "percent"), "%", ""), ")", sep = "")
cat(": ", signif(x, digits = digits), ifelse(attr(x, "percent"), "%", ""), "\n", sep = "")
}
invisible(x)
}
print.mv.multiclass.auc <- print.multiclass.auc
print.ci.auc <- function(x, digits = max(3, getOption("digits") - 3), ...) {
signif.ci <- signif(x, digits = digits)
cat(attr(x, "conf.level") * 100, "% CI: ", sep = "")
cat(signif.ci[1], ifelse(attr(attr(x, "auc"), "percent"), "%", ""), "-", signif.ci[3], ifelse(attr(attr(x, "auc"), "percent"), "%", ""), sep = "")
if (attr(x, "method") == "delong") {
cat(" (DeLong)\n", sep = "")
} else {
cat(" (", attr(x, "boot.n"), " ", ifelse(attr(x, "boot.stratified"), "stratified", "non-stratified"), " bootstrap replicates)\n", sep = "")
}
invisible(x)
}
print.ci.thresholds <- function(x, digits = max(3, getOption("digits") - 3), ...) {
cat(attr(x, "conf.level") * 100, "% CI", sep = "")
cat(" (", attr(x, "boot.n"), " ", ifelse(attr(x, "boot.stratified"), "stratified", "non-stratified"), " bootstrap replicates):\n", sep = "")
signif.sp <- signif(x$sp, digits = digits)
signif.se <- signif(x$se, digits = digits)
print(data.frame(thresholds = attr(x, "thresholds"), sp.low = signif.sp[, 1], sp.median = signif.sp[, 2], sp.high = signif.sp[, 3], se.low = signif.se[, 1], se.median = signif.se[, 2], se.high = signif.se[, 3]), row.names = FALSE)
invisible(x)
}
print.ci.sp <- function(x, digits = max(3, getOption("digits") - 3), ...) {
cat(attr(x, "conf.level") * 100, "% CI", sep = "")
cat(" (", attr(x, "boot.n"), " ", ifelse(attr(x, "boot.stratified"), "stratified", "non-stratified"), " bootstrap replicates):\n", sep = "")
signif.sp <- signif(x, digits = digits)
print(data.frame(se = attr(x, "sensitivities"), sp.low = signif.sp[, 1], sp.median = signif.sp[, 2], sp.high = signif.sp[, 3]), row.names = FALSE)
invisible(x)
}
print.ci.se <- function(x, digits = max(3, getOption("digits") - 3), ...) {
cat(attr(x, "conf.level") * 100, "% CI", sep = "")
cat(" (", attr(x, "boot.n"), " ", ifelse(attr(x, "boot.stratified"), "stratified", "non-stratified"), " bootstrap replicates):\n", sep = "")
signif.se <- signif(x, digits = digits)
print(data.frame(sp = attr(x, "specificities"), se.low = signif.se[, 1], se.median = signif.se[, 2], se.high = signif.se[, 3]), row.names = FALSE)
invisible(x)
}
print.ci.coords <- function(x, digits = max(3, getOption("digits") - 3), ...) {
cat(attr(x, "conf.level") * 100, "% CI", sep = "")
cat(" (", attr(x, "boot.n"), " ", ifelse(attr(x, "boot.stratified"), "stratified", "non-stratified"), " bootstrap replicates):\n", sep = "")
table <- do.call(cbind, x)
table <- signif(table, digits = digits)
table <- cbind(x = attr(x, "x"), as.data.frame(table))
colnames.grid <- expand.grid(c("low", "median", "high"), attr(x, "ret"))
colnames.vec <- paste(colnames.grid$Var2, colnames.grid$Var1, sep = ".")
colnames(table) <- c(attr(x, "input"), colnames.vec)
rownames(table) <- attr(x, "x")
print(table, row.names = length(attr(x, "ret")) > 1)
invisible(x)
}
print_dataline <- function(x) {
# Case / Controls call
if ("cases" %in% names(x$call) && "controls" %in% names(x$call)) {
cat("Data: ", length(x$controls), " controls ", x$direction, " ", length(x$cases), " cases.\n", sep = "")
} else {
if ("predictor.name" %in% names(x)) {
predictor.name <- x$predictor.name
} else if ("predictor" %in% names(x$call)) {
predictor.name <- as.character(x$call[match("predictor", names(x$call))])
} else {
predictor.name <- "(unknown)"
}
# Get response
if ("response.name" %in% names(x)) {
response.name <- x$response.name
} else if ("response" %in% names(x$call)) {
response.name <- as.character(x$call[match("response", names(x$call))])
} else if ("x" %in% names(x$call)) {
response.name <- as.character(x$call[match("x", names(x$call))])
} else {
response.name <- "(unknown)"
}
cat("Data: ", predictor.name, " in ", length(x$controls), " controls (", response.name, " ", x$levels[1], ") ", x$direction, " ", length(x$cases), " cases (", response.name, " ", x$levels[2], ").\n", sep = "")
}
}
pROC/R/venkatraman.R 0000644 0001762 0000144 00000011546 15040443562 013722 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
venkatraman.paired.test <- function(roc1, roc2, boot.n, ties.method = "first") {
X <- roc1$predictor
Y <- roc2$predictor
R <- rank(X, ties.method = ties.method)
S <- rank(Y, ties.method = ties.method)
D <- roc1$response # because roc1&roc2 are paired
E <- venkatraman.paired.stat(R, S, D, roc1$levels)
EP <- vapply(seq_len(boot.n), venkatraman.paired.permutation, FUN.VALUE = double(1L), R = R, S = S, D = D, levels = roc1$levels, ties.method = ties.method)
return(list(E, EP))
}
venkatraman.unpaired.test <- function(roc1, roc2, boot.n, ties.method = "first") {
X <- roc1$predictor
Y <- roc2$predictor
R <- rank(X, ties.method = ties.method)
S <- rank(Y, ties.method = ties.method)
D1 <- roc1$response
D2 <- roc2$response
mp <- (sum(D1 == roc1$levels[2]) + sum(D2 == roc2$levels[2])) / (length(D1) + length(D1)) # mixing proportion, kappa
E <- venkatraman.unpaired.stat(R, S, D1, D2, roc1$levels, roc2$levels, mp)
EP <- vapply(seq_len(boot.n), venkatraman.unpaired.permutation, FUN.VALUE = double(1L), R = R, S = S, D1 = D1, D2 = D2, levels1 = roc1$levels, levels2 = roc2$levels, mp = mp, ties.method = ties.method)
return(list(E, EP))
}
venkatraman.paired.permutation <- function(n, R, S, D, levels, ties.method) {
# Break ties
R2 <- R + runif(length(D)) - 0.5 # Add small amount of random but keep same mean
S2 <- S + runif(length(D)) - 0.5
# Permutation
q <- 1 - round(runif(length(D)))
R3 <- R2 * q + (1 - q) * S
S3 <- S2 * q + (1 - q) * R
return(venkatraman.paired.stat(rank(R3, ties.method = ties.method), rank(S3, ties.method = ties.method), D, levels))
}
venkatraman.unpaired.permutation <- function(n, R, S, D1, D2, levels1, levels2, mp, ties.method) {
# Break ties
R <- R + runif(length(D1)) - 0.5 # Add small amount of random but keep same mean
S <- S + runif(length(D2)) - 0.5
R.controls <- R[D1 == levels1[1]]
R.cases <- R[D1 == levels1[2]]
S.controls <- S[D2 == levels2[1]]
S.cases <- S[D2 == levels2[2]]
# Permutation
controls <- sample(c(R.controls, S.controls))
cases <- sample(c(R.cases, S.cases))
R[D1 == levels1[1]] <- controls[1:length(R.controls)]
S[D2 == levels2[1]] <- controls[(length(R.controls) + 1):length(controls)]
R[D1 == levels1[2]] <- cases[1:length(R.cases)]
S[D2 == levels2[2]] <- cases[(length(R.cases) + 1):length(cases)]
return(venkatraman.unpaired.stat(rank(R, ties.method = ties.method), rank(S, ties.method = ties.method), D1, D2, levels1, levels2, mp))
}
venkatraman.paired.stat <- function(R, S, D, levels) {
R.controls <- R[D == levels[1]]
R.cases <- R[D == levels[2]]
S.controls <- S[D == levels[1]]
S.cases <- S[D == levels[2]]
n <- length(D)
R.fn <- sapply(1:n, function(x) sum(R.cases <= x))
R.fp <- sapply(1:n, function(x) sum(R.controls > x))
S.fn <- sapply(1:n, function(x) sum(S.cases <= x))
S.fp <- sapply(1:n, function(x) sum(S.controls > x))
return(sum(abs((S.fn + S.fp) - (R.fn + R.fp))))
}
venkatraman.unpaired.stat <- function(R, S, D1, D2, levels1, levels2, mp) {
R.controls <- R[D1 == levels1[1]]
R.cases <- R[D1 == levels1[2]]
S.controls <- S[D2 == levels2[1]]
S.cases <- S[D2 == levels2[2]]
n <- length(D1)
m <- length(D2)
R.fx <- sapply(1:n, function(x) sum(R.cases <= x)) / length(R.cases)
R.gx <- sapply(1:n, function(x) sum(R.controls <= x)) / length(R.controls)
S.fx <- sapply(1:m, function(x) sum(S.cases <= x)) / length(S.cases)
S.gx <- sapply(1:m, function(x) sum(S.controls <= x)) / length(S.controls)
R.p <- mp * R.fx + (1 - mp) * R.gx
S.p <- mp * S.fx + (1 - mp) * S.gx
R.exp <- mp * R.fx + (1 - mp) * (1 - R.gx)
S.exp <- mp * S.fx + (1 - mp) * (1 - S.gx)
# Do the integration
x <- sort(c(R.p, S.p))
R.f <- approxfun(R.p, R.exp)
S.f <- approxfun(S.p, S.exp)
f <- function(x) abs(R.f(x) - S.f(x))
y <- f(x)
# trapezoid integration:
idx <- 2:length(x)
integral <- sum(((y[idx] + y[idx - 1]) * (x[idx] - x[idx - 1])) / 2, na.rm = TRUE) # remove NA that can appear in the borders
return(integral)
}
pROC/R/has.partial.auc.R 0000644 0001762 0000144 00000002462 15040443562 014365 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2011-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
has.partial.auc <- function(roc) {
UseMethod("has.partial.auc")
}
has.partial.auc.auc <- function(roc) {
if (is.null(roc)) {
return(NULL)
}
is.numeric(attr(roc, "partial.auc")) && length(attr(roc, "partial.auc") == 2)
}
has.partial.auc.smooth.roc <- function(roc) {
return(has.partial.auc.roc(roc))
}
has.partial.auc.roc <- function(roc) {
return(has.partial.auc.auc(roc$auc))
}
pROC/R/roc.utils.R 0000644 0001762 0000144 00000051727 15042617211 013336 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Helper functions for the ROC curves. These functions should not be called directly as they perform very specific tasks and do nearly no argument validity checks. Not documented in RD and not exported.
# returns a list of sensitivities (se) and specificities (sp) for the given data. Fast algorithm
roc_utils_perfs_all <- function(thresholds, controls, cases, direction) {
ncontrols <- length(controls)
ncases <- length(cases)
predictor <- c(controls, cases)
response <- c(rep(0, length(controls)), rep(1, length(cases)))
decr <- direction == "<"
predictor.order <- order(predictor, decreasing = decr)
predictor.sorted <- predictor[predictor.order]
response.sorted <- response[predictor.order]
tp <- cumsum(response.sorted == 1)
fp <- cumsum(response.sorted == 0)
se <- tp / ncases
sp <- (ncontrols - fp) / ncontrols
# filter duplicate thresholds
dups.pred <- rev(duplicated(rev(predictor.sorted)))
dups.sesp <- duplicated(se) & duplicated(sp)
dups <- dups.pred | dups.sesp
# Make sure we have the right length
if (sum(!dups) != length(thresholds) - 1) {
sessionInfo <- sessionInfo()
save(thresholds, controls, cases, direction, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("pROC: fast algorithm computed an incorrect number of sensitivities and specificities. Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", utils::packageDescription("pROC")$BugReports))
}
if (direction == "<") {
se <- rev(c(0, se[!dups]))
sp <- rev(c(1, sp[!dups]))
} else {
se <- c(0, se[!dups])
sp <- c(1, sp[!dups])
}
return(list(se = se, sp = sp))
}
roc_utils_fun_sesp <- function(...) {
warning("pROC::roc$fun.sesp is deprecated")
roc_utils_perfs_all(...)
}
# returns a vector with two elements, sensitivity and specificity, given the threshold at which to evaluate the performance, the values of controls and cases and the direction of the comparison, a character '>' or '<' as controls CMP cases
# sp <- roc_utils_perfs(...)[1,]
# se <- roc_utils_perfs(...)[2,]
roc_utils_perfs <- function(threshold, controls, cases, direction) {
if (direction == ">") {
tp <- sum(cases <= threshold)
tn <- sum(controls > threshold)
} else if (direction == "<") {
tp <- sum(cases >= threshold)
tn <- sum(controls < threshold)
}
# return(c(sp, se))
return(c(sp = tn / length(controls), se = tp / length(cases)))
}
# as roc_utils_perfs, but for densities
roc_utils_perfs_dens <- function(threshold, x, dens.controls, dens.cases, direction) {
if (direction == ">") {
tp <- sum(dens.cases[x <= threshold])
tn <- sum(dens.controls[x > threshold])
} else if (direction == "<") {
tp <- sum(dens.cases[x >= threshold])
tn <- sum(dens.controls[x < threshold])
}
# return(c(sp, se))
return(c(sp = tn / sum(dens.controls), se = tp / sum(dens.cases)))
}
# return the thresholds to evaluate in the ROC curve, given the 'predictor' values. Returns all unique values of 'predictor' plus 2 extreme values
roc_utils_thresholds <- function(predictor, direction) {
unique.candidates <- sort(unique(predictor))
thresholds1 <- (c(-Inf, unique.candidates) + c(unique.candidates, +Inf)) / 2
thresholds2 <- (c(-Inf, unique.candidates) / 2 + c(unique.candidates, +Inf) / 2)
thresholds <- ifelse(abs(thresholds1) > 1e100, thresholds2, thresholds1)
if (any(ties <- thresholds %in% predictor)) {
# If we get here, some thresholds are identical to the predictor
# This is caused by near numeric ties that caused the mean to equal
# one of the candidate
# We need to make sure we select the right threshold more carefully
if (direction == ">") {
# We have:
# tp <- sum(cases <= threshold)
# tn <- sum(controls > threshold)
# We need to make sure the selected threshold
# Corresponds to the lowest observation of the predictor
# Identify problematic thresholds
# rows <- which(ties)
for (tie.idx in which(ties)) {
if (thresholds[tie.idx] == unique.candidates[tie.idx - 1]) {
# We're already good, nothing to do
} else if (thresholds[tie.idx] == unique.candidates[tie.idx]) {
thresholds[tie.idx] <- unique.candidates[tie.idx - 1]
} else {
sessionInfo <- sessionInfo()
save(predictor, direction, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("Couldn't fix near ties in thresholds: %s, %s, %s, %s. Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", thresholds[tie.idx], unique.candidates[tie.idx - 1], unique.candidates[tie.idx], direction, utils::packageDescription("pROC")$BugReports))
}
}
} else if (direction == "<") {
# We have:
# tp <- sum(cases >= threshold)
# tn <- sum(controls < threshold)
# We need to make sure the selected threshold
# Corresponds to the highest observation of the predictor
# Identify the problematic thresholds:
# rows <- which(apply(o, 1, any))
for (tie.idx in which(ties)) {
if (thresholds[tie.idx] == unique.candidates[tie.idx - 1]) {
# Easy to fix: should be unique.candidates[tie.idx]
thresholds[tie.idx] <- unique.candidates[tie.idx]
} else if (thresholds[tie.idx] == unique.candidates[tie.idx]) {
# We're already good, nothing to do
} else {
sessionInfo <- sessionInfo()
save(predictor, direction, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("Couldn't fix near ties in thresholds: %s, %s, %s, %s. Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", thresholds[tie.idx], unique.candidates[tie.idx - 1], unique.candidates[tie.idx], direction, utils::packageDescription("pROC")$BugReports))
}
}
}
}
return(thresholds)
}
# Find all the local maximas of the ROC curve. Returns a logical vector
roc_utils_max_thresholds_idx <- function(thresholds, sp, se) {
reversed <- FALSE
if (is.unsorted(sp)) {
# make sure SP is sorted increasingly, and sort thresholds accordingly
thresholds <- rev(thresholds)
sp <- rev(sp)
se <- rev(se)
reversed <- TRUE
}
# TODO: find whether the duplicate check is still needed.
# Should have been fixed by passing only c(controls, cases)
# instead of whole 'predictor' to roc_utils_thresholds in roc.default
# but are there other potential issues like that?
dup <- duplicated(data.frame(sp, se))
thresholds <- thresholds[!dup]
sp <- sp[!dup]
se <- se[!dup]
# Find the local maximas
if (length(thresholds) == 1) {
local.maximas <- TRUE # let's consider that if there is only 1 point, we should print it.
} else if (length(thresholds) == 2) {
local.maximas <- c(se[1] > se[2], sp[2] > sp[1])
} else {
local.maximas <- se[1] > se[2]
for (i in 2:(length(thresholds) - 1)) {
if (sp[i] > sp[i - 1] & se[i] > se[i + 1]) {
local.maximas <- c(local.maximas, TRUE)
} else if (sp[i] > sp[i - 1] & se[i] == 0) {
local.maximas <- c(local.maximas, TRUE)
} else if (se[i] > se[i - 1] & sp[i] == 1) {
local.maximas <- c(local.maximas, TRUE)
} else {
local.maximas <- c(local.maximas, FALSE)
}
}
local.maximas <- c(local.maximas, sp[length(thresholds)] > sp[length(thresholds) - 1])
}
if (any(dup)) {
lms <- rep(FALSE, length(dup))
lms[!dup] <- local.maximas
local.maximas <- lms
}
if (reversed) {
rev(local.maximas)
}
# Remove +-Inf at the limits of the curve
# local.maximas <- local.maximas & is.finite(thresholds)
# Question: why did I do that? It breaks coords.roc when partial.auc contains only the extreme point
return(local.maximas)
}
detect.env.true <- function(x) {
value <- Sys.getenv(x)
if (value == "T" || value == "True" || value == "TRUE" || value == "true") {
return(TRUE)
} else {
return(FALSE)
}
}
# sort roc curve. Make sure specificities are increasing.
sort_roc <- function(roc) {
if (is.unsorted(roc$specificities)) {
roc$sensitivities <- rev(roc$sensitivities)
roc$specificities <- rev(roc$specificities)
roc$thresholds <- rev(roc$thresholds)
}
return(roc)
}
# sort smoothed roc curve. Make sure specificities are increasing.
sort_smooth_roc <- function(roc) {
if (is.unsorted(roc$specificities)) {
roc$sensitivities <- rev(roc$sensitivities)
roc$specificities <- rev(roc$specificities)
}
return(roc)
}
# The list of valid coordinate arguments, without 'thresholds'
roc.utils.valid.coords <- c(
"specificity", "sensitivity", "accuracy",
"tn", "tp", "fn", "fp",
"npv", "ppv", "fdr",
"fpr", "tpr", "tnr", "fnr",
"1-specificity", "1-sensitivity", "1-accuracy", "1-npv", "1-ppv",
"precision", "recall", "lr_pos", "lr_neg",
"youden", "closest.topleft"
)
# Arguments which can be returned by coords
# @param threshold: FALSE for smooth.roc where threshold isn't valid
roc_utils_match_coords_ret_args <- function(x, threshold = TRUE) {
valid.ret.args <- roc.utils.valid.coords
if (threshold) {
valid.ret.args <- c("threshold", valid.ret.args)
}
if ("all" %in% x) {
if (length(x) > 1) {
stop("ret='all' can't be used with other 'ret' options.")
}
x <- valid.ret.args
}
x <- replace(x, x == "topleft", "closest.topleft")
x <- replace(x, x == "t", "threshold")
x <- replace(x, x == "npe", "1-npv")
x <- replace(x, x == "ppe", "1-ppv")
return(match.arg(x, valid.ret.args, several.ok = TRUE))
}
# Arguments which can be used as input for coords
# @param threshold: FALSE for smooth.roc where threshold isn't valid
roc_utils_match_coords_input_args <- function(x, threshold = TRUE) {
valid.args <- roc.utils.valid.coords
if (threshold) {
valid.args <- c("threshold", valid.args)
}
x <- replace(x, x == "topleft", "closest.topleft")
x <- replace(x, x == "t", "threshold")
x <- replace(x, x == "npe", "1-npv")
x <- replace(x, x == "ppe", "1-ppv")
matched <- match.arg(x, valid.args, several.ok = FALSE)
# We only handle monotone coords
if (!coord.is.monotone[matched]) {
stop(sprintf("Coordinate '%s' is not monotone and cannot be used as input.", matched))
}
return(matched)
}
# Compute the min/max for partial AUC
# ... with an auc
roc_utils_min_partial_auc_auc <- function(auc) {
roc_utils_min_partial_auc(attr(auc, "partial.auc"), attr(auc, "percent"))
}
roc_utils_max_partial_auc_auc <- function(roc) {
roc_utils_max_partial_auc(attr(auc, "partial.auc"), attr(auc, "percent"))
}
# ... with partial.auc/percent
roc_utils_min_partial_auc <- function(partial.auc, percent) {
if (!identical(partial.auc, FALSE)) {
min <- sum(ifelse(percent, 100, 1) - partial.auc) * abs(diff(partial.auc)) / 2 / ifelse(percent, 100, 1)
} else {
min <- 0.5 * ifelse(percent, 100, 1)
}
return(min)
}
roc_utils_max_partial_auc <- function(partial.auc, percent) {
if (!identical(partial.auc, FALSE)) {
max <- abs(diff(partial.auc))
} else {
max <- 1 * ifelse(percent, 100, 1)
}
return(max)
}
# Checks if the
# Input: roc object
# Output: boolean, true the curve reaches 100%/100%, false otherwise
roc_utils_is_perfect_curve <- function(roc) {
best.point <- max(roc$sensitivities + roc$specificities) / ifelse(roc$percent, 100, 1)
return(abs(best.point - 2) < .Machine$double.eps^0.5) # or best.point == 2, with numerical tolerance
}
# Load package namespace 'pkg'.
# Input: package name
# Returns: TRUE upon success (or if the package was already loaded)
# Stops if the package can't be loaded
load.suggested.package <- function(pkg) {
if (requireNamespace(pkg)) {
return(TRUE)
} else if (interactive()) {
if (getRversion() < "3.5.0") { # utils::askYesNo not available
message(sprintf("Package %s not available, do you want to install it now?", pkg))
auto.install <- utils::menu(c("Yes", "No")) == 1
} else {
auto.install <- utils::askYesNo(sprintf("Package %s not available, do you want to install it now?", pkg))
}
if (isTRUE(auto.install)) {
utils::install.packages(pkg)
if (requireNamespace(pkg)) {
return(TRUE)
} else {
stop(sprintf("Installation of %s failed!", pkg))
}
}
}
stop(sprintf("Package '%s' not available.", pkg))
}
# Calculate coordinates
# @param roc: the roc curve, used to guess if data is in percent and number of cases and controls.
# @param thr, se, sp
# @param best.weights: see coords
# @return data.frame
roc_utils_calc_coords <- function(roc, thr, se, sp, best.weights) {
ncases <- ifelse(methods::is(roc, "smooth.roc"), length(attr(roc, "roc")$cases), length(roc$cases))
ncontrols <- ifelse(methods::is(roc, "smooth.roc"), length(attr(roc, "roc")$controls), length(roc$controls))
substr.percent <- ifelse(roc$percent, 100, 1)
tp <- se * ncases / substr.percent
fn <- ncases - tp
tn <- sp * ncontrols / substr.percent
fp <- ncontrols - tn
npv <- substr.percent * tn / (tn + fn)
ppv <- substr.percent * tp / (tp + fp)
# res <- matrix(NA, nrow = length(ret), ncol = length(se))
# if ("tp" %in% ret) {}
accuracy <- substr.percent * (tp + tn) / (ncases + ncontrols)
precision <- ppv
recall <- tpr <- se
fpr <- substr.percent - sp
tnr <- sp
fnr <- substr.percent * fn / (tp + fn)
fdr <- substr.percent * fp / (tp + fp)
youden <- roc_utils_optim_crit(se, sp, substr.percent, best.weights, "youden")
closest.topleft <- -roc_utils_optim_crit(se, sp, substr.percent, best.weights, "closest.topleft") / substr.percent
return(cbind(
threshold = thr,
sensitivity = se,
specificity = sp,
accuracy = accuracy,
tn = tn,
tp = tp,
fn = fn,
fp = fp,
npv = npv,
ppv = ppv,
tpr = tpr,
tnr = tnr,
fpr = fpr,
fnr = fnr,
fdr = fdr,
"1-specificity" = substr.percent - sp,
"1-sensitivity" = substr.percent - se,
"1-accuracy" = substr.percent - accuracy,
"1-npv" = substr.percent - npv,
"1-ppv" = substr.percent - ppv,
precision = precision,
recall = recall,
"lr_pos" = (se / substr.percent) / (1 - sp / substr.percent),
"lr_neg" = (1 - se / substr.percent) / (sp / substr.percent),
youden = youden,
closest.topleft = closest.topleft
))
}
# Match arbitrary user-supplied thresholds to the threshold of the ROC curve.
# We need to be careful to assign x to the right thresholds around exact data point
# values. This means this function cannot look at the ROC thresholds themselves
# but must instead use the predictor values to assess the thresholds exactly.
# Returns the indices of the thresholds x.
# @param roc: the roc curve
# @param x: the threshold to determine indices
# @return integer vector of indices along roc$thresholds/roc$se/roc$sp.
roc_utils_thr_idx <- function(roc, x) {
cut_points <- sort(unique(roc$predictor))
thr_idx <- rep(NA_integer_, length(x))
if (roc$direction == "<") {
cut_points <- c(cut_points, Inf)
j <- 1
o <- order(x)
for (i in seq_along(x)) {
t <- x[o[i]]
while (cut_points[j] < t) {
j <- j + 1
}
thr_idx[o[i]] <- j
}
} else {
cut_points <- c(rev(cut_points), -Inf)
j <- 1
o <- order(x, decreasing = TRUE)
for (i in seq_along(x)) {
t <- x[o[i]]
while (cut_points[j] > t) {
j <- j + 1
}
thr_idx[o[i]] <- j
}
}
return(thr_idx)
}
# Get optimal criteria Youden or Closest Topleft
# @param se, sp: the roc curve
# @param max: the maximum value, 1 or 100, based on percent. Namely ifelse(percent, 100, 1)
# @param weights: see coords(best.weights=)
# @param method: youden or closest.topleft coords(best.method=)
# @return numeric vector along roc$thresholds/roc$se/roc$sp.
roc_utils_optim_crit <- function(se, sp, max, weights, method) {
if (is.numeric(weights) && length(weights) == 2) {
r <- (1 - weights[2]) / (weights[1] * weights[2]) # r should be 1 by default
} else {
stop("'best.weights' must be a numeric vector of length 2")
}
if (weights[2] <= 0 || weights[2] >= 1) {
stop("prevalence ('best.weights[2]') must be in the interval ]0,1[.")
}
if (method == "youden") {
optim.crit <- se + r * sp
} else if (method == "closest.topleft" || method == "topleft") {
optim.crit <- -((max - se)^2 + r * (max - sp)^2)
}
return(optim.crit)
}
coord.is.monotone <- c(
"threshold" = TRUE,
"sensitivity" = TRUE,
"specificity" = TRUE,
"accuracy" = FALSE,
"tn" = TRUE,
"tp" = TRUE,
"fn" = TRUE,
"fp" = TRUE,
"npv" = FALSE,
"ppv" = FALSE,
"tpr" = TRUE,
"tnr" = TRUE,
"fpr" = TRUE,
"fnr" = TRUE,
"fdr" = FALSE,
"1-specificity" = TRUE,
"1-sensitivity" = TRUE,
"1-accuracy" = FALSE,
"1-npv" = FALSE,
"1-ppv" = FALSE,
"precision" = FALSE,
"recall" = TRUE,
"lr_pos" = FALSE,
"lr_neg" = FALSE,
"youden" = FALSE,
"closest.topleft" = FALSE
)
coord.is.decreasing <- c(
"threshold" = NA, # Depends on direction
"sensitivity" = TRUE,
"specificity" = FALSE,
"accuracy" = NA,
"tn" = FALSE,
"tp" = TRUE,
"fn" = FALSE,
"fp" = TRUE,
"npv" = NA,
"ppv" = NA,
"tpr" = TRUE,
"tnr" = FALSE,
"fpr" = TRUE,
"fnr" = FALSE,
"fdr" = NA,
"1-specificity" = TRUE,
"1-sensitivity" = FALSE,
"1-accuracy" = NA,
"1-npv" = NA,
"1-ppv" = NA,
"precision" = NA,
"recall" = TRUE,
"lr_pos" = NA,
"lr_neg" = NA,
"youden" = NA,
"closest.topleft" = NA
)
# Get response and predictor(s) from a formula.
# This function takes care of all the logic to handle
# weights, subset, na.action etc. It handles formulas with
# and without data. It rejects weights and certain na.actions.
# @param formula
# @param data
# @param data.missing
# @param call the call from the parent function
# @param ... the ... from the parent function
# @return a list with 3 elements: response (vector), predictor.names (character),
# predictors (data.frame).
roc_utils_extract_formula <- function(formula, data, data.missing, call, ...) {
# Get predictors (easy)
if (data.missing) {
predictors <- attr(terms(formula), "term.labels")
} else {
predictors <- attr(terms(formula, data = data), "term.labels")
}
indx <- match(c("formula", "data", "weights", "subset", "na.action"), names(call), nomatch = 0)
if (indx[1] == 0) {
stop("A formula argument is required")
}
# Keep the standard arguments and run them in model.frame
temp <- call[c(1, indx)]
temp[[1]] <- as.name("model.frame")
# Only na.pass and na.fail should be used
if (indx[5] != 0) {
na.action.value <- as.character(call[indx[5]])
if (!na.action.value %in% c("na.pass", "na.fail")) {
warning(paste0(
sprintf("Value %s of na.action is not supported ", na.action.value),
"and will break pairing in roc.test and are.paired. ",
"Please use 'na.rm = TRUE' instead."
))
}
} else {
temp$na.action <- "na.pass"
}
# If data is missing we have to "find" it
if (data.missing) {
m <- tryCatch(
{
# First try normally. This works if the formula refers to variables
# on the caller's environment or an attached database.
eval.parent(temp, n = 2)
},
error = function(cond) {
# If the function was called in a "with" call, the data is
# a few frames up. 7 and 5 look like magic numbers here...
# but they will change depending on the context and if the
# roc function was wrapped. So we start with 7 and walk down
# the frames until we find the data we want
frames <- sys.frames()
for (frame in frames[(length(frames) - 7):1]) {
temp$data <- frame
for (n in 5:9) {
# n controls where the given formula will be found.
# Here as well, 5-9 seem to be magic numbers
try(
{
return(eval.parent(temp, n = n))
},
silent = TRUE
)
}
}
# If we're here it means we didn't find anything.
# Stop with the initial message
stop(cond)
}
)
} else {
# Run model.frame in the parent
m <- eval.parent(temp, n = 2)
}
if (!is.null(model.weights(m))) stop("weights are not supported")
# Sanity checks
stopifnot(length(predictors) == ncol(m) - 1)
stopifnot(all.equal(model.response(m), m[[1]], check.attributes = FALSE))
return(list(
response.name = names(m)[1],
response = model.response(m),
predictor.names = names(m)[-1],
predictors = m[-1]
))
}
pROC/R/null.roc.R 0000644 0001762 0000144 00000000213 13607143106 013132 0 ustar ligges users # null.roc <- structure(list(percent = FALSE, sensitivities = c(1, 0), specificities = c(0, 1), auc = NULL, class = "auc"), class = "roc")
pROC/R/obuchowski.R 0000644 0001762 0000144 00000017405 15040443562 013570 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2011-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Formula 3 from Obuchowski 2004, p. 1123
# Variance of an AUC given kappa
var_theta_obuchowski <- function(theta, kappa) {
A <- qnorm(theta) * 1.414
(0.0099 * exp(-A^2 / 2)) * ((5 * A^2 + 8) + (A^2 + 8) / kappa)
}
# Formulas from Obuchowski 1997, table 1 p. 1531
expr1 <- function(A, B) {
exp(-A^2 / (2 * (1 + B^2)))
}
expr2 <- function(B) {
1 + B^2
}
expr3 <- function(cdagger1, cdagger2) {
pnorm(cdagger1) - pnorm(cdagger2)
}
expr4 <- function(cddagger1, cddagger2) {
exp(-cddagger1) - exp(-cddagger2)
}
cdagger <- function(A, B, FPRi) {
(qnorm(FPRi) + A * B * (1 + B^2)^(-1)) * (1 + B^2)^(1 / 2)
}
cddagger <- function(cdagger) {
cdagger^2 / 2
}
f.full <- function(A, B) {
expr1 <- expr1(A, B)
expr2 <- expr2(B)
expr1 * (2 * pi * expr2)^(-1 / 2)
}
f.partial <- function(A, B, FPR1, FPR2) {
cdagger1 <- cdagger(A, B, FPR1)
cdagger2 <- cdagger(A, B, FPR2)
expr1 <- expr1(A, B)
expr2 <- expr2(B)
expr3 <- expr3(cdagger1, cdagger2)
expr1 * (2 * pi * expr2)^(-1 / 2) * expr3
}
g.full <- function(A, B) {
expr1 <- expr1(A, B)
expr2 <- expr2(B)
-expr1 * A * B * (2 * pi * expr2^3)^(-1 / 2)
}
g.partial <- function(A, B, FPR1, FPR2) {
cdagger1 <- cdagger(A, B, FPR1)
cdagger2 <- cdagger(A, B, FPR2)
cddagger1 <- cddagger(cdagger1)
cddagger2 <- cddagger(cdagger2)
expr1 <- expr1(A, B)
expr2 <- expr2(B)
expr3 <- expr3(cdagger1, cdagger2)
expr4 <- expr4(cddagger1, cddagger2)
# WARNING: we have set (-expr4), in contradiction with Obuchowski paper
expr1 * (2 * pi * expr2)^(-1) * (-expr4) - A * B * expr1 * (2 * pi * expr2^3)^(-1 / 2) * expr3
}
# Variance of a ROC curve given a 'roc' object
var_roc_obuchowski <- function(roc) {
binormal <- smooth(roc, method = "binormal")$model
A <- unname(coefficients(binormal)[1])
B <- unname(coefficients(binormal)[2])
kappa <- length(roc$controls) / length(roc$cases)
if (!identical(attr(roc$auc, "partial.auc"), FALSE)) {
FPR1 <- 1 - attr(roc$auc, "partial.auc")[2]
FPR2 <- 1 - attr(roc$auc, "partial.auc")[1]
va <- var_params_obuchowski(A, B, kappa, FPR1, FPR2)
} else {
va <- var_params_obuchowski(A, B, kappa)
}
return(va)
}
# Variance of a ROC curve given the parameters
# Obuchowski 1997, formula 4 p. 1530
# A and B: params of the binormal ROC curve
# kappa: proportion controls / cases
# FPR1, FPR2: the bottom (1) or top (2) bounds of the pAUC interval
var_params_obuchowski <- function(A, B, kappa, FPR1, FPR2) {
if (!missing(FPR1) && !is.null(FPR1) && !missing(FPR1) && !is.null(FPR2)) {
f.partial(A, B, FPR1, FPR2)^2 * (1 + B^2 / kappa + A^2 / 2) + g.partial(A, B, FPR1, FPR2)^2 * B^2 * (1 + kappa) / (2 * kappa)
} else {
f.full(A, B)^2 * (1 + B^2 / kappa + A^2 / 2) + g.full(A, B)^2 * B^2 * (1 + kappa) / (2 * kappa)
}
}
# Covariance of 2 given 'roc' objects (under the alternative hypothesis)
cov_roc_obuchowski <- function(roc1, roc2) {
binormal1 <- smooth(roc1, method = "binormal")$model
A1 <- unname(coefficients(binormal1)[1])
B1 <- unname(coefficients(binormal1)[2])
binormal2 <- smooth(roc2, method = "binormal")$model
A2 <- unname(coefficients(binormal2)[1])
B2 <- unname(coefficients(binormal2)[2])
kappa <- length(roc1$controls) / length(roc1$cases)
ra <- cor(roc1$cases, roc2$cases)
rn <- cor(roc1$controls, roc2$controls)
if (!identical(attr(roc1$auc, "partial.auc"), FALSE)) {
FPR11 <- 1 - attr(roc1$auc, "partial.auc")[2]
FPR12 <- 1 - attr(roc1$auc, "partial.auc")[1]
FPR21 <- 1 - attr(roc2$auc, "partial.auc")[2]
FPR22 <- 1 - attr(roc2$auc, "partial.auc")[1]
co <- cov_params_obuchowski(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22)
} else {
co <- cov_params_obuchowski(A1, B1, A2, B2, rn, ra, kappa)
}
return(co)
}
# Covariance under the null hypothesis
# roc1 is taken as null
cov0.roc.obuchowski <- function(roc1, roc2) {
binormal <- smooth(roc, method = "binormal")$model
A <- unname(coefficients(binormal)[1])
B <- unname(coefficients(binormal)[2])
R <- length(roc1$controls) / length(roc1$cases)
ra <- cor(roc1$cases, roc2$cases)
rn <- cor(roc1$controls, roc2$controls)
if (!identical(attr(roc1$auc, "partial.auc"), FALSE)) {
FPR1 <- attr(roc1$auc, "partial.auc")[2]
FPR2 <- attr(roc1$auc, "partial.auc")[1]
co <- cov_params_obuchowski(A, B, A, B, rn, ra, kappa, FPR1, FPR2, FPR1, FPR2)
} else {
co <- cov_params_obuchowski(A, B, A, B, rn, ra, kappa)
}
return(co)
}
# Covariance of a ROC curve given the parameters
# Obuchowski 1997, formula 5 p. 1531
# (A|B)(1|2): A and B params of the binormal ROC curve
# rn, ra: correlation of the results in ROC curves 1 and 2 in controls (n) and cases (a) patients
# kappa: proportion controls / cases
# FPR(1|2)(1|2): the bounds of the pAUC interval:
# ***** ROC curve 1 or 2
# ***** bottom (1) or top (2) of the interval
cov_params_obuchowski <- function(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22) {
if (!missing(FPR11) && !is.null(FPR11) &&
!missing(FPR12) && !is.null(FPR12) &&
!missing(FPR21) && !is.null(FPR21) &&
!missing(FPR22) && !is.null(FPR22)) {
f1 <- f.partial(A1, B1, FPR11, FPR12)
f2 <- f.partial(A2, B2, FPR21, FPR22)
g1 <- g.partial(A1, B1, FPR11, FPR12)
g2 <- g.partial(A2, B2, FPR21, FPR22)
} else {
f1 <- f.full(A1, B1)
f2 <- f.full(A2, B2)
g1 <- g.full(A1, B1)
g2 <- g.full(A2, B2)
}
f1 * f2 * (ra + rn * B1 * B2 / kappa + ra^2 * A1 * A2 / 2) +
g1 * g2 * (B1 * B2 * (rn^2 + kappa * ra^2) / (2 * kappa)) +
f1 * g2 * (ra^2 * A1 * B2 / 2) + f2 * g1 * (ra^2 * A2 * B1 / 2)
}
# Variance of a difference between two ROC curves given the parameters
# Obuchowski 1997, formula 4 and 5 p. 1530--1531
# (A|B)(1|2): A and B params of the binormal ROC curve
# rn, ra: correlation of the results in ROC curves 1 and 2 in controls (n) and cases (a) patients
# kappa: proportion controls / cases
# FPR(1|2)(1|2): the bounds of the pAUC interval:
# ***** ROC curve 1 or 2
# ***** bottom (1) or top (2) of the interval
vardiff.params.obuchowski <- function(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22) {
var(A1, B1, kappa, FPR11, FPR12) + var(A2, B2, kappa, FPR21, FPR22) +
2 * cov(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22)
}
# Variance of a difference between two ROC curves given the parameters
# under the null hypothesis. ROC curve 1 is taken as null
# Obuchowski 1997, formula 4 and 5 p. 1530--1531
# (A|B)(1|2): A and B params of the binormal ROC curve
# rn, ra: correlation of the results in ROC curves 1 and 2 in controls (n) and cases (a) patients
# kappa: proportion controls / cases
# FPR(1|2)(1|2): the bounds of the pAUC interval:
# ***** ROC curve 1 or 2
# ***** bottom (1) or top (2) of the interval
vardiff0.params.obuchowski <- function(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22) {
2 * var(A1, B1, kappa, FPR11, FPR12) +
2 * cov(A1, B1, A2, B2, rn, ra, kappa, FPR11, FPR12, FPR21, FPR22)
}
pROC/R/smooth.R 0000644 0001762 0000144 00000026150 15040443562 012721 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
smooth <- function(...) {
UseMethod("smooth")
}
smooth.default <- function(...) {
stats::smooth(...)
}
smooth.smooth.roc <- function(smooth.roc, ...) {
roc <- attr(smooth.roc, "roc")
if (is.null(roc)) {
stop("Cannot smooth a ROC curve generated directly with numeric 'density.controls' and 'density.cases'.")
}
smooth.roc(roc, ...)
}
smooth.roc <- function(roc, method = c("binormal", "density", "fitdistr", "logcondens", "logcondens.smooth"), n = 512, bw = "nrd0",
density = NULL, density.controls = density, density.cases = density,
start = NULL, start.controls = start, start.cases = start,
reuse.auc = TRUE, reuse.ci = FALSE,
...) {
method <- match.arg(method)
if (is.ordered(roc$original.predictor) && (method == "density" || method == "fitidstr")) {
stop("ROC curves of ordered predictors can be smoothed only with binormal smoothing.")
}
if (method == "binormal") {
sesp <- smooth_roc_binormal(roc, n)
} else if (method == "fitdistr") {
sesp <- smooth_roc_fitdistr(roc, n, density.controls, density.cases, start.controls, start.cases, ...)
} else if (method == "density") {
sesp <- smooth_roc_density(roc, n, density.controls, density.cases, bw, ...)
} else if (method == "logcondens") {
sesp <- smooth_roc_logcondens(roc, n)
} else if (method == "logcondens.smooth") {
sesp <- smooth_roc_logcondens_smooth(roc, n)
} else {
stop(sprintf(
"Impossible smooth method value '%s'. Please report this bug to <%s>.",
method, utils::packageDescription("pROC")$BugReports
))
}
class(sesp) <- "smooth.roc"
sesp <- sort_smooth_roc(sesp) # sort se and sp
# anchor SE/SP at 0/100
sesp$specificities <- c(0, as.vector(sesp$specificities), ifelse(roc$percent, 100, 1))
sesp$sensitivities <- c(ifelse(roc$percent, 100, 1), as.vector(sesp$sensitivities), 0)
attr(sesp, "roc") <- roc # keep the original roc. May be useful in CI.
sesp$percent <- roc$percent # keep some basic roc specifications
sesp$direction <- roc$direction
sesp$call <- match.call()
# keep smoothing arguments (for print and bootstrap)
sesp$smoothing.args <- list(...)
sesp$smoothing.args$method <- method
sesp$smoothing.args$n <- n
sesp$smoothing.args$start.controls <- start.controls
sesp$smoothing.args$start.cases <- start.cases
sesp$smoothing.args$density.controls <- density.controls
sesp$smoothing.args$density.cases <- density.cases
sesp$smoothing.args$bw <- bw
# complete fit.controls/cases if a function was passed as densfun
if (method == "fitdistr") {
if (is.null(sesp$fit.controls$densfun)) {
if (missing(density.controls)) {
sesp$fit.controls$densfun <- deparse(substitute(density))
} else {
sesp$fit.controls$densfun <- deparse(substitute(density.controls))
}
}
if (is.null(sesp$fit.cases$densfun)) {
if (missing(density.cases)) {
sesp$fit.cases$densfun <- deparse(substitute(density))
} else {
sesp$fit.cases$densfun <- deparse(substitute(density.cases))
}
}
}
# if there was an auc and a ci, re-do them
if (!is.null(roc$auc) && reuse.auc) {
args <- attributes(roc$auc)
args$roc <- NULL
args$smooth.roc <- sesp
sesp$auc <- do.call("auc.smooth.roc", args)
}
if (!is.null(roc$ci) && reuse.ci) {
args <- attributes(roc$ci)
args$roc <- NULL
args$smooth.roc <- sesp
sesp$ci <- do.call(paste(class(roc$ci), "smooth.roc", sep = "."), args)
}
return(sesp)
}
smooth_roc_density <- function(roc, n, density.controls, density.cases, bw,
# catch args for density
cut = 3, adjust = 1, kernel = window, window = "gaussian",
percent = roc$percent, direction = roc$direction,
...) {
if (!is.numeric(density.controls) || !is.numeric(density.cases)) {
predictor <- c(roc$controls, roc$cases)
if (is.character(bw)) {
bw <- match.fun(paste("bw", bw, sep = "."))(predictor)
}
bw <- bw * adjust
from <- min(predictor) - (cut * bw)
to <- max(predictor) + (cut * bw)
}
if (mode(density.controls) == "function") {
density.controls <- density.controls(roc$controls, n = n, from = from, to = to, bw = bw, kernel = kernel, ...)
if (!is.numeric(density.controls)) {
if (is.list(density.controls) && !is.null(density.controls$y) && is.numeric(density.controls$y)) {
density.controls <- density.controls$y
} else {
stop("The 'density' function must return a numeric vector or a list with a 'y' item.")
}
}
} else if (is.null(density.controls)) {
density.controls <- suppressWarnings(density(roc$controls, n = n, from = from, to = to, bw = bw, kernel = kernel, ...))$y
} else if (!is.numeric(density.controls)) {
stop("'density.controls' must be either NULL, a function or numeric values of density (over the y axis).")
}
if (mode(density.cases) == "function") {
density.cases <- density.cases(roc$cases, n = n, from = from, to = to, bw = bw, kernel = kernel, ...)
if (!is.numeric(density.cases)) {
if (is.list(density.cases) && !is.null(density.cases$y) && is.numeric(density.cases$y)) {
density.cases <- density.cases$y
} else {
stop("The 'density' function must return a numeric vector or a list with a 'y' item.")
}
}
} else if (is.null(density.cases)) {
density.cases <- suppressWarnings(density(roc$cases, n = n, from = from, to = to, bw = bw, kernel = kernel, ...))$y
} else if (!is.numeric(density.cases)) {
stop("'density.cases' must be either NULL, a function or numeric values of density (over the y axis).")
}
if (length(density.controls) != length(density.cases)) {
stop("Length of 'density.controls' and 'density.cases' differ.")
}
perfs <- sapply((1:length(density.controls)) + .5, roc_utils_perfs_dens, x = (1:length(density.controls)) + .5, dens.controls = density.controls, dens.cases = density.cases, direction = direction)
return(list(
sensitivities = perfs[2, ] * ifelse(percent, 100, 1),
specificities = perfs[1, ] * ifelse(percent, 100, 1)
))
}
smooth_roc_binormal <- function(roc, n) {
df <- data.frame(sp = qnorm(roc$sp * ifelse(roc$percent, 1 / 100, 1)), se = qnorm(roc$se * ifelse(roc$percent, 1 / 100, 1)))
df <- df[apply(df, 1, function(x) all(is.finite(x))), ]
if (dim(df)[1] <= 1) { # ROC curve or with only 1 point
stop("ROC curve not smoothable (not enough points).")
}
model <- lm(sp ~ se, df)
if (any(is.na(model$coefficients[2]))) {
stop("ROC curve not smoothable (not enough points).")
}
se <- qnorm(seq(0, 1, 1 / (n - 1)))
sp <- predict(model, data.frame(se))
return(list(
sensitivities = pnorm(se) * ifelse(roc$percent, 100, 1),
specificities = pnorm(sp) * ifelse(roc$percent, 100, 1),
model = model
))
}
smooth_roc_fitdistr <- function(roc, n, densfun.controls, densfun.cases, start.controls, start.cases, ...) {
load.suggested.package("MASS")
densfuns.list <- list(
beta = "dbeta", cauchy = "dcauchy", "chi-squared" = "dchisq", exponential = "dexp", f = "df",
gamma = "dgamma", geometric = "dgeom", "log-normal" = "dlnorm", lognormal = "dlnorm",
logistic = "dlogis", "negative binomial" = "dnbinom", normal = "dnorm", poisson = "dpois",
t = "dt", weibull = "dweibull"
)
if (is.null(densfun.controls)) {
densfun.controls <- "normal"
} else if (is.character(densfun.controls)) {
densfun.controls <- match.arg(densfun.controls, names(densfuns.list))
}
if (is.null(densfun.cases)) {
densfun.cases <- "normal"
} else if (is.character(densfun.cases)) {
densfun.cases <- match.arg(densfun.cases, names(densfuns.list))
}
fit.controls <- MASS::fitdistr(roc$controls, densfun.controls, start.controls, ...)
fit.cases <- MASS::fitdistr(roc$cases, densfun.cases, start.cases, ...)
# store function name in fitting results
if (mode(densfun.controls) != "function") {
fit.controls$densfun <- densfun.controls
}
if (mode(densfun.cases) != "function") {
fit.cases$densfun <- densfun.cases
}
x <- seq(min(c(roc$controls, roc$cases)), max(c(roc$controls, roc$cases)), length.out = n)
# get the actual function name for do.call
if (is.character(densfun.controls)) {
densfun.controls <- match.fun(densfuns.list[[densfun.controls]])
}
if (is.character(densfun.cases)) {
densfun.cases <- match.fun(densfuns.list[[densfun.cases]])
}
# ... that should be passed to densfun
if (length(list(...)) > 0 && any(names(list(...)) %in% names(formals(densfun.controls)))) {
dots.controls <- list(...)[names(formals(densfun.controls))[match(names(list(...)), names(formals(densfun.controls)))]]
} else {
dots.controls <- list()
}
if (length(list(...)) > 0 && any(names(list(...)) %in% names(formals(densfun.cases)))) {
dots.cases <- list(...)[names(formals(densfun.cases))[match(names(list(...)), names(formals(densfun.cases)))]]
} else {
dots.cases <- list()
}
density.controls <- do.call(densfun.controls, c(list(x = x), fit.controls$estimate, dots.controls))
density.cases <- do.call(densfun.cases, c(list(x = x), fit.cases$estimate, dots.cases))
perfs <- sapply(x, roc_utils_perfs_dens, x = x, dens.controls = density.controls, dens.cases = density.cases, direction = roc$direction)
return(list(
sensitivities = perfs[2, ] * ifelse(roc$percent, 100, 1),
specificities = perfs[1, ] * ifelse(roc$percent, 100, 1),
fit.controls = fit.controls, fit.cases = fit.cases
))
}
smooth_roc_logcondens <- function(roc, n) {
load.suggested.package("logcondens")
sp <- seq(0, 1, 1 / (n - 1))
logcondens <- logcondens::logConROC(roc$cases, roc$controls, sp)
se <- logcondens$fROC
return(list(
sensitivities = se * ifelse(roc$percent, 100, 1),
specificities = (1 - sp) * ifelse(roc$percent, 100, 1),
logcondens = logcondens
))
}
smooth_roc_logcondens_smooth <- function(roc, n) {
load.suggested.package("logcondens")
sp <- seq(0, 1, 1 / (n - 1))
logcondens <- logcondens::logConROC(roc$cases, roc$controls, sp)
se <- logcondens$fROC.smooth
return(list(
sensitivities = se * ifelse(roc$percent, 100, 1),
specificities = (1 - sp) * ifelse(roc$percent, 100, 1),
logcondens = logcondens
))
}
pROC/R/roc.R 0000644 0001762 0000144 00000041547 15042617211 012176 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
roc <- function(...) {
UseMethod("roc")
}
roc.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
response <- roc.data$response
predictors <- roc.data$predictors
if (length(response) == 0) {
stop("Error in the formula: a response is required in a formula of type response~predictor.")
}
if (ncol(predictors) == 1) {
roc <- roc.default(response, predictors[, 1], ...)
roc$call <- match.call()
roc$predictor.name <- roc.data$predictor.names
roc$response.name <- roc.data$response.name
if (!is.null(roc$smooth)) {
attr(roc, "roc")$call <- roc$call
}
return(roc)
} else if (ncol(predictors) > 1) {
roclist <- lapply(roc.data$predictor.names, function(predictor, formula, m.data, call, ...) {
# Get one ROC
roc <- roc.default(response, m.data[[predictor]], ...)
# Update the call to reflect the parents
formula[3] <- call(predictor) # replace the predictor in formula
call$formula <- formula # Replace modified formula
roc$call <- call
roc$predictor.name <- predictor
roc$response.name <- roc.data$response.name
return(roc)
}, formula = formula, m.data = predictors, call = match.call(), ...)
# Set the list names
names(roclist) <- roc.data$predictor.names
return(roclist)
} else {
stop("Invalid formula:at least 1 predictor is required in a formula of type response~predictor.")
}
}
roc.data.frame <- function(data, response, predictor,
ret = c("roc", "coords", "all_coords"),
...) {
ret <- match.arg(ret)
if (is.character(substitute(response))) {
response_name <- response
} else {
response_name <- deparse(substitute(response))
}
if (is.character(substitute(predictor))) {
predictor_name <- predictor
} else {
predictor_name <- deparse(substitute(predictor))
}
if (any(!c(response_name, predictor_name) %in% colnames(data))) {
# Some column is not in data. This could be a genuine error or the user not aware or NSE and wants to use roc_ instead
warning("This method uses non-standard evaluation (NSE). Did you want to use the `roc_` function instead?")
}
r <- roc_(data, response_name, predictor_name, ret = ret, ...)
if (ret == "roc") {
r$call <- match.call()
}
return(r)
}
roc_ <- function(data, response, predictor,
ret = c("roc", "coords", "all_coords"),
...) {
ret <- match.arg(ret)
# Ensure the data contains the columns we need
# In case of an error we want to show the name of the data. If the function
# was called from roc.data.frame we want to deparse in that environment instead
if (sys.nframe() > 1 && deparse(sys.calls()[[sys.nframe() - 1]][[1]]) == "roc.data.frame") {
data_name <- deparse(substitute(data, parent.frame(n = 1)))
} else {
data_name <- deparse(substitute(data))
}
if (!response %in% colnames(data)) {
stop(sprintf("Column %s not present in data %s", response, data_name))
}
if (!predictor %in% colnames(data)) {
stop(sprintf("Column '%s' not present in data %s", predictor, data_name))
}
r <- roc(data[[response]], data[[predictor]], ...)
if (ret == "roc") {
r$call <- match.call()
return(r)
} else if (ret == "coords") {
co <- coords(r, x = "all", transpose = FALSE)
rownames(co) <- NULL
return(co)
} else if (ret == "all_coords") {
co <- coords(r, x = "all", ret = "all", transpose = FALSE)
rownames(co) <- NULL
return(co)
}
}
roc.default <- function(response, predictor,
controls, cases,
density.controls, density.cases,
# data interpretation
levels = base::levels(as.factor(response)), # precise the levels of the responses as c("control group", "positive group"). Can be used to ignore some response levels.
percent = FALSE, # Must sensitivities, specificities and AUC be reported in percent? Note that if TRUE, and you want a partial area, you must pass it in percent also (partial.area=c(100, 80))
na.rm = TRUE,
direction = c("auto", "<", ">"), # direction of the comparison. Auto: automatically define in which group the median is higher and take the good direction to have an AUC >= 0.5
algorithm = 2,
quiet = FALSE,
# what computation must be done
smooth = FALSE, # call smooth.roc on the current object
auc = TRUE, # call auc.roc on the current object
ci = FALSE, # call ci.roc on the current object
plot = FALSE, # call plot.roc on the current object
# disambiguate method/n for ci and smooth
smooth.method = "binormal",
smooth.n = 512,
ci.method = NULL,
# capture density for smooth.roc here (do not pass to graphical functions)
density = NULL,
# further arguments passed to plot, auc, ci, smooth.
...) {
# Check arguments
direction <- match.arg(direction)
# Response / Predictor
if (!missing(response) && !is.null(response) && !missing(predictor) && !is.null(predictor)) {
# Forbid case/controls
if ((!missing(cases) && !is.null(cases)) || (!missing(controls) && !is.null(controls))) {
stop("'cases/controls' argument incompatible with 'response/predictor'.")
}
# Forbid density
if ((!missing(density.cases) && !is.null(density.cases)) || (!missing(density.controls) && !is.null(density.controls))) {
stop("'density.*' arguments incompatible with 'response/predictor'.")
}
original.predictor <- predictor # store a copy of the original predictor (before converting ordered to numeric and removing NA)
original.response <- response # store a copy of the original predictor (before converting ordered to numeric)
# Validate levels
if (missing(levels)) {
if (length(levels) > 2) {
warning("'response' has more than two levels. Consider setting 'levels' explicitly or using 'multiclass.roc' instead")
levels <- levels[1:2]
} else if (length(levels) < 2) {
stop("'response' must have two levels")
}
ifelse(quiet, invisible, message)(sprintf("Setting levels: control = %s, case = %s", levels[1], levels[2]))
} else if (length(levels) != 2) {
stop("'levels' argument must have length 2")
}
# ensure predictor is numeric or ordered
if (!is.numeric(predictor)) {
if (is.ordered(predictor)) {
predictor <- tryCatch(
{
as.numeric(as.character(predictor))
},
warning = function(warn) {
warning("Ordered predictor converted to numeric vector. Threshold values will not correspond to values in predictor.")
return(as.numeric(predictor))
}
)
} else {
stop("Predictor must be numeric or ordered.")
}
}
if (is.matrix(predictor)) {
warning("Deprecated use a matrix as predictor. Unexpected results may be produced, please pass a numeric vector.")
}
if (is.matrix(response)) {
warning("Deprecated use a matrix as response. Unexpected results may be produced, please pass a vector or factor.")
}
# also make sure response and predictor are vectors of the same length
if (length(predictor) != length(response)) {
stop("Response and predictor must be vectors of the same length.")
}
# remove NAs if requested
if (na.rm) {
nas <- is.na(response) | is.na(predictor)
if (any(nas)) {
na.action <- grep(TRUE, nas)
class(na.action) <- "omit"
response <- response[!nas]
attr(response, "na.action") <- na.action
predictor <- predictor[!nas]
attr(predictor, "na.action") <- na.action
}
} else if (any(is.na(c(predictor[response == levels[1]], predictor[response == levels[2]], response)))) { # Unable to compute anything if there is any NA in the response or in the predictor data we want to consider !
return(NA)
}
splitted <- split(predictor, response)
controls <- splitted[[as.character(levels[1])]]
if (length(controls) == 0) {
stop("No control observation.")
}
cases <- splitted[[as.character(levels[2])]]
if (length(cases) == 0) {
stop("No case observation.")
}
# Remove patients not in levels
patients.in.levels <- response %in% levels
if (!all(patients.in.levels)) {
response <- response[patients.in.levels]
predictor <- predictor[patients.in.levels]
}
# Check infinities
if (any(which <- is.infinite(predictor))) {
warning("Infinite values(s) in predictor, cannot build a valid ROC curve. NaN returned instead.")
return(NaN)
}
}
# Cases / Controls
else if (!missing(cases) && !is.null(cases) && !missing(controls) && !is.null(controls)) {
# Forbid density
if ((!missing(density.cases) && !is.null(density.cases)) || (!missing(density.controls) && !is.null(density.controls))) {
stop("'density.*' arguments incompatible with 'response/predictor'.")
}
# remove nas
if (na.rm) {
if (any(is.na(controls))) {
controls <- na.omit(controls)
}
if (any(is.na(cases))) {
cases <- na.omit(cases)
}
} else if (any(is.na(c(controls, cases)))) { # Unable to compute anything if there is any NA in the data we want to consider !
return(NA)
}
# are there empty cats?
if (length(controls) == 0) {
stop("No control observation.")
}
if (length(cases) == 0) {
stop("No case observation.")
}
# check data consistency
if (is.ordered(cases)) {
if (is.ordered(controls)) {
if (identical(attr(cases, "levels"), attr(controls, "levels"))) {
# merge
original.predictor <- ordered(c(as.character(cases), as.character(controls)), levels = attr(controls, "levels"))
# Predictor, control and cases must be numeric from now on
predictor <- as.numeric(original.predictor)
controls <- as.numeric(controls)
cases <- as.numeric(cases)
} else {
stop("Levels of cases and controls differ.")
}
} else {
stop("Cases are of ordered type but controls are not.")
}
} else if (is.numeric(cases)) {
if (is.numeric(controls)) {
# build response/predictor
predictor <- c(controls, cases)
original.predictor <- predictor
} else {
stop("Cases are of numeric type but controls are not.")
}
} else {
stop("Cases and controls must be numeric or ordered.")
}
# Check infinities
if (any(which <- is.infinite(predictor))) {
warning("Infinite values(s) in predictor, cannot build a valid ROC curve. NaN returned instead.")
return(NaN)
}
response <- c(rep(0, length(controls)), rep(1, length(cases)))
original.response <- response
levels <- c(0, 1)
} else if (!missing(density.cases) && !is.null(density.cases) && !missing(density.controls) && !is.null(density.controls)) {
if (!is.numeric(density.cases) || !is.numeric(density.controls)) {
stop("'density.cases' and 'density.controls' must be numeric values of density (over the y axis).")
}
if (direction == "auto") {
dir <- "<"
} else {
dir <- direction
}
smooth.roc <- smooth_roc_density(density.controls = density.controls, density.cases = density.cases, percent = percent, direction = dir)
class(smooth.roc) <- "smooth.roc"
smooth.roc <- sort_smooth_roc(smooth.roc) # sort se and sp
# anchor SE/SP at 0/100
smooth.roc$specificities <- c(0, as.vector(smooth.roc$specificities), ifelse(percent, 100, 1))
smooth.roc$sensitivities <- c(ifelse(percent, 100, 1), as.vector(smooth.roc$sensitivities), 0)
smooth.roc$percent <- percent # keep some basic roc specifications
smooth.roc$direction <- direction
smooth.roc$call <- match.call()
if (auc) {
smooth.roc$auc <- auc(smooth.roc, ...)
if (direction == "auto" && smooth.roc$auc < roc_utils_min_partial_auc_auc(smooth.roc$auc)) {
smooth.roc <- roc.default(
density.controls = density.controls, density.cases = density.cases, levels = levels,
percent = percent, direction = ">", auc = auc, ci = ci, plot = plot, ...
)
smooth.roc$call <- match.call()
return(smooth.roc)
}
}
if (ci) {
warning("CI can not be computed with densities.")
}
if (plot) {
plot.roc(smooth.roc, ...)
}
return(smooth.roc)
} else {
stop("No valid data provided.")
}
if (direction == "auto" && median(controls) <= median(cases)) {
direction <- "<"
ifelse(quiet, invisible, message)("Setting direction: controls < cases")
} else if (direction == "auto" && median(controls) > median(cases)) {
direction <- ">"
ifelse(quiet, invisible, message)("Setting direction: controls > cases")
}
# smooth with densities, but only density was provided, not density.controls/cases
if (smooth) {
if (missing(density.controls)) {
density.controls <- density
}
if (missing(density.cases)) {
density.cases <- density
}
}
# Only support algorithm
if (algorithm != 2) {
warning("Ignoring algorithm=%s argument: since pROC 1.19, only algorithm 2 is available.")
}
roc <- roc_cc_nochecks(controls, cases,
percent = percent,
direction = direction,
smooth = smooth, density.cases = density.cases, density.controls = density.controls, smooth.method = smooth.method, smooth.n = smooth.n,
auc, ...
)
roc$call <- match.call()
if (smooth) {
attr(roc, "roc")$call <- roc$call
attr(roc, "roc")$original.predictor <- original.predictor
attr(roc, "roc")$original.response <- original.response
attr(roc, "roc")$predictor <- predictor
attr(roc, "roc")$response <- response
attr(roc, "roc")$levels <- levels
}
roc$original.predictor <- original.predictor
roc$original.response <- original.response
roc$predictor <- predictor
roc$response <- response
roc$levels <- levels
if (auc) {
attr(roc$auc, "roc") <- roc
}
# compute CI
if (ci) {
roc$ci <- ci(roc, method = ci.method, ...)
}
# plot
if (plot) {
plot.roc(roc, ...)
}
# return roc
return(roc)
}
# Creates a ROC object from response, predictor, ... without argument checking. Not to be exposed to the end user
roc_rp_nochecks <- function(response, predictor, levels, ...) {
splitted <- split(predictor, response)
controls <- splitted[[as.character(levels[1])]]
if (length(controls) == 0) {
stop("No control observation.")
}
cases <- splitted[[as.character(levels[2])]]
if (length(cases) == 0) {
stop("No case observation.")
}
roc_cc_nochecks(controls, cases, ...)
}
# Creates a ROC object from controls, cases, ... without argument checking. Not to be exposed to the end user
roc_cc_nochecks <- function(controls, cases, percent, direction, smooth, smooth.method, smooth.n, auc, ...) {
# create the roc object
roc <- list()
class(roc) <- "roc"
roc$percent <- percent
# compute SE / SP
thresholds <- roc_utils_thresholds(c(controls, cases), direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = direction)
se <- perfs$se
sp <- perfs$sp
if (percent) {
se <- se * 100
sp <- sp * 100
}
# store the computations in the roc object
roc$sensitivities <- se
roc$specificities <- sp
roc$thresholds <- thresholds
roc <- sort_roc(roc)
roc$direction <- direction
roc$cases <- cases
roc$controls <- controls
roc$fun.sesp <- roc_utils_fun_sesp
if (smooth) {
roc <- smooth.roc(roc, method = smooth.method, n = smooth.n, ...)
}
# compute AUC
if (auc) {
roc$auc <- auc.roc(roc, ...)
}
return(roc)
}
pROC/R/roc.utils.percent.R 0000644 0001762 0000144 00000012121 15040443562 014762 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Helper functions to safely convert ROC objects from percent=TRUE to percent=FALSE
# and inversely. These are internal and experimental. They shouldn't be exposed
# to the end user.
# Returns a ROC curve with percent=FALSE
roc_utils_unpercent <- function(x) {
UseMethod("roc_utils_unpercent")
}
roc_utils_unpercent.roc <- function(x) {
if (x$percent) {
if (!is.null(x$auc)) {
x$auc <- roc_utils_unpercent(x$auc)
}
x$sensitivities <- x$sensitivities / 100
x$specificities <- x$specificities / 100
x$percent <- FALSE
if (!is.null(x$call)) {
x$call$percent <- FALSE
}
if (!is.null(x$ci)) {
x$ci <- roc_utils_unpercent(x$ci)
}
}
return(x)
}
roc_utils_unpercent.auc <- function(x) {
if (attr(x, "percent")) {
newx <- x / 100
attributes(newx) <- attributes(x)
x <- newx
attr(x, "percent") <- FALSE
if (is.numeric(attr(x, "partial.auc"))) {
attr(x, "partial.auc") <- attr(x, "partial.auc") / 100
}
if (!is.null(attr(x, "roc"))) {
attr(x, "roc") <- roc_utils_unpercent(attr(x, "roc"))
}
}
return(x)
}
roc_utils_unpercent.ci.auc <- function(x) {
if (attr(attr(x, "auc"), "percent")) {
x[] <- x / 100
attr(x, "auc") <- roc_utils_unpercent(attr(x, "auc"))
}
return(x)
}
roc_utils_unpercent.ci.thresholds <- function(x) {
if (attr(x, "roc")$percent) {
x$sensitivity[] <- x$sensitivity / 100
x$specificity[] <- x$specificity / 100
attr(x, "roc") <- roc_utils_unpercent(attr(x, "roc"))
}
return(x)
}
roc_utils_unpercent.ci.sp <- function(x) {
if (attr(x, "roc")$percent) {
x[] <- x / 100
attr(x, "sensitivities") <- attr(x, "sensitivities") / 100
rownames(x) <- attr(x, "sensitivities")
attr(x, "roc") <- roc_utils_unpercent(attr(x, "roc"))
}
return(x)
}
roc_utils_unpercent.ci.se <- function(x) {
if (attr(x, "roc")$percent) {
x[] <- x / 100
attr(x, "specificities") <- attr(x, "specificities") / 100
rownames(x) <- attr(x, "specificities")
attr(x, "roc") <- roc_utils_unpercent(attr(x, "roc"))
}
return(x)
}
roc_utils_unpercent.ci.coords <- function(x) {
stop("Cannot convert ci.coords object to percent = FALSE")
}
# Returns a ROC curve with percent=TRUE
roc_utils_topercent <- function(x) {
UseMethod("roc_utils_topercent")
}
roc_utils_topercent.roc <- function(x) {
if (!x$percent) {
if (!is.null(x$auc)) {
x$auc <- roc_utils_topercent(x$auc)
}
x$sensitivities <- x$sensitivities * 100
x$specificities <- x$specificities * 100
x$percent <- TRUE
if (!is.null(x$call)) {
x$call$percent <- TRUE
}
if (!is.null(x$ci)) {
x$ci <- roc_utils_topercent(x$ci)
}
}
return(x)
}
roc_utils_topercent.auc <- function(x) {
if (!attr(x, "percent")) {
newx <- x * 100
attributes(newx) <- attributes(x)
x <- newx
attr(x, "percent") <- TRUE
if (is.numeric(attr(x, "partial.auc"))) {
attr(x, "partial.auc") <- attr(x, "partial.auc") * 100
}
if (!is.null(attr(x, "roc"))) {
attr(x, "roc") <- roc_utils_topercent(attr(x, "roc"))
}
}
return(x)
}
roc_utils_topercent.ci.auc <- function(x) {
if (!attr(attr(x, "auc"), "percent")) {
x[] <- x * 100
attr(x, "auc") <- roc_utils_topercent(attr(x, "auc"))
}
return(x)
}
roc_utils_topercent.ci.thresholds <- function(x) {
if (!attr(x, "roc")$percent) {
x$sensitivity[] <- x$sensitivity * 100
x$specificity[] <- x$specificity * 100
attr(x, "roc") <- roc_utils_topercent(attr(x, "roc"))
}
return(x)
}
roc_utils_topercent.ci.sp <- function(x) {
if (!attr(x, "roc")$percent) {
x[] <- x * 100
attr(x, "sensitivities") <- attr(x, "sensitivities") * 100
rownames(x) <- paste(attr(x, "sensitivities"), "%", sep = "")
attr(x, "roc") <- roc_utils_topercent(attr(x, "roc"))
}
return(x)
}
roc_utils_topercent.ci.se <- function(x) {
if (!attr(x, "roc")$percent) {
x[] <- x * 100
attr(x, "specificities") <- attr(x, "specificities") * 100
rownames(x) <- paste(attr(x, "specificities"), "%", sep = "")
attr(x, "roc") <- roc_utils_topercent(attr(x, "roc"))
}
return(x)
}
roc_utils_topercent.ci.coords <- function(x) {
stop("Cannot convert ci.coords object to percent = TRUE")
}
pROC/R/coords.R 0000644 0001762 0000144 00000051005 15040443562 012676 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
coords <- function(...) {
UseMethod("coords")
}
coords.auc <- function(auc,
...) {
roc <- attr(auc, "roc")
roc$auc <- auc
return(coords(roc))
}
coords.smooth.roc <- function(smooth.roc,
x,
input,
ret = c("specificity", "sensitivity"),
ignore.partial.auc = FALSE,
as.list = FALSE,
drop = TRUE,
best.method = c("youden", "closest.topleft"),
best.weights = c(1, 0.5),
transpose = FALSE,
as.matrix = FALSE,
...) {
# make sure x was provided
if (missing(x) || is.null(x) || (length(x) == 0 && !is.numeric(x))) {
x <- "all"
} else if (length(x) == 0 && is.numeric(x)) {
stop("Numeric 'x' has length 0")
}
# Warn about deprecated stuff
if (!missing(drop) && drop) {
warning("'drop' is deprecated and will be removed in a future version.")
}
if (!missing(as.matrix) && as.matrix) {
warning("'as.matrix' is deprecated and will be removed in a future version.")
}
if (transpose) {
warning("'transpose=TRUE' is deprecated. Only 'transpose=FALSE' will be allowed in a future version.")
}
if (!missing(as.list) && as.list) {
warning("'as.list' is deprecated and will be removed in a future version.")
}
# match return
ret <- roc_utils_match_coords_ret_args(ret, threshold = FALSE)
if (is.character(x)) {
x <- match.arg(x, c("all", "best")) # no thresholds in smoothed roc: only best or all are possible
partial.auc <- attr(smooth.roc$auc, "partial.auc")
if (x == "all") {
# Pre-filter thresholds based on partial.auc
if (is.null(smooth.roc$auc) || identical(partial.auc, FALSE) || ignore.partial.auc) {
se <- smooth.roc$sensitivities
sp <- smooth.roc$specificities
} else {
if (attr(smooth.roc$auc, "partial.auc.focus") == "sensitivity") {
se <- smooth.roc$sensitivities[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]]
sp <- smooth.roc$specificities[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]]
partial.auc.limits <- attr(smooth.roc$auc, "partial.auc")
if (!partial.auc.limits[1] %in% se) {
se <- c(partial.auc.limits[1], se)
sp <- c(coords(smooth.roc, x = partial.auc.limits[1], input = "sensitivity", ret = "specificity")[1, 1], sp)
}
if (!partial.auc.limits[2] %in% se) {
se <- c(se, partial.auc.limits[2])
sp <- c(sp, coords(smooth.roc, x = partial.auc.limits[2], input = "sensitivity", ret = "specificity")[1, 1])
}
} else {
se <- smooth.roc$sensitivities[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]]
sp <- smooth.roc$specificities[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]]
partial.auc.limits <- attr(smooth.roc$auc, "partial.auc")
if (!partial.auc.limits[1] %in% sp) {
se <- c(se, coords(smooth.roc, x = partial.auc.limits[1], input = "specificity", ret = "sensitivity")[1, 1])
sp <- c(sp, partial.auc.limits[1])
}
if (!partial.auc.limits[2] %in% sp) {
se <- c(coords(smooth.roc, x = partial.auc.limits[2], input = "specificity", ret = "sensitivity")[1, 1], se)
sp <- c(partial.auc.limits[2], sp)
}
}
}
if (length(se) == 0) {
warning("No coordinates found, returning NULL. This is possibly cased by a too small partial AUC interval.")
return(NULL)
}
if (any(!ret %in% c("specificity", "sensitivity"))) {
# Deduce additional tn, tp, fn, fp, npv, ppv
res <- roc_utils_calc_coords(smooth.roc, NA, se, sp, best.weights)
} else {
res <- cbind(
specificity = sp,
sensitivity = se
)
}
} else {
# cheat: allow the user to pass "topleft"
best.method <- match.arg(best.method[1], c("youden", "closest.topleft", "topleft"))
if (best.method == "topleft") {
best.method <- "closest.topleft"
}
optim.crit <- roc_utils_optim_crit(
smooth.roc$sensitivities, smooth.roc$specificities,
ifelse(smooth.roc$percent, 100, 1),
best.weights, best.method
)
if (is.null(smooth.roc$auc) || identical(partial.auc, FALSE) || ignore.partial.auc) {
se <- smooth.roc$sensitivities[optim.crit == max(optim.crit)]
sp <- smooth.roc$specificities[optim.crit == max(optim.crit)]
optim.crit <- optim.crit[optim.crit == max(optim.crit)]
} else {
if (attr(smooth.roc$auc, "partial.auc.focus") == "sensitivity") {
optim.crit.partial <- (optim.crit)[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]]
se <- smooth.roc$sensitivities[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
sp <- smooth.roc$specificities[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
optim.crit <- optim.crit[smooth.roc$sensitivities <= partial.auc[1] & smooth.roc$sensitivities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
} else {
optim.crit.partial <- (optim.crit)[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]]
se <- smooth.roc$sensitivities[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
sp <- smooth.roc$specificities[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
optim.crit <- optim.crit[smooth.roc$specificities <= partial.auc[1] & smooth.roc$specificities >= partial.auc[2]][optim.crit.partial == max(optim.crit.partial)]
}
}
if (any(!ret %in% c("specificity", "sensitivity", best.method))) {
# Deduce additional tn, tp, fn, fp, npv, ppv
res <- roc_utils_calc_coords(smooth.roc, NA, se, sp, best.weights)
} else {
res <- cbind(
specificity = sp,
sensitivity = se,
best.method = ifelse(best.method == "youden", 1, -1) * optim.crit
)
colnames(res)[3] <- best.method
}
}
if (as.list) {
warning("'as.list' is deprecated and will be removed in a future version.")
list <- apply(t(res)[ret, , drop = FALSE], 2, as.list)
if (drop == TRUE && length(x) == 1) {
return(list[[1]])
}
return(list)
} else if (transpose) {
rownames(res) <- NULL
return(t(res)[ret, , drop = drop])
} else {
if (missing(drop)) {
drop <- FALSE
}
if (!as.matrix) {
res <- as.data.frame(res)
}
return(res[, ret, drop = drop])
}
}
# Adjust drop for downstream call
if (missing(drop) && !transpose) {
drop <- FALSE
}
# match input
input <- roc_utils_match_coords_input_args(input, threshold = FALSE)
# use coords.roc
smooth.roc$thresholds <- rep(NA, length(smooth.roc$specificities))
return(coords.roc(smooth.roc, x, input, ret, as.list, drop,
transpose = transpose, as.matrix = as.matrix, ...
))
}
coords.roc <- function(roc,
x,
input = "threshold",
ret = c("threshold", "specificity", "sensitivity"),
ignore.partial.auc = FALSE,
as.list = FALSE,
drop = TRUE,
best.method = c("youden", "closest.topleft"),
best.weights = c(1, 0.5),
transpose = FALSE,
as.matrix = FALSE,
...) {
# make sure x was provided
if (missing(x) || is.null(x) || (length(x) == 0 && !is.numeric(x))) {
x <- "all"
} else if (length(x) == 0 && is.numeric(x)) {
stop("Numeric 'x' has length 0")
}
# Warn about deprecated stuff
if (!missing(drop) && drop) {
warning("'drop' is deprecated and will be removed in a future version.")
}
if (!missing(as.matrix) && as.matrix) {
warning("'as.matrix' is deprecated and will be removed in a future version.")
}
if (transpose) {
warning("'transpose=TRUE' is deprecated. Only 'transpose=FALSE' will be allowed in a future version.")
}
if (!missing(as.list) && as.list) {
warning("'as.list' is deprecated and will be removed in a future version.")
}
# match input
input <- roc_utils_match_coords_input_args(input)
# match return
ret <- roc_utils_match_coords_ret_args(ret)
# make sure the sort of roc is correct
roc <- sort_roc(roc)
if (is.character(x)) {
x <- match.arg(x, c("all", "local maximas", "best"))
partial.auc <- attr(roc$auc, "partial.auc")
if (x == "all") {
# Pre-filter thresholds based on partial.auc
if (is.null(roc$auc) || identical(partial.auc, FALSE) || ignore.partial.auc) {
se <- roc$sensitivities
sp <- roc$specificities
thres <- roc$thresholds
} else {
if (attr(roc$auc, "partial.auc.focus") == "sensitivity") {
se <- roc$sensitivities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
sp <- roc$specificities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
thres <- roc$thresholds[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
partial.auc.limits <- attr(roc$auc, "partial.auc")
if (!partial.auc.limits[1] %in% se) {
se <- c(partial.auc.limits[1], se)
sp <- c(coords(roc, x = partial.auc.limits[1], input = "sensitivity", ret = "specificity")[1, 1], sp)
thres <- c(NA, thres)
}
if (!partial.auc.limits[2] %in% se) {
se <- c(se, partial.auc.limits[2])
sp <- c(sp, coords(roc, x = partial.auc.limits[2], input = "sensitivity", ret = "specificity")[1, 1])
thres <- c(thres, NA)
}
} else {
se <- roc$sensitivities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
sp <- roc$specificities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
thres <- roc$thresholds[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
partial.auc.limits <- attr(roc$auc, "partial.auc")
if (!partial.auc.limits[1] %in% sp) {
se <- c(se, coords(roc, x = partial.auc.limits[1], input = "specificity", ret = "sensitivity")[1, 1])
sp <- c(sp, partial.auc.limits[1])
thres <- c(thres, NA)
}
if (!partial.auc.limits[2] %in% sp) {
se <- c(coords(roc, x = partial.auc.limits[2], input = "specificity", ret = "sensitivity")[1, 1], se)
sp <- c(partial.auc.limits[2], sp)
thres <- c(NA, thres)
}
}
}
if (length(thres) == 0) {
warning("No coordinates found, returning NULL. This is possibly cased by a too small partial AUC interval.")
return(NULL)
}
res <- cbind(
threshold = thres,
specificity = sp,
sensitivity = se
)
} else if (x == "local maximas") {
# Pre-filter thresholds based on partial.auc
if (is.null(roc$auc) || identical(partial.auc, FALSE) || ignore.partial.auc) {
se <- roc$sensitivities
sp <- roc$specificities
thres <- roc$thresholds
} else {
if (attr(roc$auc, "partial.auc.focus") == "sensitivity") {
se <- roc$sensitivities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
sp <- roc$specificities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
thres <- roc$thresholds[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
} else {
se <- roc$sensitivities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
sp <- roc$specificities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
thres <- roc$thresholds[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
}
}
if (length(thres) == 0) {
warning("No coordinates found, returning NULL. This is possibly cased by a too small partial AUC interval.")
return(NULL)
}
lm.idx <- roc_utils_max_thresholds_idx(thres, sp = sp, se = se)
res <- cbind(
threshold = thres[lm.idx],
specificity = sp[lm.idx],
sensitivity = se[lm.idx]
)
} else { # x == "best"
# cheat: allow the user to pass "topleft"
best.method <- match.arg(best.method[1], c("youden", "closest.topleft", "topleft"))
if (best.method == "topleft") {
best.method <- "closest.topleft"
}
optim.crit <- roc_utils_optim_crit(
roc$sensitivities, roc$specificities,
ifelse(roc$percent, 100, 1),
best.weights, best.method
)
# Filter thresholds based on partial.auc
if (is.null(roc$auc) || identical(partial.auc, FALSE) || ignore.partial.auc) {
se <- roc$sensitivities[optim.crit == max(optim.crit)]
sp <- roc$specificities[optim.crit == max(optim.crit)]
thres <- roc$thresholds[optim.crit == max(optim.crit)]
optim.crit <- optim.crit[optim.crit == max(optim.crit)]
} else {
if (attr(roc$auc, "partial.auc.focus") == "sensitivity") {
optim.crit <- (optim.crit)[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]]
se <- roc$sensitivities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]][optim.crit == max(optim.crit)]
sp <- roc$specificities[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]][optim.crit == max(optim.crit)]
thres <- roc$thresholds[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]][optim.crit == max(optim.crit)]
optim.crit <- optim.crit[roc$sensitivities <= partial.auc[1] & roc$sensitivities >= partial.auc[2]][optim.crit == max(optim.crit)]
} else {
optim.crit <- (optim.crit)[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]]
se <- roc$sensitivities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]][optim.crit == max(optim.crit)]
sp <- roc$specificities[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]][optim.crit == max(optim.crit)]
thres <- roc$thresholds[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]][optim.crit == max(optim.crit)]
optim.crit <- optim.crit[roc$specificities <= partial.auc[1] & roc$specificities >= partial.auc[2]][optim.crit == max(optim.crit)]
}
}
if (length(thres) == 0) {
warning("No coordinates found, returning NULL. This is possibly cased by a too small partial AUC interval.")
return(NULL)
}
res <- cbind(
threshold = thres,
specificity = sp,
sensitivity = se,
best.method = ifelse(best.method == "youden", 1, -1) * optim.crit
)
colnames(res)[4] <- best.method
}
} else if (is.numeric(x)) {
if (input == "threshold") {
thr_idx <- roc_utils_thr_idx(roc, x)
res <- cbind(
threshold = x, # roc$thresholds[thr_idx], # user-supplied vs ours.
specificity = roc$specificities[thr_idx],
sensitivity = roc$sensitivities[thr_idx]
)
} else {
# Arbitrary coord given in input.
# We could be tempted to use all_coords directly.
# However any non monotone coordinate in ret will be inaccurate
# when interpolated. Therefore it is safer to only interpolate
# se and sp and re-calculate the remaining coords later.
res <- cbind(
threshold = rep(NA, length(x)),
sensitivity = rep(NA, length(x)),
specificity = rep(NA, length(x))
)
if (input %in% c("sensitivity", "specificity")) {
# Shortcut slow roc_utils_calc_coords
se <- roc$sensitivities
sp <- roc$specificities
if (methods::is(roc, "smooth.roc")) {
thr <- rep(NA, length(roc$sensitivities))
} else {
thr <- roc$thresholds
}
if (input == "sensitivity") {
input_values <- se
} else {
input_values <- sp
}
} else {
all_coords <- roc_utils_calc_coords(roc, rep(NA, length(roc$sensitivities)), roc$sensitivities, roc$specificities, best.weights)
input_values <- all_coords[, input]
se <- all_coords[, "sensitivity"]
sp <- all_coords[, "specificity"]
thr <- all_coords[, "threshold"]
}
for (i in seq_along(x)) {
value <- x[i]
if (value < min(input_values) || value > max(input_values)) {
stop(sprintf(
"Input %s (%s) not in range (%s-%s)", input, value,
min(input_values), max(input_values)
))
}
idx <- which(input_values == value)
if (length(idx) > 1) {
# More than one to pick from. Need to take best
# according to sorting
if (coord.is.decreasing[input]) {
idx <- idx[length(idx)] # last
} else {
idx <- idx[1] # first
}
}
if (length(idx) == 1) {
# Exactly one to pick from
res[i, ] <- c(thr[idx], se[idx], sp[idx])
} else {
# Need to interpolate
if (coord.is.decreasing[input]) {
idx.next <- match(TRUE, input_values < value)
} else {
idx.next <- match(TRUE, input_values > value)
}
proportion <- (value - input_values[idx.next]) / (input_values[idx.next - 1] - input_values[idx.next])
int.se <- se[idx.next] + proportion * (se[idx.next - 1] - se[idx.next])
int.sp <- sp[idx.next] + proportion * (sp[idx.next - 1] - sp[idx.next])
res[i, 2:3] <- c(int.se, int.sp)
}
}
}
} else {
stop("'x' must be a numeric or character vector.")
}
if (any(!ret %in% colnames(res))) {
# Deduce additional tn, tp, fn, fp, npv, ppv
res <- roc_utils_calc_coords(roc, res[, "threshold"], res[, "sensitivity"], res[, "specificity"], best.weights)
}
if (as.list) {
list <- apply(t(res)[ret, , drop = FALSE], 2, as.list)
if (drop == TRUE && length(x) == 1) {
return(list[[1]])
}
return(list)
} else if (transpose) {
rownames(res) <- NULL
return(t(res)[ret, , drop = drop])
} else {
# HACK:
# We need an exception for r4lineups that will keep the old drop = TRUE
# behavior, until r4lineups gets updated. This is an ugly hack but allows
# us to switch to a better drop = FALSE for everyone else
if (missing(drop)) {
if (sys.nframe() > 2 &&
length(deparse(sys.call(-2))) == 1 &&
deparse(sys.call(-2)) == "make_rocdata(df_confacc)" &&
length(deparse(sys.call(-1))) == 1 && (
deparse(sys.call(-1)) == 'coords(rocobj, "all", ret = c("tp"))' ||
deparse(sys.call(-1)) == 'coords(rocobj, "all", ret = "fp")'
)) {
# We're in r4lineups
drop <- TRUE
} else {
drop <- FALSE
}
}
if (!as.matrix) {
res <- as.data.frame(res)
}
return(res[, ret, drop = drop])
}
}
pROC/R/ci.coords.R 0000644 0001762 0000144 00000020772 15040443562 013277 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci.coords <- function(...) {
UseMethod("ci.coords")
}
ci.coords.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci.coords'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.coords(roc(response, predictor, ci = FALSE, ...), ...)
}
ci.coords.default <- function(response, predictor, ...) {
if (methods::is(response, "multiclass.roc") || methods::is(response, "multiclass.auc")) {
stop("'ci.coords' not available for multiclass ROC curves.")
}
roc <- roc.default(response, predictor, ci = FALSE, ...)
if (methods::is(roc, "smooth.roc")) {
return(ci.coords(smooth.roc = roc, ...))
} else {
return(ci.coords(roc = roc, ...))
}
}
ci.coords.smooth.roc <- function(smooth.roc,
x,
input = c("specificity", "sensitivity"), ret = c("specificity", "sensitivity"),
best.method = c("youden", "closest.topleft"), best.weights = c(1, 0.5),
best.policy = c("stop", "omit", "random"),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(smooth.roc)) {
warning("ci.coords() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
input <- roc_utils_match_coords_input_args(input)
ret <- roc_utils_match_coords_ret_args(ret)
best.policy <- match.arg(best.policy)
if (is.character(x)) {
x <- match.arg(x, c("all", "local maximas", "best"))
if (x == "all" || x == "local maximas") {
stop("'all' and 'local maximas' are not available for confidence intervals.")
}
}
# Check if called with density.cases or density.controls
if (is.null(smooth.roc$smoothing.args) || is.numeric(smooth.roc$smoothing.args$density.cases) || is.numeric(smooth.roc$smoothing.args$density.controls)) {
stop("Cannot compute CI of ROC curves smoothed with numeric density.controls and density.cases.")
}
# Get the non smoothed roc.
roc <- attr(smooth.roc, "roc")
roc$ci <- NULL # remove potential ci in roc to avoid infinite loop with smooth.roc()
# prepare the calls
smooth.roc.call <- as.call(c(utils::getS3method("smooth", "roc"), smooth.roc$smoothing.args))
smooth_coords_fun <- if (boot.stratified) stratified.ci.smooth.coords else nonstratified.ci.smooth.coords
# Replicate with simplify=FALSE returns a list of length boot.n
perfs <- replicate(boot.n, smooth_coords_fun(roc, x, input, ret, best.method, best.weights, smooth.roc.call, best.policy), simplify = FALSE)
# Reshape into an array of length(x) x length(ret) x boot.n suited for summary
perfs_array <- array(unlist(perfs),
dim = c(length(x), length(ret), boot.n),
dimnames = list(x, ret, NULL)
)
if (any(which.ones <- sapply(perfs, function(x) all(is.na(x))))) {
if (all(which.ones)) {
warning("All bootstrap iterations produced NA values only.")
} else {
how.many <- sum(which.ones)
warning(sprintf("%s NA value(s) produced during bootstrap were ignored.", how.many))
}
}
summarized.perfs <- apply(perfs_array, 1:2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2), na.rm = TRUE)
ci <- lapply(ret, function(x) t(summarized.perfs[, , x]))
names(ci) <- ret
class(ci) <- c("ci.coords", "ci", class(ci))
attr(ci, "input") <- input
attr(ci, "x") <- x
attr(ci, "ret") <- ret
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "roc") <- smooth.roc
return(ci)
}
ci.coords.roc <- function(roc,
x,
input = "threshold", ret = c("threshold", "specificity", "sensitivity"),
best.method = c("youden", "closest.topleft"), best.weights = c(1, 0.5),
best.policy = c("stop", "omit", "random"),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(roc)) {
warning("ci.coords() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
input <- roc_utils_match_coords_input_args(input)
if (missing(ret) && input != "threshold") {
# Don't show NA thresholds by default
ret <- roc_utils_match_coords_ret_args(ret, threshold = FALSE)
} else {
ret <- roc_utils_match_coords_ret_args(ret)
}
best.policy <- match.arg(best.policy)
if (is.character(x)) {
x <- match.arg(x, c("all", "local maximas", "best"))
if (x == "all" || x == "local maximas") {
stop("'all' and 'local maximas' are not available for confidence intervals.")
}
}
if ("threshold" %in% ret && !(identical(x, "best") || input == "threshold")) {
stop("'threshold' output is only supported for best ROC point ('x = \"best\"') or if \"threshold\" was given as input.")
}
coords_fun <- if (boot.stratified) stratified.ci.coords else nonstratified.ci.coords
# Replicate with simplify=FALSE returns a list of length boot.n
perfs <- replicate(boot.n, coords_fun(roc, x, input, ret, best.method, best.weights, best.policy), simplify = FALSE)
# Reshape into an array of length(x) x length(ret) x boot.n suited for summary
perfs_array <- array(unlist(perfs),
dim = c(length(x), length(ret), boot.n),
dimnames = list(x, ret, NULL)
)
if (any(which.ones <- sapply(perfs, function(x) all(is.na(x))))) {
if (all(which.ones)) {
warning("All bootstrap iterations produced NA values only.")
} else {
how.many <- sum(which.ones)
warning(sprintf("%s NA value(s) produced during bootstrap were ignored.", how.many))
}
}
summarized.perfs <- apply(perfs_array, 1:2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2), na.rm = TRUE)
ci <- lapply(ret, function(x) t(summarized.perfs[, , x]))
names(ci) <- ret
class(ci) <- c("ci.coords", "ci", class(ci))
attr(ci, "input") <- input
attr(ci, "x") <- x
attr(ci, "ret") <- ret
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "roc") <- roc
return(ci)
}
# Function to be called when "best" threshold returned more than 1 column
# Will follow the action defined by best.policy
# For instance:
# if (x == "best" && nrow(res) != 1) {
# return(enforce.best.policy(res, best.policy))
# }
enforce.best.policy <- function(res, best.policy) {
if (best.policy == "stop") {
stop("More than one \"best\" threshold was found, aborting. Change 'best.policy' to alter this behavior.")
} else if (best.policy == "omit") {
res[1, ] <- NA
return(res[1, drop = FALSE])
} else {
return(res[sample(seq_len(nrow(res)), size = 1), , drop = FALSE])
}
}
pROC/R/lines.roc.R 0000644 0001762 0000144 00000003753 15040443562 013310 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
lines.roc <- function(x, ...) {
UseMethod("lines.roc")
}
lines.roc.formula <- function(x, data, subset, na.action, ...) {
data.missing <- missing(data)
call <- match.call()
names(call)[2] <- "formula" # forced to be x by definition of lines
roc.data <- roc_utils_extract_formula(
formula = x, data, subset, na.action, ...,
data.missing = data.missing,
call = call
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'lines.roc'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
roc <- roc(response, predictor, ...)
lines.roc.roc(roc, ...)
roc$call <- match.call()
invisible(roc)
}
lines.roc.default <- function(x, predictor, ...) {
roc <- roc(x, predictor, ...)
lines.roc.roc(roc, ...)
roc$call <- match.call()
invisible(roc)
}
lines.roc.smooth.roc <- lines.smooth.roc <- function(x, ...) {
lines.roc.roc(x, ...) # force usage of lines.roc.roc
}
lines.roc.roc <- function(x, lwd = 2, ...) {
suppressWarnings(lines(x$specificities, x$sensitivities, lwd = lwd, ...))
invisible(x)
}
pROC/R/auc.R 0000644 0001762 0000144 00000021122 15040443562 012152 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
auc <- function(...) {
UseMethod("auc")
}
auc.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'auc'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
roc(response, predictor, auc = TRUE, ...)$auc
}
auc.default <- function(response, predictor, ...) {
roc.default(response, predictor, auc = TRUE, ...)$auc
}
auc.smooth.roc <- function(smooth.roc, ...) {
auc.roc(smooth.roc, ...) # force usage of auc.roc: compatible
}
auc.multiclass.roc <- function(multiclass.roc, ...) {
sum <- sum(sapply(multiclass.roc$rocs, auc, ...))
count <- length(multiclass.roc$levels)
# Hand & Till formula:
auc <- (2 * sum) / (count * (count - 1))
# Prepare auc object
auc <- as.vector(auc) # remove potential pre-existing attributes
attr(auc, "percent") <- multiclass.roc$percent
attr(auc, "roc") <- multiclass.roc
# Get partial auc details from first computed auc
# TODO: find a better way to recover partial.auc!
aucs <- lapply(multiclass.roc$rocs, auc, ...) # keep individual AUCs in a list for later
attr(auc, "partial.auc") <- attr(aucs[[1]], "partial.auc")
if (!identical(attr(aucs[[1]], "partial.auc"), FALSE)) {
attr(auc, "partial.auc.focus") <- attr(aucs[[1]], "partial.auc.focus")
attr(auc, "partial.auc.correct") <- attr(aucs[[1]], "partial.auc.correct")
}
class(auc) <- c("multiclass.auc", "numeric")
return(auc)
}
auc.mv.multiclass.roc <- function(mv.multiclass.roc, ...) {
aucs <- lapply(mv.multiclass.roc$rocs, function(x) list(auc(x[[1]], ...), auc(x[[2]], ...)))
A.ij.total <- sum(sapply(aucs, function(x) mean(unlist(x))))
c <- length(mv.multiclass.roc$levels)
auc <- 2 / (c * (c - 1)) * A.ij.total
# Prepare auc object
auc <- as.vector(auc) # remove potential pre-existing attributes
attr(auc, "percent") <- mv.multiclass.roc$percent
attr(auc, "roc") <- mv.multiclass.roc
# Get partial auc details from first computed auc
attr(auc, "partial.auc") <- attr(aucs[[1]][[1]], "partial.auc")
if (!identical(attr(aucs[[1]], "partial.auc"), FALSE)) {
attr(auc, "partial.auc.focus") <- attr(aucs[[1]][[1]], "partial.auc.focus")
attr(auc, "partial.auc.correct") <- attr(aucs[[1]][[1]], "partial.auc.correct")
}
class(auc) <- c("mv.multiclass.auc", "numeric")
return(auc)
}
auc.roc <- function(roc,
# Partial auc definition
partial.auc = FALSE, # false (consider total area) or numeric length 2: boundaries of the AUC to consider, between 0 and 1, or 0 and 100 if percent is TRUE
partial.auc.focus = c("specificity", "sensitivity"), # if partial.auc is not FALSE: do the boundaries
partial.auc.correct = FALSE,
allow.invalid.partial.auc.correct = FALSE,
... # unused required to allow roc passing arguments to plot or ci.
) {
if (!identical(partial.auc, FALSE)) {
partial.auc.focus <- match.arg(partial.auc.focus)
}
percent <- roc$percent
# Validate partial.auc
if (!identical(partial.auc, FALSE) & !(is.numeric(partial.auc) && length(partial.auc) == 2)) {
stop("partial.auc must be either FALSE or a numeric vector of length 2")
}
# Ensure partial.auc is sorted with partial.auc[1] >= partial.auc[2]
partial.auc <- sort(partial.auc, decreasing = TRUE)
# Get and sort the sensitivities and specificities
roc <- sort_roc(roc)
se <- roc$sensitivities
sp <- roc$specificities
# Full area if partial.auc is FALSE
if (identical(partial.auc, FALSE)) {
if (methods::is(roc, "smooth.roc") && !is.null(roc$smoothing.args) && roc$smoothing.args$method == "binormal") {
coefs <- coefficients(roc$model)
auc <- unname(pnorm(coefs[1] / sqrt(1 + coefs[2]^2)) * ifelse(percent, 100^2, 1))
} else {
diffs.x <- sp[-1] - sp[-length(sp)]
means.vert <- (se[-1] + se[-length(se)]) / 2
auc <- sum(means.vert * diffs.x)
}
}
# Partial area
else {
if (partial.auc.focus == "sensitivity") {
# if we focus on SE, just swap and invert x and y and the computations for SP will work
x <- rev(se)
y <- rev(sp)
} else {
x <- sp
y <- se
}
# find the SEs and SPs in the interval
x.inc <- x[x <= partial.auc[1] & x >= partial.auc[2]]
y.inc <- y[x <= partial.auc[1] & x >= partial.auc[2]]
# compute the AUC strictly in the interval
diffs.x <- x.inc[-1] - x.inc[-length(x.inc)]
means.vert <- (y.inc[-1] + y.inc[-length(y.inc)]) / 2
auc <- sum(means.vert * diffs.x)
# add the borders:
if (length(x.inc) == 0) { # special case: the whole AUC is between 2 se/sp points. Need to interpolate from both
diff.horiz <- partial.auc[1] - partial.auc[2]
# determine indices
idx.hi <- match(FALSE, x < partial.auc[1])
idx.lo <- idx.hi - 1
# proportions
proportion.hi <- (x[idx.hi] - partial.auc[1]) / (x[idx.hi] - x[idx.lo])
proportion.lo <- (partial.auc[2] - x[idx.lo]) / (x[idx.hi] - x[idx.lo])
# interpolated y's
y.hi <- y[idx.hi] + proportion.hi * (y[idx.lo] - y[idx.hi])
y.lo <- y[idx.lo] - proportion.lo * (y[idx.lo] - y[idx.hi])
# compute AUC
mean.vert <- (y.hi + y.lo) / 2
auc <- mean.vert * diff.horiz
} else { # if the upper limit is not exactly present in SPs, interpolate
if (!(partial.auc[1] %in% x.inc)) {
# find the limit indices
idx.out <- match(FALSE, x < partial.auc[1])
idx.in <- idx.out - 1
# interpolate y
proportion <- (partial.auc[1] - x[idx.out]) / (x[idx.in] - x[idx.out])
y.interpolated <- y[idx.out] + proportion * (y[idx.in] - y[idx.out])
# add to AUC
auc <- auc + (partial.auc[1] - x[idx.in]) * (y[idx.in] + y.interpolated) / 2
}
if (!(partial.auc[2] %in% x.inc)) { # if the lower limit is not exactly present in SPs, interpolate
# find the limit indices in and out
# idx.out <- length(x) - match(TRUE, rev(x) < partial.auc[2]) + 1
idx.out <- match(TRUE, x > partial.auc[2]) - 1
idx.in <- idx.out + 1
# interpolate y
proportion <- (x[idx.in] - partial.auc[2]) / (x[idx.in] - x[idx.out])
y.interpolated <- y[idx.in] + proportion * (y[idx.out] - y[idx.in])
# add to AUC
auc <- auc + (x[idx.in] - partial.auc[2]) * (y[idx.in] + y.interpolated) / 2
}
}
}
# In percent, we have 100*100 = 10,000 as maximum area, so we need to divide by a factor 100
if (percent) {
auc <- auc / 100
}
# Correction according to McClish DC, 1989
if (all(!identical(partial.auc, FALSE), partial.auc.correct)) { # only for pAUC
min <- roc_utils_min_partial_auc(partial.auc, percent)
max <- roc_utils_max_partial_auc(partial.auc, percent)
# The correction is defined only when auc >= min
if (!allow.invalid.partial.auc.correct && auc < min) {
warning("Partial AUC correction not defined for ROC curves below the diagonal.")
auc <- NA
} else if (percent) {
auc <- (100 + ((auc - min) * 100 / (max - min))) / 2 # McClish formula adapted for %
} else {
auc <- (1 + ((auc - min) / (max - min))) / 2 # original formula by McClish
}
}
# Prepare the AUC to return with attributes
auc <- as.vector(auc) # remove potential pre-existing attributes
attr(auc, "partial.auc") <- partial.auc
attr(auc, "percent") <- percent
attr(auc, "roc") <- roc
if (!identical(partial.auc, FALSE)) {
attr(auc, "partial.auc.focus") <- partial.auc.focus
attr(auc, "partial.auc.correct") <- partial.auc.correct
}
class(auc) <- c("auc", class(auc))
return(auc)
}
pROC/R/ci.sp.R 0000644 0001762 0000144 00000013077 15040443562 012430 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci.sp <- function(...) {
UseMethod("ci.sp")
}
ci.sp.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci.sp'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.sp(roc(response, predictor, ci = FALSE, ...), ...)
}
ci.sp.default <- function(response, predictor, ...) {
if (methods::is(response, "multiclass.roc") || methods::is(response, "multiclass.auc")) {
stop("'ci.sp' not available for multiclass ROC curves.")
}
roc <- roc.default(response, predictor, ci = FALSE, ...)
if (methods::is(roc, "smooth.roc")) {
return(ci.sp(smooth.roc = roc, ...))
} else {
return(ci.sp(roc = roc, ...))
}
}
ci.sp.smooth.roc <- function(smooth.roc,
sensitivities = seq(0, 1, .1) * ifelse(smooth.roc$percent, 100, 1),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(smooth.roc)) {
warning("ci.sp() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# Check if called with density.cases or density.controls
if (is.null(smooth.roc$smoothing.args) || is.numeric(smooth.roc$smoothing.args$density.cases) || is.numeric(smooth.roc$smoothing.args$density.controls)) {
stop("Cannot compute CI of ROC curves smoothed with numeric density.controls and density.cases.")
}
# Get the non smoothed roc.
roc <- attr(smooth.roc, "roc")
roc$ci <- NULL # remove potential ci in roc to avoid infinite loop with smooth.roc()
# prepare the calls
smooth.roc.call <- as.call(c(utils::getS3method("smooth", "roc"), smooth.roc$smoothing.args))
if (boot.stratified) {
perfs <- do.call(rbind, lapply(seq_len(boot.n), stratified.ci.smooth.sp, roc = roc, se = sensitivities, smooth.roc.call = smooth.roc.call))
} else {
perfs <- do.call(rbind, lapply(seq_len(boot.n), nonstratified.ci.smooth.sp, roc = roc, se = sensitivities, smooth.roc.call = smooth.roc.call))
}
if (any(is.na(perfs))) {
warning("NA value(s) produced during bootstrap were ignored.")
perfs <- perfs[!apply(perfs, 1, function(x) any(is.na(x))), ]
}
ci <- t(apply(perfs, 2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)))
rownames(ci) <- paste(sensitivities, ifelse(roc$percent, "%", ""), sep = "")
class(ci) <- c("ci.sp", "ci", class(ci))
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "sensitivities") <- sensitivities
attr(ci, "roc") <- smooth.roc
return(ci)
}
ci.sp.roc <- function(roc,
sensitivities = seq(0, 1, .1) * ifelse(roc$percent, 100, 1),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(roc)) {
warning("ci.sp() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
if (boot.stratified) {
perfs <- do.call(rbind, lapply(seq_len(boot.n), stratified.ci.sp, roc = roc, se = sensitivities))
} else {
perfs <- do.call(rbind, lapply(seq_len(boot.n), nonstratified.ci.sp, roc = roc, se = sensitivities))
}
if (any(is.na(perfs))) {
warning("NA value(s) produced during bootstrap were ignored.")
perfs <- perfs[!apply(perfs, 1, function(x) any(is.na(x))), ]
}
ci <- t(apply(perfs, 2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)))
rownames(ci) <- paste(sensitivities, ifelse(roc$percent, "%", ""), sep = "")
class(ci) <- c("ci.sp", "ci", class(ci))
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "sensitivities") <- sensitivities
attr(ci, "roc") <- roc
return(ci)
}
pROC/R/are.paired.R 0000644 0001762 0000144 00000011101 15040443562 013410 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
are.paired <- function(...) {
UseMethod("are.paired")
}
are.paired.auc <- function(roc1, roc2, ...) {
return(are.paired.roc(roc1, roc2, ...))
}
are.paired.smooth.roc <- function(roc1, roc2, ...) {
return(are.paired.roc(roc1, roc2, ...))
}
are.paired.roc <- function(roc1, roc2,
return.paired.rocs = FALSE,
reuse.auc = TRUE, reuse.ci = FALSE, reuse.smooth = TRUE,
...) {
# check return.paired.rocs
if (!is.logical(return.paired.rocs) || length(return.paired.rocs) != 1) {
stop("'return.paired.rocs' must be either TRUE or FALSE.")
}
# Recover base ROC curves (not auc or smoothed)
if ("auc" %in% class(roc1)) {
roc1 <- attr(roc1, "roc")
}
if ("auc" %in% class(roc2)) {
roc2 <- attr(roc2, "roc")
}
if ("smooth.roc" %in% class(roc1)) {
oroc1 <- roc1
roc1 <- attr(roc1, "roc")
}
if ("smooth.roc" %in% class(roc2)) {
oroc2 <- roc2
roc2 <- attr(roc2, "roc")
}
# Check if the levels are the same. Otherwise it is not paired.
if (!identical(roc1$levels, roc2$levels)) {
return(FALSE)
}
# check if responses of roc 1 and 2 are identical
if (identical(roc1$response, roc2$response)) {
retval <- TRUE
if (return.paired.rocs) {
attr(retval, "roc1") <- roc1
attr(retval, "roc2") <- roc2
}
return(retval)
} else {
# Make sure the difference is not only due to missing values
# compare original response (with NAs and response not in levels)
if (identical(roc1$original.response, roc2$original.response)) {
retval <- TRUE
if (!return.paired.rocs) {
return(retval)
}
# else prepare paired ROCs
idx.exclude <- is.na(roc1$original.predictor) | is.na(roc2$original.predictor) | is.na(roc1$original.response) | !roc1$original.response %in% roc1$levels
roc1.paired <- roc(roc1$original.response[!idx.exclude], roc1$original.predictor[!idx.exclude], levels = roc1$levels, percent = roc1$percent, na.rm = FALSE, direction = roc1$direction, auc = FALSE)
roc2.paired <- roc(roc2$original.response[!idx.exclude], roc2$original.predictor[!idx.exclude], levels = roc2$levels, percent = roc2$percent, na.rm = FALSE, direction = roc2$direction, auc = FALSE)
# Re-use auc/ci/smooth for roc1
if (exists("oroc1") && reuse.smooth) {
args <- oroc1$smoothing.args
args$roc <- roc1.paired
roc1.paired <- do.call("smooth.roc", args)
roc1.paired$call$roc <- as.name("roc1.paired")
}
if (!is.null(roc1$auc) && reuse.auc) {
args <- attributes(roc1$auc)
args$roc <- roc1.paired
roc1.paired$auc <- do.call("auc.roc", args)
}
if (!is.null(roc1$ci) && reuse.ci) {
args <- attributes(roc1$ci)
args$roc <- NULL
roc1.paired$ci <- do.call(class(roc1$ci)[1], c(roc = list(roc1.paired), args))
}
# Re-use auc/ci/smooth for roc2
if (exists("oroc2") && reuse.smooth) {
args <- oroc2$smoothing.args
args$roc <- roc2.paired
roc2.paired <- do.call("smooth.roc", args)
roc2.paired$call$roc <- as.name("roc2.paired")
}
if (!is.null(roc2$auc) && reuse.auc) {
args <- attributes(roc2$auc)
args$roc <- roc2.paired
roc2.paired$auc <- do.call("auc.roc", args)
}
if (!is.null(roc2$ci) && reuse.ci) {
args <- attributes(roc2$ci)
args$roc <- NULL
roc2.paired$ci <- do.call(class(roc2$ci)[1], c(roc = list(roc2.paired), args))
}
# Attach ROCs and return value
attr(retval, "roc1") <- roc1.paired
attr(retval, "roc2") <- roc2.paired
return(retval)
} else {
return(FALSE)
}
}
}
pROC/R/groupGeneric.R 0000644 0001762 0000144 00000003162 15040443562 014037 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2014 Xavier Robin
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
Ops.auc <- function(e1, e2) {
if (methods::is(e1, "auc")) {
attributes(e1) <- NULL
}
if (methods::is(e2, "auc")) {
attributes(e2) <- NULL
}
NextMethod()
}
Math.auc <- function(x, ...) {
attributes(x) <- NULL
NextMethod()
}
Ops.ci.se <- Ops.ci.sp <- Ops.ci.auc <- function(e1, e2) {
e1 <- remove.ci.attributes(e1)
e2 <- remove.ci.attributes(e2)
NextMethod()
}
Math.ci.se <- Math.ci.sp <- Math.ci.auc <- function(x, ...) {
x <- remove.ci.attributes(x)
NextMethod()
}
remove.ci.attributes <- function(ci) {
attr(ci, "conf.level") <- NULL
attr(ci, "boot.n") <- NULL
attr(ci, "boot.stratified") <- NULL
attr(ci, "specificities") <- NULL
attr(ci, "sensitivities") <- NULL
attr(ci, "roc") <- NULL
attr(ci, "method") <- NULL
attr(ci, "auc") <- NULL
class(ci) <- class(ci)[-(1:2)]
return(ci)
}
pROC/R/cov.R 0000644 0001762 0000144 00000017605 15040443562 012204 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
cov <- function(...) {
UseMethod("cov")
}
cov.default <- function(...) {
stats::cov(...)
}
cov.auc <- function(roc1, roc2, ...) {
# Change roc1 from an auc to a roc object but keep the auc specifications
auc1 <- roc1
attr(auc1, "roc") <- NULL
roc1 <- attr(roc1, "roc")
roc1$auc <- auc1
# Pass to cov.roc
return(cov.roc(roc1, roc2, ...))
}
cov.smooth.roc <- function(roc1, roc2, ...) {
cov.roc(roc1, roc2, ...)
}
cov.roc <- function(roc1, roc2,
method = c("delong", "bootstrap", "obuchowski"),
reuse.auc = TRUE,
boot.n = 2000, boot.stratified = TRUE, boot.return = FALSE,
progress = NULL,
parallel = FALSE,
...) {
# If roc2 is an auc, take the roc but keep the auc specifications
if (methods::is(roc2, "auc")) {
auc2 <- roc2
attr(auc2, "roc") <- NULL
roc2 <- attr(roc2, "roc")
roc2$auc <- auc2
}
if (roc_utils_is_perfect_curve(roc1) && roc_utils_is_perfect_curve(roc2)) {
warning("cov() of two ROC curves with AUC == 1 is always 0 and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# store which objects are smoothed, and how
smoothing.args <- list()
if ("smooth.roc" %in% class(roc1)) {
smoothing.args$roc1 <- roc1$smoothing.args
smoothing.args$roc1$smooth <- TRUE
roc1 <- attr(roc1, "roc")
# oroc1$auc <- roc1$auc
} else {
smoothing.args$roc1 <- list(smooth = FALSE)
}
if ("smooth.roc" %in% class(roc2)) {
smoothing.args$roc2 <- roc2$smoothing.args
smoothing.args$roc2$smooth <- TRUE
roc2 <- attr(roc2, "roc")
# oroc2$auc <- roc2$auc
} else {
smoothing.args$roc2 <- list(smooth = FALSE)
}
# then determine whether the rocs are paired or not
rocs.are.paired <- are.paired(roc1, roc2, return.paired.rocs = FALSE, reuse.auc = TRUE, reuse.ci = FALSE, reuse.smooth = TRUE)
if (!rocs.are.paired) {
message("ROC curves are unpaired.")
return(0)
}
# check that the AUC was computed, or do it now
if (is.null(roc1$auc) | !reuse.auc) {
if (smoothing.args$roc1$smooth) {
roc1$auc <- auc(smooth.roc = do.call("smooth.roc", c(list(roc = roc1), smoothing.args$roc1)), ...)
# remove partial.auc.* arguments that are now in roc1$auc and that will mess later processing
# (formal argument "partial.auc(.*)" matched by multiple actual arguments)
# This removal should be safe because we always use smoothing.args with roc1 in the following processing,
# however it is a potential source of bugs.
smoothing.args$roc1$partial.auc <- NULL
smoothing.args$roc1$partial.auc.correct <- NULL
smoothing.args$roc1$partial.auc.focus <- NULL
} else {
roc1$auc <- auc(roc1, ...)
}
}
if (is.null(roc2$auc) | !reuse.auc) {
if (smoothing.args$roc2$smooth) {
roc2$auc <- auc(smooth.roc = do.call("smooth.roc", c(list(roc = roc2), smoothing.args$roc2)), ...)
# remove partial.auc.* arguments that are now in roc1$auc and that will mess later processing
# (formal argument "partial.auc(.*)" matched by multiple actual arguments)
# This removal should be safe because we always use smoothing.args with roc2 in the following processing,
# however it is a potential source of bugs.
smoothing.args$roc2$partial.auc <- NULL
smoothing.args$roc2$partial.auc.correct <- NULL
smoothing.args$roc2$partial.auc.focus <- NULL
} else {
roc2$auc <- auc(roc2, ...)
}
}
# check that the same region was requested in auc. Otherwise, issue a warning
if (!identical(attributes(roc1$auc)[names(attributes(roc1$auc)) != "roc"], attributes(roc2$auc)[names(attributes(roc2$auc)) != "roc"])) {
warning("Different AUC specifications in the ROC curves. Enforcing the inconsistency, but unexpected results may be produced.")
}
# check that the same smoothing params were requested in auc. Otherwise, issue a warning
if (!identical(smoothing.args$roc1, smoothing.args$roc2)) {
warning("Different smoothing parameters in the ROC curves. Enforcing the inconsistency, but unexpected results may be produced.")
}
# Check the method
if (missing(method) | is.null(method)) {
# determine method if missing
if (has.partial.auc(roc1)) {
# partial auc: go for bootstrap
method <- "bootstrap"
} else if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
# smoothing in one or both: bootstrap
method <- "bootstrap"
} else if (roc1$direction != roc2$direction) {
# delong doesn't work well with opposite directions (will report high significance if roc1$auc and roc2$auc are similar and high)
method <- "bootstrap"
} else {
method <- "delong"
}
} else {
method <- match.arg(method)
if (method == "delong") {
# delong NA to pAUC: warn + change
if (has.partial.auc(roc1) || has.partial.auc(roc2)) {
stop("DeLong method is not supported for partial AUC. Use method=\"bootstrap\" instead.")
}
if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
stop("DeLong method is not supported for smoothed ROCs. Use method=\"bootstrap\" instead.")
}
if (roc1$direction != roc2$direction) {
warning("DeLong method should not be applied to ROC curves with a different direction.")
}
} else if (method == "obuchowski") {
if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
stop("Obuchowski method is not supported for smoothed ROCs. Use method=\"bootstrap\" instead.")
}
if ((has.partial.auc(roc1) && attr(roc1$auc, "partial.auc.focus") == "sensitivity") ||
(has.partial.auc(roc2) && attr(roc2$auc, "partial.auc.focus") == "sensitivity")) {
stop("Obuchowski method is not supported for partial AUC on sensitivity region. Use method=\"bootstrap\" instead.")
}
if (roc1$direction != roc2$direction) {
warning("Obuchowski method should not be applied to ROC curves with a different direction.")
}
}
}
if (method == "delong") {
n <- length(roc1$controls)
m <- length(roc1$cases)
V1 <- delongPlacements(roc1)
var1 <- var(V1$Y) / n + var(V1$X) / m
V2 <- delongPlacements(roc2)
var2 <- var(V2$Y) / n + var(V2$X) / m
cov <- cov(V2$X, V1$X) / m + cov(V2$Y, V1$Y) / n
if (roc1$percent) {
cov <- cov * (100^2)
}
} else if (method == "obuchowski") {
cov <- cov_roc_obuchowski(roc1, roc2) / length(roc1$cases)
if (roc1$percent) {
cov <- cov * (100^2)
}
} else { # method == "bootstrap"
# Check if called with density.cases or density.controls
if (is.null(smoothing.args) || is.numeric(smoothing.args$density.cases) || is.numeric(smoothing.args$density.controls)) {
stop("Cannot compute the covariance of ROC curves smoothed with numeric density.controls and density.cases.")
}
cov <- bootstrap.cov(roc1, roc2, boot.n, boot.stratified, boot.return, smoothing.args)
}
return(cov)
}
pROC/R/bootstrap.R 0000644 0001762 0000144 00000072411 15040443562 013426 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
########## AUC of two ROC curves (roc.test, cov) ##########
bootstrap.cov <- function(roc1, roc2, boot.n, boot.stratified, boot.return, smoothing.args) {
# rename method into smooth.method for roc
smoothing.args$roc1$smooth.method <- smoothing.args$roc1$method
smoothing.args$roc1$method <- NULL
smoothing.args$roc2$smooth.method <- smoothing.args$roc2$method
smoothing.args$roc2$method <- NULL
# Prepare arguments for later calls to roc
auc1skeleton <- attributes(roc1$auc)
auc1skeleton$roc <- NULL
auc1skeleton$direction <- roc1$direction
auc1skeleton$class <- NULL
auc1skeleton$allow.invalid.partial.auc.correct <- TRUE
auc1skeleton <- c(auc1skeleton, smoothing.args$roc1)
names(auc1skeleton)[which(names(auc1skeleton) == "n")] <- "smooth.n"
auc2skeleton <- attributes(roc2$auc)
auc2skeleton$roc <- NULL
auc2skeleton$direction <- roc2$direction
auc2skeleton$class <- NULL
auc2skeleton$allow.invalid.partial.auc.correct <- TRUE
auc2skeleton <- c(auc2skeleton, smoothing.args$roc2)
names(auc2skeleton)[which(names(auc2skeleton) == "n")] <- "smooth.n"
auc1skeleton$auc <- auc2skeleton$auc <- TRUE
# Some attributes may be duplicated in AUC skeletons and will mess the boostrap later on when we do.call().
# If this condition happen, it probably means we have a bug elsewhere.
# Rather than making a complicated processing to remove the duplicates,
# just throw an error and let us solve the bug when a user reports it.
duplicated.auc1skeleton <- duplicated(names(auc1skeleton))
duplicated.auc2skeleton <- duplicated(names(auc2skeleton))
if (any(duplicated.auc1skeleton)) {
sessionInfo <- sessionInfo()
save(roc1, roc2, boot.n, boot.stratified, boot.return, smoothing.args, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("pROC: duplicated argument(s) in AUC1 skeleton: \"%s\". Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", paste(names(auc1skeleton)[duplicated(names(auc1skeleton))], collapse = ", "), utils::packageDescription("pROC")$BugReports))
}
if (any(duplicated.auc2skeleton)) {
sessionInfo <- sessionInfo()
save(roc1, roc2, boot.n, boot.stratified, boot.return, smoothing.args, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("duplicated argument(s) in AUC2 skeleton: \"%s\". Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", paste(names(auc2skeleton)[duplicated(names(auc2skeleton))], collapse = ", "), utils::packageDescription("pROC")$BugReports))
}
if (boot.stratified) { # precompute sorted responses if stratified
resampled.values <- vapply(seq_len(boot.n), stratified.bootstrap.test, FUN.VALUE = double(2L), roc1 = roc1, roc2 = roc2, test = "boot", x = NULL, paired = TRUE, auc1skeleton = auc1skeleton, auc2skeleton = auc2skeleton)
} else {
auc1skeleton$levels <- roc1$levels
auc1skeleton$direction <- roc1$direction
auc2skeleton$levels <- roc2$levels
auc2skeleton$direction <- roc2$direction
resampled.values <- vapply(seq_len(boot.n), nonstratified.bootstrap.test, FUN.VALUE = double(2L), roc1 = roc1, roc2 = roc2, test = "boot", x = NULL, paired = TRUE, auc1skeleton = auc1skeleton, auc2skeleton = auc2skeleton)
}
# are there NA values?
if ((num.NAs <- sum(apply(resampled.values, 1, is.na))) > 0) {
warning(sprintf("%i NA value(s) produced during bootstrap were ignored.", num.NAs))
resampled.values <- resampled.values[!apply(resampled.values, 1, function(x) any(is.na(x))), ]
}
cov <- stats::cov(resampled.values[1, ], resampled.values[2, ])
if (boot.return) {
attr(cov, "resampled.values") <- resampled.values
}
return(cov)
}
# Bootstrap test, used by roc.test.roc
bootstrap.test <- function(roc1, roc2, test, x, paired, boot.n, boot.stratified, smoothing.args) {
# rename method into smooth.method for roc
smoothing.args$roc1$smooth.method <- smoothing.args$roc1$method
smoothing.args$roc1$method <- NULL
smoothing.args$roc2$smooth.method <- smoothing.args$roc2$method
smoothing.args$roc2$method <- NULL
# Prepare arguments for later calls to roc
auc1skeleton <- attributes(roc1$auc)
auc1skeleton$roc <- NULL
auc1skeleton$direction <- roc1$direction
auc1skeleton$class <- NULL
auc1skeleton$allow.invalid.partial.auc.correct <- TRUE
auc1skeleton <- c(auc1skeleton, smoothing.args$roc1)
names(auc1skeleton)[which(names(auc1skeleton) == "n")] <- "smooth.n"
auc2skeleton <- attributes(roc2$auc)
auc2skeleton$roc <- NULL
auc2skeleton$direction <- roc2$direction
auc2skeleton$class <- NULL
auc2skeleton$allow.invalid.partial.auc.correct <- TRUE
auc2skeleton <- c(auc2skeleton, smoothing.args$roc2)
names(auc2skeleton)[which(names(auc2skeleton) == "n")] <- "smooth.n"
auc1skeleton$auc <- auc2skeleton$auc <- test == "boot"
# Some attributes may be duplicated in AUC skeletons and will mess the boostrap later on when we do.call().
# If this condition happen, it probably means we have a bug elsewhere.
# Rather than making a complicated processing to remove the duplicates,
# just throw an error and let us solve the bug when a user reports it.
duplicated.auc1skeleton <- duplicated(names(auc1skeleton))
duplicated.auc2skeleton <- duplicated(names(auc2skeleton))
if (any(duplicated.auc1skeleton)) {
sessionInfo <- sessionInfo()
save(roc1, roc2, test, x, paired, boot.n, boot.stratified, smoothing.args, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("pROC: duplicated argument(s) in AUC1 skeleton: \"%s\". Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", paste(names(auc1skeleton)[duplicated(names(auc1skeleton))], collapse = ", "), utils::packageDescription("pROC")$BugReports))
}
if (any(duplicated.auc2skeleton)) {
sessionInfo <- sessionInfo()
save(roc1, roc2, test, x, paired, boot.n, boot.stratified, smoothing.args, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("duplicated argument(s) in AUC2 skeleton: \"%s\". Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", paste(names(auc2skeleton)[duplicated(names(auc2skeleton))], collapse = ", "), utils::packageDescription("pROC")$BugReports))
}
if (boot.stratified) { # precompute sorted responses if stratified
# response.roc1 <- factor(c(rep(roc1$levels[1], length(roc1$controls)), rep(roc1$levels[2], length(roc1$cases))), levels=roc1$levels)
# response.roc2 <- factor(c(rep(roc2$levels[1], length(roc2$controls)), rep(roc2$levels[2], length(roc2$cases))), levels=roc2$levels)
# auc1skeleton$response <- response.roc1
# auc2skeleton$response <- response.roc2
resampled.values <- vapply(seq_len(boot.n), stratified.bootstrap.test, FUN.VALUE = double(2L), roc1 = roc1, roc2 = roc2, test = test, x = x, paired = paired, auc1skeleton = auc1skeleton, auc2skeleton = auc2skeleton)
} else {
auc1skeleton$levels <- roc1$levels
auc1skeleton$direction <- roc1$direction
auc2skeleton$levels <- roc2$levels
auc2skeleton$direction <- roc2$direction
resampled.values <- vapply(seq_len(boot.n), nonstratified.bootstrap.test, FUN.VALUE = double(2L), roc1 = roc1, roc2 = roc2, test = test, x = x, paired = paired, auc1skeleton = auc1skeleton, auc2skeleton = auc2skeleton)
}
# compute the statistics
diffs <- resampled.values[1, ] - resampled.values[2, ]
# are there NA values?
if ((num.NAs <- sum(is.na(diffs))) > 0) {
warning(sprintf("%i NA value(s) produced during bootstrap were ignored.", num.NAs))
diffs <- diffs[!is.na(diffs)]
}
# Restore smoothing if necessary
if (smoothing.args$roc1$smooth) {
smoothing.args$roc1$method <- smoothing.args$roc1$smooth.method
roc1 <- do.call("smooth.roc", c(list(roc = roc1), smoothing.args$roc1))
}
if (smoothing.args$roc2$smooth) {
smoothing.args$roc2$method <- smoothing.args$roc2$smooth.method
roc2 <- do.call("smooth.roc", c(list(roc = roc2), smoothing.args$roc2))
}
if (test == "sp") {
coord1 <- coords(roc1, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
D <- (coord1 - coord2) / sd(diffs)
} else if (test == "se") {
coord1 <- coords(roc1, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
D <- (coord1 - coord2) / sd(diffs)
} else {
D <- (roc1$auc - roc2$auc) / sd(diffs)
}
if (is.nan(D) && all(diffs == 0) && roc1$auc == roc2$auc) {
D <- 0
} # special case: no difference between AUCs produces a NaN
return(D)
}
stratified.bootstrap.test <- function(n, roc1, roc2, test, x, paired, auc1skeleton, auc2skeleton) {
# sample control and cases separately for a stratified bootstrap
idx.controls.roc1 <- sample(1:length(roc1$controls), replace = TRUE)
idx.cases.roc1 <- sample(1:length(roc1$cases), replace = TRUE)
# finish roc skeletons
auc1skeleton$controls <- roc1$controls[idx.controls.roc1]
auc1skeleton$cases <- roc1$cases[idx.cases.roc1]
if (paired) {
auc2skeleton$controls <- roc2$controls[idx.controls.roc1]
auc2skeleton$cases <- roc2$cases[idx.cases.roc1]
} else { # for unpaired, resample roc2 separately
idx.controls.roc2 <- sample(1:length(roc2$controls), replace = TRUE)
idx.cases.roc2 <- sample(1:length(roc2$cases), replace = TRUE)
auc2skeleton$controls <- roc2$controls[idx.controls.roc2]
auc2skeleton$cases <- roc2$cases[idx.cases.roc2]
}
# re-compute the resampled ROC curves
roc1 <- try(do.call("roc_cc_nochecks", auc1skeleton), silent = TRUE)
roc2 <- try(do.call("roc_cc_nochecks", auc2skeleton), silent = TRUE)
# resampled ROCs might not be smoothable: return NA
if (methods::is(roc1, "try-error") || methods::is(roc2, "try-error")) {
return(c(NA, NA))
} else {
if (test == "sp") {
coord1 <- coords(roc1, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
return(c(coord1, coord2))
} else if (test == "se") {
coord1 <- coords(roc1, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
return(c(coord1, coord2))
} else {
return(c(roc1$auc, roc2$auc))
}
}
}
nonstratified.bootstrap.test <- function(n, roc1, roc2, test, x, paired, auc1skeleton, auc2skeleton) {
# sample all patients
idx.all.roc1 <- sample(1:length(roc1$response), replace = TRUE)
# finish roc skeletons
auc1skeleton$response <- roc1$response[idx.all.roc1]
auc1skeleton$predictor <- roc1$predictor[idx.all.roc1]
if (paired) { # if paired, resample roc2 as roc1
auc2skeleton$response <- roc2$response[idx.all.roc1]
auc2skeleton$predictor <- roc2$predictor[idx.all.roc1]
} else { # if unpaired, resample roc2 separately
idx.all.roc2 <- sample(1:length(roc2$response), replace = TRUE)
auc2skeleton$response <- roc2$response[idx.all.roc2]
auc2skeleton$predictor <- roc2$predictor[idx.all.roc2]
}
# re-compute the resampled ROC curves
roc1 <- try(do.call("roc_rp_nochecks", auc1skeleton), silent = TRUE)
roc2 <- try(do.call("roc_rp_nochecks", auc2skeleton), silent = TRUE)
# resampled ROCs might not be smoothable: return NA
if (methods::is(roc1, "try-error") || methods::is(roc2, "try-error")) {
return(c(NA, NA))
} else {
if (test == "sp") {
coord1 <- coords(roc1, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("specificity"), ret = c("sensitivity"))[1, 1]
return(c(coord1, coord2))
} else if (test == "se") {
coord1 <- coords(roc1, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
coord2 <- coords(roc2, x = x, input = c("sensitivity"), ret = c("specificity"))[1, 1]
return(c(coord1, coord2))
} else {
return(c(roc1$auc, roc2$auc))
}
}
}
########## AUC of one ROC curves (ci.auc, var) ##########
ci_auc_bootstrap <- function(roc, conf.level, boot.n, boot.stratified, ...) {
if (boot.stratified) {
aucs <- unlist(lapply(seq_len(boot.n), stratified.ci.auc, roc = roc))
} else {
aucs <- unlist(lapply(seq_len(boot.n), nonstratified.ci.auc, roc = roc))
}
if (sum(is.na(aucs)) > 0) {
warning("NA value(s) produced during bootstrap were ignored.")
aucs <- aucs[!is.na(aucs)]
}
# TODO: Maybe apply a correction (it's in the Tibshirani?) What do Carpenter-Bithell say about that?
# Prepare the return value
return(quantile(aucs, c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)))
}
stratified.ci.auc <- function(n, roc) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
auc.roc(roc, partial.auc = attr(roc$auc, "partial.auc"), partial.auc.focus = attr(roc$auc, "partial.auc.focus"), partial.auc.correct = attr(roc$auc, "partial.auc.correct"), allow.invalid.partial.auc.correct = TRUE)
}
nonstratified.ci.auc <- function(n, roc) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(controls, cases), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
auc.roc(roc, partial.auc = attr(roc$auc, "partial.auc"), partial.auc.focus = attr(roc$auc, "partial.auc.focus"), partial.auc.correct = attr(roc$auc, "partial.auc.correct"), allow.invalid.partial.auc.correct = TRUE)
}
########## AUC of a smooth ROC curve (ci.smooth.auc) ##########
# Returns a smoothed auc in a stratified manner
stratified.ci.smooth.auc <- function(n, roc, smooth.roc.call, auc.call) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
# need to rebuild a ROC and smooth it
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
auc.call$smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(auc.call$smooth.roc, "try-error")) {
return(NA)
}
return(eval(auc.call))
}
# Returns a smoothed auc in a non stratified manner
nonstratified.ci.smooth.auc <- function(n, roc, smooth.roc.call, auc.call) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(controls, cases), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
roc$cases <- cases
roc$controls <- controls
roc$predictor <- predictor
roc$response <- response
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
auc.call$smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(auc.call$smooth.roc, "try-error")) {
return(NA)
}
return(eval(auc.call))
}
########## SE of a ROC curve (ci.se) ##########
stratified.ci.se <- function(n, roc, sp) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$thresholds <- thresholds
return(coords.roc(roc, sp, input = "specificity", ret = "sensitivity")[, 1])
}
nonstratified.ci.se <- function(n, roc, sp) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$thresholds <- thresholds
return(coords.roc(roc, sp, input = "specificity", ret = "sensitivity")[, 1])
}
########## SE of a smooth ROC curve (ci.se) ##########
stratified.ci.smooth.se <- function(n, roc, sp, smooth.roc.call) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
return(coords.smooth.roc(smooth.roc, sp, input = "specificity", ret = "sensitivity")[, 1])
}
nonstratified.ci.smooth.se <- function(n, roc, sp, smooth.roc.call) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- predictor
roc$response <- response
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
return(coords.smooth.roc(smooth.roc, sp, input = "specificity", ret = "sensitivity")[, 1])
}
########## SP of a ROC curve (ci.sp) ##########
stratified.ci.sp <- function(n, roc, se) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$thresholds <- thresholds
return(coords.roc(roc, se, input = "sensitivity", ret = "specificity")[, 1])
}
nonstratified.ci.sp <- function(n, roc, se) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$thresholds <- thresholds
return(coords.roc(roc, se, input = "sensitivity", ret = "specificity")[, 1])
}
########## SP of a smooth ROC curve (ci.sp) ##########
stratified.ci.smooth.sp <- function(n, roc, se, smooth.roc.call) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
return(coords.smooth.roc(smooth.roc, se, input = "sensitivity", ret = "specificity")[, 1])
}
nonstratified.ci.smooth.sp <- function(n, roc, se, smooth.roc.call) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- predictor
roc$response <- response
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
return(coords.smooth.roc(smooth.roc, se, input = "sensitivity", ret = "specificity")[, 1])
}
########## Threshold of a ROC curve (ci.thresholds) ##########
stratified.ci.thresholds <- function(n, roc, thresholds) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
return(sapply(thresholds, roc_utils_perfs, controls = controls, cases = cases, direction = roc$direction))
}
# Returns an auc in a non stratified manner
nonstratified.ci.thresholds <- function(n, roc, thresholds) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
return(sapply(thresholds, roc_utils_perfs, controls = controls, cases = cases, direction = roc$direction))
}
########## Coords of one ROC curves (ci.coords) ##########
stratified.ci.coords <- function(roc, x, input, ret, best.method, best.weights, best.policy) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
res <- coords.roc(roc,
x = x, input = input, ret = ret,
best.method = best.method, best.weights = best.weights
)
# Return a random column with "best"
if (length(x) == 1 && x == "best" && nrow(res) != 1) {
return(enforce.best.policy(res, best.policy))
} else {
return(res)
}
}
nonstratified.ci.coords <- function(roc, x, input, ret, best.method, best.weights, best.policy) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(controls, cases), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se
roc$specificities <- perfs$sp
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
res <- coords.roc(roc,
x = x, input = input, ret = ret,
best.method = best.method, best.weights = best.weights
)
# Return a random column with "best"
if (length(x) == 1 && x == "best" && nrow(res) != 1) {
return(enforce.best.policy(res, best.policy))
} else {
return(res)
}
}
########## Coords of a smooth ROC curve (ci.coords) ##########
stratified.ci.smooth.coords <- function(roc, x, input, ret, best.method, best.weights, smooth.roc.call, best.policy) {
controls <- sample(roc$controls, replace = TRUE)
cases <- sample(roc$cases, replace = TRUE)
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- c(controls, cases)
roc$response <- c(rep(roc$levels[1], length(controls)), rep(roc$levels[2], length(cases)))
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
res <- coords.roc(smooth.roc,
x = x, input = input, ret = ret,
best.method = best.method, best.weights = best.weights
)
# Return a random column with "best"
if (length(x) == 1 && x == "best" && nrow(res) != 1) {
return(enforce.best.policy(res, best.policy))
} else {
return(res)
}
}
nonstratified.ci.smooth.coords <- function(roc, x, input, ret, best.method, best.weights, smooth.roc.call, best.policy) {
tmp.idx <- sample(1:length(roc$predictor), replace = TRUE)
predictor <- roc$predictor[tmp.idx]
response <- roc$response[tmp.idx]
splitted <- split(predictor, response)
controls <- splitted[[as.character(roc$levels[1])]]
cases <- splitted[[as.character(roc$levels[2])]]
thresholds <- roc_utils_thresholds(c(cases, controls), roc$direction)
perfs <- roc_utils_perfs_all(thresholds = thresholds, controls = controls, cases = cases, direction = roc$direction)
# update ROC
roc$sensitivities <- perfs$se * ifelse(roc$percent, 100, 1)
roc$specificities <- perfs$sp * ifelse(roc$percent, 100, 1)
roc$cases <- cases
roc$controls <- controls
roc$predictor <- predictor
roc$response <- response
roc$thresholds <- thresholds
# call smooth.roc and auc.smooth.roc
smooth.roc.call$roc <- roc
smooth.roc <- try(eval(smooth.roc.call), silent = TRUE)
if (methods::is(smooth.roc, "try-error")) {
return(NA)
}
res <- coords.roc(smooth.roc,
x = x, input = input, ret = ret,
best.method = best.method, best.weights = best.weights
)
# Return a random column with "best"
if (length(x) == 1 && x == "best" && nrow(res) != 1) {
return(enforce.best.policy(res, best.policy))
} else {
return(res)
}
}
pROC/R/delong.R 0000644 0001762 0000144 00000012676 15040443562 012670 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez,
# Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Delong's test paired, used by roc.test.roc
delong.paired.test <- function(calcs) {
# Input calcs is a list returned by delong.paired.calculations().
zscore <- with(calcs, d / sig)
if (is.nan(zscore) && calcs$d == 0 && calcs$sig == 0) {
zscore <- 0
} # special case: no difference between theta's produces a NaN
return(zscore)
}
# Delong's test unpaired, used by roc.test.roc
delong.unpaired.test <- function(roc1, roc2) {
nR <- length(roc1$controls)
mR <- length(roc1$cases)
nS <- length(roc2$controls)
mS <- length(roc2$cases)
VR <- delongPlacements(roc1)
VS <- delongPlacements(roc2)
SRX <- sum((VR$X - VR$theta) * (VR$X - VR$theta)) / (mR - 1)
SSX <- sum((VS$X - VS$theta) * (VS$X - VS$theta)) / (mS - 1)
SRY <- sum((VR$Y - VR$theta) * (VR$Y - VR$theta)) / (nR - 1)
SSY <- sum((VS$Y - VS$theta) * (VS$Y - VS$theta)) / (nS - 1)
SR <- SRX / mR + SRY / nR
SS <- SSX / mS + SSY / nS
ntotR <- nR + mR
ntotS <- nS + mS
SSR <- sqrt((SR) + (SS))
t <- (VR$theta - VS$theta) / SSR
df <- ((SR) + (SS))^2 /
(((SR)^2 / (ntotR - 1)) + ((SS)^2 / (ntotS - 1)))
return(c(t, df))
}
ci_auc_delong <- function(roc, conf.level) {
YR <- roc$controls # = C2, n, YRj
XR <- roc$cases # = C1, m, XRi
n <- length(YR)
m <- length(XR)
# If controls or cases have a single observation, we would produce NaNs in SX and SY
if (m <= 1 || n <= 1) {
return(rep(NA, 3))
}
V <- delongPlacements(roc)
SX <- sum((V$X - V$theta) * (V$X - V$theta)) / (m - 1)
SY <- sum((V$Y - V$theta) * (V$Y - V$theta)) / (n - 1)
S <- SX / m + SY / n
ci <- qnorm(c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2), mean = V$theta, sd = sqrt(S))
# In some rare cases we have ci[3] > 1 or ci[1] < 0
ci[ci > 1] <- 1
ci[ci < 0] <- 0
# According to Pepe (p. 107), we should probably be doing something like
# log(roc$auc / (1 - roc$auc)) + pnorm( 1-conf.level/2) * (S / (roc$auc * (1 - roc$auc)))
# log(roc$auc / (1 - roc$auc)) - pnorm( 1-conf.level/2) * (S / (roc$auc * (1 - roc$auc)))
# for logit AUC, so that for AUC:
# exp(log(roc$auc / (1 - roc$auc)) + pnorm( 1-conf.level/2) * (S / (roc$auc * (1 - roc$auc)))) * (1 - roc$auc)
# exp(log(roc$auc / (1 - roc$auc)) - pnorm( 1-conf.level/2) * (S / (roc$auc * (1 - roc$auc)))) * (1 - roc$auc)
# However the bounds are very very much smaller (about 10 times) than bootstrap, which seems unrealistic
# Stay with normal conf interval for now.
return(ci)
}
# function to calculate the CI
ci_delong_paired <- function(calcs, conf.level) {
# Input calcs is a list generated by delong.paired.calculations().
# CI is calculated using the normally distributed pivot given in
# DeLong's 1988 paper.
crit_z <- qnorm(1 - ((1 - conf.level) / 2))
out <- list()
out$upper <- with(calcs, d + crit_z * sig)
out$lower <- with(calcs, d - crit_z * sig)
out$level <- conf.level
return(out)
}
# Runs the placements and main calculations for the paired DeLong's test
# so that they can be easily used by both the test and CI functions.
delong.paired.calculations <- function(roc1, roc2) {
n <- length(roc1$controls)
m <- length(roc1$cases)
VR <- delongPlacements(roc1)
VS <- delongPlacements(roc2)
SX <- matrix(NA, ncol = 2, nrow = 2)
SX[1, 1] <- sum((VR$X - VR$theta) * (VR$X - VR$theta)) / (m - 1)
SX[1, 2] <- sum((VR$X - VR$theta) * (VS$X - VS$theta)) / (m - 1)
SX[2, 1] <- sum((VS$X - VS$theta) * (VR$X - VR$theta)) / (m - 1)
SX[2, 2] <- sum((VS$X - VS$theta) * (VS$X - VS$theta)) / (m - 1)
SY <- matrix(NA, ncol = 2, nrow = 2)
SY[1, 1] <- sum((VR$Y - VR$theta) * (VR$Y - VR$theta)) / (n - 1)
SY[1, 2] <- sum((VR$Y - VR$theta) * (VS$Y - VS$theta)) / (n - 1)
SY[2, 1] <- sum((VS$Y - VS$theta) * (VR$Y - VR$theta)) / (n - 1)
SY[2, 2] <- sum((VS$Y - VS$theta) * (VS$Y - VS$theta)) / (n - 1)
S <- SX / m + SY / n
L <- c(1, -1)
sig <- sqrt(L %*% S %*% L)
d <- VR$theta - VS$theta
return(list("d" = d, "sig" = sig[[1]]))
}
# Calls delongPlacementsCpp safely
# Ensures that the theta value calculated is correct
delongPlacements <- function(roc) {
placements <- delongPlacementsCpp(roc)
# Ensure theta equals auc
auc <- roc$auc / ifelse(roc$percent, 100, 1)
if (!isTRUE(all.equal(placements$theta, auc))) {
sessionInfo <- sessionInfo()
save(roc, placements, sessionInfo, file = "pROC_bug.RData")
stop(sprintf("pROC: error in calculating DeLong's theta: got %.20f instead of %.20f. Diagnostic data saved in pROC_bug.RData. Please report this bug to <%s>.", placements$theta, auc, utils::packageDescription("pROC")$BugReports))
}
return(placements)
}
pROC/R/ci.R 0000644 0001762 0000144 00000005426 15040443562 012006 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci <- function(...) {
UseMethod("ci")
}
ci.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.roc(roc(response, predictor, ...), ...)
}
ci.default <- function(response, predictor, ...) {
roc <- roc.default(response, predictor, ci = FALSE, ...)
if (methods::is(roc, "smooth.roc")) {
return(ci.roc(smooth.roc = roc, ...))
} else {
return(ci.roc(roc = roc, ...))
}
}
ci.smooth.roc <- function(smooth.roc, of = c("auc", "sp", "se", "coords"), ...) {
of <- match.arg(of)
if (of == "auc") {
ci <- ci.auc.smooth.roc(smooth.roc, ...)
} else if (of == "sp") {
ci <- ci.sp.smooth.roc(smooth.roc, ...)
} else if (of == "se") {
ci <- ci.se.smooth.roc(smooth.roc, ...)
} else if (of == "coords") {
ci <- ci.coords.smooth.roc(smooth.roc, ...)
} else {
stop(sprintf("Unknown 'of' for CI: %s", of))
}
return(ci)
}
ci.roc <- function(roc, of = c("auc", "thresholds", "sp", "se", "coords"), ...) {
of <- match.arg(of)
if (of == "auc") {
ci <- ci.auc.roc(roc, ...)
} else if (of == "thresholds") {
ci <- ci.thresholds.roc(roc, ...)
} else if (of == "sp") {
ci <- ci.sp.roc(roc, ...)
} else if (of == "se") {
ci <- ci.se.roc(roc, ...)
} else if (of == "coords") {
ci <- ci.coords.roc(roc, ...)
} else {
stop(sprintf("Unknown 'of' for CI: %s", of))
}
return(ci)
}
ci.multiclass.roc <- function(multiclass.roc, of = "auc", ...) {
stop("CI of a multiclass ROC curve not implemented")
}
ci.multiclass.auc <- function(multiclass.auc, of = "auc", ...) {
stop("CI of a multiclass AUC not implemented")
}
pROC/R/ci.auc.R 0000644 0001762 0000144 00000016160 15040443562 012552 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci.auc <- function(...) {
UseMethod("ci.auc")
}
ci.auc.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci.auc'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.auc.roc(roc.default(response, predictor, ci = FALSE, ...), ...)
}
ci.auc.default <- function(response, predictor, ...) {
roc <- roc.default(response, predictor, ci = FALSE, ...)
if (methods::is(roc, "smooth.roc")) {
return(ci.auc(smooth.roc = roc, ...))
} else {
return(ci.auc(roc = roc, ...))
}
}
ci.auc.auc <- function(auc, ...) {
roc <- attr(auc, "roc")
roc$auc <- auc
ci.auc(roc, reuse.auc = TRUE, ...)
}
ci.auc.smooth.roc <- function(smooth.roc,
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
reuse.auc = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("conf.level must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(smooth.roc)) {
warning("ci.auc() of a ROC curve with AUC == 1 is always 1-1 and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# We need an auc
if (is.null(smooth.roc$auc) | !reuse.auc) {
smooth.roc$auc <- auc(smooth.roc, ...)
}
# Check if called with density.cases or density.controls
if (is.null(smooth.roc$smoothing.args) || is.numeric(smooth.roc$smoothing.args$density.cases) || is.numeric(smooth.roc$smoothing.args$density.controls)) {
stop("Cannot compute CI of ROC curves smoothed with numeric density.controls and density.cases.")
}
# Get the non smoothed roc.
roc <- attr(smooth.roc, "roc")
roc$ci <- NULL # remove potential ci in roc to avoid infinite loop with smooth.roc()
# do all the computations in fraction, re-transform in percent later if necessary
percent <- smooth.roc$percent
smooth.roc$percent <- FALSE
roc$percent <- FALSE
oldauc <- smooth.roc$auc
if (percent) {
attr(smooth.roc$auc, "percent") <- FALSE
if (!identical(attr(smooth.roc$auc, "partial.auc"), FALSE)) {
attr(smooth.roc$auc, "partial.auc") <- attr(smooth.roc$auc, "partial.auc") / 100
}
}
# prepare the calls
smooth.roc.call <- as.call(c(utils::getS3method("smooth", "roc"), smooth.roc$smoothing.args))
auc.args <- attributes(smooth.roc$auc)[grep("partial.auc", names(attributes(smooth.roc$auc)))]
auc.args$allow.invalid.partial.auc.correct <- TRUE
auc.call <- as.call(c(utils::getS3method("auc", "smooth.roc"), auc.args))
if (boot.stratified) {
aucs <- unlist(lapply(seq_len(boot.n), stratified.ci.smooth.auc, roc = roc, smooth.roc.call = smooth.roc.call, auc.call = auc.call))
} else {
aucs <- unlist(lapply(seq_len(boot.n), nonstratified.ci.smooth.auc, roc = roc, smooth.roc.call = smooth.roc.call, auc.call = auc.call))
}
if (sum(is.na(aucs)) > 0) {
warning("NA value(s) produced during bootstrap were ignored.")
aucs <- aucs[!is.na(aucs)]
}
# TODO: Maybe apply a correction (it's in the Tibshirani?) What do Carpenter-Bithell say about that?
# Prepare the return value
ci <- quantile(aucs, c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2))
if (percent) {
ci <- ci * 100
aucs <- aucs * 100
}
attr(ci, "conf.level") <- conf.level
attr(ci, "method") <- "bootstrap"
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "auc") <- oldauc
class(ci) <- c("ci.auc", "ci", class(ci))
return(ci)
}
ci.auc.roc <- function(roc,
conf.level = 0.95,
method = c("delong", "bootstrap"),
boot.n = 2000,
boot.stratified = TRUE,
reuse.auc = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("conf.level must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(roc)) {
warning("ci.auc() of a ROC curve with AUC == 1 is always 1-1 and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# We need an auc
if (is.null(roc$auc) | !reuse.auc) {
roc$auc <- auc(roc, ...)
}
# do all the computations in fraction, re-transform in percent later if necessary
percent <- roc$percent
oldauc <- roc$auc
if (percent) {
roc <- roc_utils_unpercent(roc)
}
# Check the method
if (missing(method) | is.null(method)) {
# determine method if missing
if (has.partial.auc(roc)) {
# partial auc: go for bootstrap
method <- "bootstrap"
} else if ("smooth.roc" %in% class(roc)) {
# smoothing: bootstrap
method <- "bootstrap"
} else {
method <- "delong"
}
} else {
method <- match.arg(method, c("delong", "bootstrap"))
# delong NA to pAUC: warn + change
if (has.partial.auc(roc) && method == "delong") {
stop("DeLong method is not supported for partial AUC. Use method=\"bootstrap\" instead.")
} else if ("smooth.roc" %in% class(roc)) {
stop("DeLong method is not supported for smoothed ROCs. Use method=\"bootstrap\" instead.")
}
}
if (method == "delong") {
ci <- ci_auc_delong(roc, conf.level)
} else {
ci <- ci_auc_bootstrap(roc, conf.level, boot.n, boot.stratified, ...)
}
if (percent) {
ci <- ci * 100
}
attr(ci, "conf.level") <- conf.level
attr(ci, "method") <- method
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "auc") <- oldauc
class(ci) <- c("ci.auc", "ci", class(ci))
return(ci)
}
ci.auc.multiclass.roc <- function(multiclass.roc, ...) {
stop("CI of a multiclass ROC curve not implemented")
}
ci.auc.multiclass.auc <- function(multiclass.auc, ...) {
stop("CI of a multiclass AUC not implemented")
}
pROC/R/power.roc.test.R 0000644 0001762 0000144 00000047132 15040443562 014307 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2011-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
power.roc.test <- function(...) {
UseMethod("power.roc.test")
}
power.roc.test.roc <- function(roc1, roc2, sig.level = 0.05, power = NULL, kappa = NULL,
alternative = c("two.sided", "one.sided"),
reuse.auc = TRUE, method = c("delong", "bootstrap", "obuchowski"),
...) {
# Basic sanity checks
if (!is.null(power) && (power < 0 || power > 1)) {
stop("'power' must range from 0 to 1")
}
if (!is.null(sig.level) && (sig.level < 0 || sig.level > 1)) {
stop("'sig.level' must range from 0 to 1")
}
# check that the AUC of roc1 was computed, or do it now
if (is.null(roc1$auc) | !reuse.auc) {
roc1$auc <- auc(roc1, ...)
}
if (!is.null(attr(roc1$auc, "partial.auc.correct")) && attr(roc1$auc, "partial.auc.correct")) {
stop("Cannot compute power with corrected partial AUCs")
}
roc1 <- roc_utils_unpercent(roc1)
if (!missing(roc2) && !is.null(roc2)) {
alternative <- match.arg(alternative)
if (!is.null(sig.level) && alternative == "two.sided") {
sig.level <- sig.level / 2
}
if ("roc" %in% class(roc2)) {
# check that the AUC of roc2 was computed, or do it now
if (is.null(roc2$auc) | !reuse.auc) {
roc2$auc <- auc(roc2, ...)
}
if (!is.null(attr(roc2$auc, "partial.auc.correct")) && attr(roc2$auc, "partial.auc.correct")) {
stop("Cannot compute power with corrected partial AUCs")
}
roc2 <- roc_utils_unpercent(roc2)
# Make sure the ROC curves are paired
rocs.are.paired <- are.paired(roc1, roc2)
if (!rocs.are.paired) {
stop("The sample size for a difference in AUC cannot be applied to unpaired ROC curves yet.")
}
# Make sure the AUC specifications are identical
attr1 <- attributes(roc1$auc)
attr1$roc <- NULL
attr2 <- attributes(roc2$auc)
attr2$roc <- NULL
if (!identical(attr1, attr2)) {
stop("Different AUC specifications in the ROC curves.")
}
# check that the same region was requested in auc. Otherwise, issue a warning
if (!identical(attributes(roc1$auc)[names(attributes(roc1$auc)) != "roc"], attributes(roc2$auc)[names(attributes(roc2$auc)) != "roc"])) {
warning("Different AUC specifications in the ROC curves. Enforcing the inconsistency, but unexpected results may be produced.")
}
ncontrols <- length(roc1$controls)
ncases <- length(roc1$cases)
if (is.null(kappa)) {
kappa <- ncontrols / ncases
}
# Power test
if (is.null(power)) {
if (is.null(sig.level)) {
stop("'sig.level' or 'power' must be provided.")
}
zalpha <- qnorm(1 - sig.level)
zbeta <- zbeta.obuchowski(roc1, roc2, zalpha, method = method, ...)
power <- pnorm(zbeta)
}
# sig.level
else if (is.null(sig.level)) {
zbeta <- qnorm(power)
zalpha <- zalpha.obuchowski(roc1, roc2, zbeta, method = method, ...)
sig.level <- 1 - pnorm(zalpha)
}
# Sample size
else {
zalpha <- qnorm(1 - sig.level)
zbeta <- qnorm(power)
ncases <- ncases.obuchowski(roc1, roc2, zalpha, zbeta, method = method, ...)
ncontrols <- kappa * ncases
}
# Restore sig.level if two.sided
if (alternative == "two.sided") {
sig.level <- sig.level * 2
}
return(structure(list(ncases = ncases, ncontrols = ncontrols, auc1 = roc1$auc, auc2 = roc2$auc, sig.level = sig.level, power = power, alternative = alternative, method = "Two ROC curves power calculation"), class = "power.htest"))
} else {
stop("'roc2' must be an object of class 'roc'.")
}
} else {
ncontrols <- length(roc1$controls)
ncases <- length(roc1$cases)
if (!is.null(sig.level) && !is.null(power)) {
if (is.null(kappa)) {
kappa <- ncontrols / ncases
}
ncontrols <- ncases <- NULL
}
auc <- auc(roc1)
# TODO: implement this with var() and cov() for the given ROC curve
return(power.roc.test.numeric(ncontrols = ncontrols, ncases = ncases, auc = auc, sig.level = sig.level, power = power, alternative = alternative, kappa = kappa, ...))
}
}
power.roc.test.numeric <- function(auc = NULL, ncontrols = NULL, ncases = NULL, sig.level = 0.05, power = NULL, kappa = 1, alternative = c("two.sided", "one.sided"), ...) {
# basic sanity checks
if (!is.null(ncases) && ncases < 0) {
stop("'ncases' must be positive")
}
if (!is.null(ncontrols) && ncontrols < 0) {
stop("'ncontrols' must be positive")
}
if (!is.null(kappa) && kappa < 0) {
stop("'kappa' must be positive")
}
if (!is.null(power) && (power < 0 || power > 1)) {
stop("'power' must range from 0 to 1")
}
if (!is.null(sig.level) && (sig.level < 0 || sig.level > 1)) {
stop("'sig.level' must range from 0 to 1")
}
# Complete ncontrols and ncases with kappa
if (is.null(ncontrols) && !is.null(ncases) && !is.null(kappa)) {
ncontrols <- kappa * ncases
} else if (is.null(ncases) && !is.null(ncontrols) && !is.null(kappa)) {
ncases <- ncontrols / kappa
}
alternative <- match.arg(alternative)
if (alternative == "two.sided" && !is.null(sig.level)) {
sig.level <- sig.level / 2
}
# determine AUC
if (is.null(auc)) {
if (is.null(ncontrols) || is.null(ncases)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(power)) {
stop("'power' or 'auc' must be provided.")
} else if (is.null(sig.level)) {
stop("'sig.level' or 'auc' must be provided.")
}
kappa <- ncontrols / ncases
zalpha <- qnorm(1 - sig.level)
zbeta <- qnorm(power)
tryCatch(
root <- uniroot(power_roc_test_optimize_auc_function, interval = c(0.5, 1 - 1e-16), ncontrols = ncontrols, ncases = ncases, zalpha = zalpha, zbeta = zbeta),
error = function(e) {
stop(sprintf("AUC could not be solved:\n%s", e))
}
)
auc <- root$root
}
# Determine number of patients (sample size)
else if (is.null(ncases) && is.null(ncontrols)) {
if (is.null(power)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(kappa)) {
stop("'kappa' must be provided.")
} else if (is.null(auc)) {
stop("'auc' or 'ncases' and 'ncontrols' must be provided.")
} else if (is.null(sig.level)) {
stop("'sig.level' or 'ncases' and 'ncontrols' must be provided.")
}
theta <- as.numeric(auc)
Vtheta <- var_theta_obuchowski(theta, kappa)
ncases <- solve.nd(
zalpha = qnorm(1 - sig.level),
zbeta = qnorm(power),
v0 = 0.0792 * (1 + 1 / kappa),
va = Vtheta,
delta = theta - 0.5
)
ncontrols <- kappa * ncases
}
# Determine power
else if (is.null(power)) {
if (is.null(ncontrols) || is.null(ncases)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(auc)) {
stop("'auc' or 'power' must be provided.")
} else if (is.null(sig.level)) {
stop("'sig.level' or 'power' must be provided.")
}
kappa <- ncontrols / ncases
theta <- as.numeric(auc)
Vtheta <- var_theta_obuchowski(theta, kappa)
zbeta <- solve.zbeta(
nd = ncases,
zalpha = qnorm(1 - sig.level),
v0 = 0.0792 * (1 + 1 / kappa),
va = Vtheta,
delta = theta - 0.5
)
power <- pnorm(zbeta)
}
# Determine sig.level
else if (is.null(sig.level)) {
if (is.null(ncontrols) || is.null(ncases)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(auc)) {
stop("'auc' or 'sig.level' must be provided.")
} else if (is.null(power)) {
stop("'power' or 'sig.level' must be provided.")
}
kappa <- ncontrols / ncases
theta <- as.numeric(auc)
Vtheta <- var_theta_obuchowski(theta, kappa)
zalpha <- solve.zalpha(
nd = ncases,
zbeta = qnorm(power),
v0 = 0.0792 * (1 + 1 / kappa),
va = Vtheta,
delta = theta - 0.5
)
sig.level <- 1 - pnorm(zalpha)
} else {
stop("One of 'power', 'sig.level', 'auc', or both 'ncases' and 'ncontrols' must be NULL.")
}
# Restore sig.level if two.sided
if (alternative == "two.sided") {
sig.level <- sig.level * 2
}
return(structure(list(ncases = ncases, ncontrols = ncontrols, auc = auc, sig.level = sig.level, power = power, method = "One ROC curve power calculation"), class = "power.htest"))
}
power.roc.test.list <- function(parslist, ncontrols = NULL, ncases = NULL, sig.level = 0.05, power = NULL, kappa = 1, alternative = c("two.sided", "one.sided"), ...) {
# basic sanity checks
if (!is.null(ncases) && ncases < 0) {
stop("'ncases' must be positive")
}
if (!is.null(ncontrols) && ncontrols < 0) {
stop("'ncontrols' must be positive")
}
if (!is.null(kappa) && kappa < 0) {
stop("'kappa' must be positive")
}
if (!is.null(power) && (power < 0 || power > 1)) {
stop("'power' must range from 0 to 1")
}
if (!is.null(sig.level) && (sig.level < 0 || sig.level > 1)) {
stop("'sig.level' must range from 0 to 1")
}
# Complete ncontrols and ncases with kappa
if (is.null(ncontrols) && !is.null(ncases) && !is.null(kappa)) {
ncontrols <- kappa * ncases
} else if (is.null(ncases) && !is.null(ncontrols) && !is.null(kappa)) {
ncases <- ncontrols / kappa
}
# Warn if anything is passed with ...
if (length(list(...)) > 0) {
warning(paste("The following arguments were ignored:", paste(names(list(...)), collapse = ", ")))
}
alternative <- match.arg(alternative)
if (alternative == "two.sided" && !is.null(sig.level)) {
sig.level <- sig.level / 2
}
# Check required elements of parslist
required <- c("A1", "B1", "A2", "B2", "rn", "ra", "delta")
if (any(!required %in% names(parslist))) {
stop(paste("Missing parameter(s):", paste(required[!required %in% names(parslist)], collapse = ", ")))
}
# Determine number of patients (sample size)
if (is.null(ncases) && is.null(ncontrols)) {
if (is.null(power)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(kappa)) {
stop("'kappa' must be provided.")
} else if (is.null(sig.level)) {
stop("'sig.level' or 'ncases' and 'ncontrols' must be provided.")
}
zalpha <- qnorm(1 - sig.level)
zbeta <- qnorm(power)
ncases <- ncases.obuchowski.params(parslist, zalpha, zbeta, kappa)
ncontrols <- kappa * ncases
}
# Determine power
else if (is.null(power)) {
if (is.null(ncontrols) || is.null(ncases)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(sig.level)) {
stop("'sig.level' or 'power' must be provided.")
}
kappa <- ncontrols / ncases
zalpha <- qnorm(1 - sig.level)
zbeta <- zbeta.obuchowski.params(parslist, zalpha, ncases, kappa)
power <- pnorm(zbeta)
}
# Determine sig.level
else if (is.null(sig.level)) {
if (is.null(ncontrols) || is.null(ncases)) {
stop("'ncontrols' and 'ncases' (or one of these with 'kappa') or 'auc' must be provided.")
} else if (is.null(power)) {
stop("'power' or 'sig.level' must be provided.")
}
kappa <- ncontrols / ncases
zbeta <- qnorm(power)
zalpha <- zalpha.obuchowski.params(parslist, zbeta, ncases, kappa)
sig.level <- 1 - pnorm(zalpha)
} else {
stop("One of 'power', 'sig.level', 'auc', or both 'ncases' and 'ncontrols' must be NULL.")
}
# Restore sig.level if two.sided
if (alternative == "two.sided") {
sig.level <- sig.level * 2
}
return(structure(list(ncases = ncases, ncontrols = ncontrols, sig.level = sig.level, power = power, method = "Two ROC curves power calculation"), class = "power.htest"))
}
#### HIDDEN FUNCTIONS ####
# A function to 'optimize' auc
power_roc_test_optimize_auc_function <- function(x, ncontrols, ncases, zalpha, zbeta) {
kappa <- ncontrols / ncases
Vtheta <- var_theta_obuchowski(x, kappa)
(zalpha * sqrt(0.0792 * (1 + 1 / kappa)) + zbeta * sqrt(Vtheta))^2 / (x - 0.5)^2 - ncases
}
# Compute variance of a delta from a 'covvar' list (see 'covvar' below)
var_delta_covvar <- function(covvar) {
covvar$var1 + covvar$var2 - 2 * covvar$cov12
}
# Compute variance of a delta from a 'covvar' list (see 'covvar' below)
# under the null hypothesis
# roc1 taken as reference.
var0.delta.covvar <- function(covvar) {
2 * covvar$var1 - 2 * covvar$cov12
}
# Compute the number of cases with Obuchowski formula and var(... method=method)
ncases.obuchowski <- function(roc1, roc2, zalpha, zbeta, method, ...) {
delta <- roc1$auc - roc2$auc
covvar <- covvar(roc1, roc2, method, ...)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
nd <- solve.nd(
zalpha = zalpha,
zbeta = zbeta,
v0 = v0, va = va,
delta = delta
)
return(nd)
}
# Compute the number of cases with Obuchowski formula from params
ncases.obuchowski.params <- function(parslist, zalpha, zbeta, kappa) {
covvar <- list(
var1 = var_params_obuchowski(parslist$A1, parslist$B1, kappa, parslist$FPR11, parslist$FPR12),
var2 = var_params_obuchowski(parslist$A2, parslist$B2, kappa, parslist$FPR21, parslist$FPR22),
cov12 = cov_params_obuchowski(parslist$A1, parslist$B1, parslist$A2, parslist$B2, parslist$rn, parslist$ra, kappa, parslist$FPR11, parslist$FPR12, parslist$FPR21, parslist$FPR22)
)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
nd <- solve.nd(
zalpha = zalpha,
zbeta = zbeta,
v0 = v0, va = va,
delta = parslist$delta
)
return(nd)
}
# Compute the z alpha with Obuchowski formula and var(... method=method)
zalpha.obuchowski <- function(roc1, roc2, zbeta, method, ...) {
delta <- roc1$auc - roc2$auc
ncases <- length(roc1$cases)
covvar <- covvar(roc1, roc2, method, ...)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
zalpha <- solve.zalpha(
nd = ncases,
zbeta = zbeta,
v0 = v0, va = va,
delta = delta
)
return(zalpha)
}
# Compute the z alpha with Obuchowski formula from params
zalpha.obuchowski.params <- function(parslist, zbeta, ncases, kappa) {
covvar <- list(
var1 = var_params_obuchowski(parslist$A1, parslist$B1, kappa, parslist$FPR11, parslist$FPR12),
var2 = var_params_obuchowski(parslist$A2, parslist$B2, kappa, parslist$FPR21, parslist$FPR22),
cov12 = cov_params_obuchowski(parslist$A1, parslist$B1, parslist$A2, parslist$B2, parslist$rn, parslist$ra, kappa, parslist$FPR11, parslist$FPR12, parslist$FPR21, parslist$FPR22)
)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
zalpha <- solve.zalpha(
nd = ncases,
zbeta = zbeta,
v0 = v0, va = va,
delta = parslist$delta
)
return(zalpha)
}
# Compute the z beta with Obuchowski formula and var(... method=method)
zbeta.obuchowski <- function(roc1, roc2, zalpha, method, ...) {
delta <- roc1$auc - roc2$auc
ncases <- length(roc1$cases)
covvar <- covvar(roc1, roc2, method, ...)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
zbeta <- solve.zbeta(
nd = ncases,
zalpha = zalpha,
v0 = v0, va = va,
delta = delta
)
return(zbeta)
}
# Compute the z beta with Obuchowski formula from params
zbeta.obuchowski.params <- function(parslist, zalpha, ncases, kappa) {
covvar <- list(
var1 = var_params_obuchowski(parslist$A1, parslist$B1, kappa, parslist$FPR11, parslist$FPR12),
var2 = var_params_obuchowski(parslist$A2, parslist$B2, kappa, parslist$FPR21, parslist$FPR22),
cov12 = cov_params_obuchowski(parslist$A1, parslist$B1, parslist$A2, parslist$B2, parslist$rn, parslist$ra, kappa, parslist$FPR11, parslist$FPR12, parslist$FPR21, parslist$FPR22)
)
v0 <- var0.delta.covvar(covvar)
va <- var_delta_covvar(covvar)
a <- va
zbeta <- solve.zbeta(
nd = ncases,
zalpha = zalpha,
v0 = v0, va = va,
delta = parslist$delta
)
return(zbeta)
}
solve.zbeta <- function(nd, zalpha, v0, va, delta) {
# Solve for z_\beta in Obuchowski formula:
# See formula 2 in Obuchowsk & McClish 1997 (2 ROC curves)
# or formula 2 in Obuchowski et al 2004 (1 ROC curve)
# The formula is of the form:
# nd = (z_alpha * sqrt(v0) - z_beta * sqrt(va)) / delta ^ 2
# Re-organized:
# z_beta = (sqrt(nd * delta ^ 2) - z_alpha * sqrt(v0)) / sqrt(va)
# @param nd: number of diseased patients (or abornmal, N_A in Obuchowsk & McClish 1997)
# @param zalpha: upper \alpha (sig.level) percentile of the standard normal distribution
# @param v0 the null variance associated with z_alpha
# @param va: the alternative variance associated with z_beta
# @param delta: the difference in AUC
return((sqrt(nd * delta^2) - zalpha * sqrt(v0)) / sqrt(va))
}
solve.nd <- function(zalpha, zbeta, v0, va, delta) {
# Solve for number of diseased (abnormal) patients in Obuchowski formula:
# See formula 2 in Obuchowsk & McClish 1997 (2 ROC curves)
# or formula 2 in Obuchowski et al 2004 (1 ROC curve)
# nd = (z_alpha * sqrt(v0) - z_beta * sqrt(va)) / delta ^ 2
# @param zalpha: upper \alpha (sig.level) percentile of the standard normal distribution
# @param zbeta: upper \beta (power) percentile of the standard normal distribution
# @param v0 the null variance associated with z_alpha
# @param va: the alternative variance associated with z_beta
# @param delta: the difference in AUC
return((zalpha * sqrt(v0) + zbeta * sqrt(va))^2 / delta^2)
}
solve.zalpha <- function(nd, zbeta, v0, va, delta) {
# Solve for z_\alpha in Obuchowski formula:
# See formula 2 in Obuchowsk & McClish 1997 (2 ROC curves)
# or formula 2 in Obuchowski et al 2004 (1 ROC curve)
# The formula is of the form:
# nd = (z_alpha * sqrt(v0) - z_beta * sqrt(va)) / delta ^ 2
# Re-organized:
# z_alpha = (sqrt(nd * delta ^ 2) - z_beta * sqrt(va)) / sqrt(v0)
# @param nd: number of diseased patients (or abornmal, N_A in Obuchowsk & McClish 1997)
# @param zbeta: upper \beta (power) percentile of the standard normal distribution
# @param v0 the null variance associated with z_alpha
# @param va: the alternative variance associated with z_beta
# @param delta: the difference in AUC
return((sqrt(nd * delta^2) - zbeta * sqrt(va)) / sqrt(v0))
}
# Compute var and cov of two ROC curves by bootstrap in a single bootstrap run
covvar <- function(roc1, roc2, method, ...) {
cov12 <- cov(roc1, roc2, boot.return = TRUE, method = method, ...)
if (!is.null(attr(cov12, "resampled.values"))) {
var1 <- var(attr(cov12, "resampled.values")[, 1])
var2 <- var(attr(cov12, "resampled.values")[, 2])
attr(cov12, "resampled.values") <- NULL
} else {
var1 <- var(roc1, method = method, ...)
var2 <- var(roc2, method = method, ...)
}
ncases <- length(roc1$cases)
return(list(var1 = var1 * ncases, var2 = var2 * ncases, cov12 = cov12 * ncases))
}
pROC/R/ggroc.R 0000644 0001762 0000144 00000007032 15040443562 012507 0 ustar ligges users # Returns the coords as a data.frame in the right ordering for ggplot2
get.coords.for.ggplot <- function(roc, ignore.partial.auc) {
df <- coords(roc, "all", transpose = FALSE, ignore.partial.auc = ignore.partial.auc)
df[["1-specificity"]] <- ifelse(roc$percent, 100, 1) - df[["specificity"]]
return(df[rev(seq(nrow(df))), ])
}
get.aes.for.ggplot <- function(roc, legacy.axes, extra_aes = c(), group = FALSE) {
# Prepare the aesthetics
if (roc$percent) {
if (legacy.axes) {
aes_list <- list(
x = "1-specificity",
y = "sensitivity"
)
xlims <- ggplot2::scale_x_continuous(lim = c(0, 100))
} else {
aes_list <- list(
x = "specificity",
y = "sensitivity"
)
xlims <- ggplot2::scale_x_reverse(lim = c(100, 0))
}
} else {
if (legacy.axes) {
aes_list <- list(
x = "1-specificity",
y = "sensitivity"
)
xlims <- ggplot2::scale_x_continuous(lim = c(0, 1))
} else {
aes_list <- list(
x = "specificity",
y = "sensitivity"
)
xlims <- ggplot2::scale_x_reverse(lim = c(1, 0))
}
}
# Add extra aes
for (ae in extra_aes) {
aes_list[[ae]] <- "name"
}
# Add group
if (group) {
aes_list[["group"]] <- "name"
}
.data <- rlang::.data
quoted_aes_list <- lapply(aes_list, function(x) ggplot2::expr(.data[[x]]))
aes <- do.call(ggplot2::aes, quoted_aes_list)
return(list(aes = aes, xlims = xlims))
}
load.ggplot2 <- function() {
if (!isNamespaceLoaded("ggplot2")) {
message("You may need to call library(ggplot2) if you want to add layers, etc.")
}
load.suggested.package("ggplot2")
}
ggroc <- function(data, ...) {
UseMethod("ggroc")
}
ggroc.roc <- function(data, legacy.axes = FALSE, ...) {
load.ggplot2()
# Get the roc data with coords
df <- get.coords.for.ggplot(data, ignore.partial.auc = TRUE)
# Prepare the aesthetics
aes <- get.aes.for.ggplot(data, legacy.axes)
# Do the plotting
ggplot2::ggplot(df) +
ggplot2::geom_line(aes$aes, ...) +
aes$xlims
}
ggroc.smooth.roc <- ggroc.roc
ggroc.list <- function(data, aes = c("colour", "alpha", "linetype", "linewidth", "size", "group"), legacy.axes = FALSE, ...) {
load.ggplot2()
if (missing(aes)) {
aes <- "colour"
}
aes <- sub("color", "colour", aes)
aes <- match.arg(aes, several.ok = TRUE)
# Make sure data is a list and every element is a roc object
if (!all(sapply(data, methods::is, "roc") | sapply(data, methods::is, "smooth.roc"))) {
stop("All elements in 'data' must be 'roc' objects.")
}
# Make sure percent is consistent
percents <- sapply(data, `[[`, "percent")
if (!(all(percents) || all(!percents))) {
stop("ROC curves use percent inconsistently and cannot be plotted together")
}
# Make sure the data is a named list
if (is.null(names(data))) {
names(data) <- seq(data)
}
# Make sure names are unique:
if (any(duplicated(names(data)))) {
stop("Names of 'data' must be unique")
}
# Get the coords
coord.dfs <- sapply(data, get.coords.for.ggplot, simplify = FALSE, ignore.partial.auc = TRUE)
# Add a "name" colummn
for (i in seq_along(coord.dfs)) {
coord.dfs[[i]]$name <- names(coord.dfs)[i]
}
# Make a big data.frame
coord.dfs <- do.call(rbind, coord.dfs)
coord.dfs$name <- factor(coord.dfs$name, as.vector(names(data)))
# Prepare the aesthetics
aes.ggplot <- get.aes.for.ggplot(data[[1]], legacy.axes, aes, group = TRUE)
# Do the plotting
ggplot2::ggplot(coord.dfs, aes.ggplot$aes) +
ggplot2::geom_line(...) +
aes.ggplot$xlims
}
pROC/R/roc.test.R 0000644 0001762 0000144 00000043715 15040443562 013157 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
roc.test <- function(...) {
UseMethod("roc.test")
}
roc.test.formula <- function(formula, data, ...) {
data.missing <- missing(data)
call <- match.call()
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = call
)
if (length(roc.data$predictor.name) != 2) {
stop("Invalid formula: exactly 2 predictors are required in a formula of type response~predictor1+predictor2.")
}
response <- roc.data$response
predictors <- roc.data$predictors
testres <- roc.test.default(response, predictors, ...)
testres$call <- call
# data.names for pretty print()ing
if (data.missing) {
testres$data.names <- sprintf("%s and %s by %s (%s, %s)", roc.data$predictor.names[1], roc.data$predictor.names[2], roc.data$response.name, testres$roc1$levels[1], testres$roc1$levels[2])
} else {
testres$data.names <- sprintf("%s and %s in %s by %s (%s, %s)", roc.data$predictor.names[1], roc.data$predictor.names[2], deparse(substitute(data)), roc.data$response.name, testres$roc1$levels[1], testres$roc1$levels[2])
}
return(testres)
}
roc.test.default <- function(response, predictor1, predictor2 = NULL, na.rm = TRUE, method = NULL, ...) {
if (is.matrix(predictor1) | is.data.frame(predictor1)) {
if (!is.null(predictor2)) {
stop("Predictor2 must not be specified if predictor1 is a matrix or a data.frame.")
}
if (dim(predictor1)[2] == 2 & length(response) == dim(predictor1)[1]) {
roc1 <- roc(response, predictor1[, 1], ...)
roc2 <- roc(response, predictor1[, 2], ...)
if (!is.null(names(predictor1))) {
data.names <- sprintf("%s and %s in %s by %s (%s, %s)", names(predictor1)[1], names(predictor1)[2], deparse(substitute(predictor1)), deparse(substitute(response)), roc1$levels[1], roc1$levels[2])
} else if (!is.null(colnames(predictor1))) {
data.names <- sprintf("%s and %s in %s by %s (%s, %s)", colnames(predictor1)[1], colnames(predictor1)[2], deparse(substitute(predictor1)), deparse(substitute(response)), roc1$levels[1], roc1$levels[2])
} else {
data.names <- sprintf("%s by %s (%s, %s)", deparse(substitute(predictor1)), deparse(substitute(response)), roc1$levels[1], roc1$levels[2])
}
} else {
stop("Wrong dimension for predictor1 as a matrix or a data.frame.")
}
} else {
if (missing(predictor2)) {
stop("Missing argument predictor2 with predictor1 as a vector.")
}
# Need to remove NAs
if (na.rm) {
nas <- is.na(response) | is.na(predictor1) | is.na(predictor2)
response <- response[!nas]
predictor1 <- predictor1[!nas]
predictor2 <- predictor2[!nas]
}
roc1 <- roc(response, predictor1, ...)
roc2 <- roc(response, predictor2, ...)
call <- match.call()
data.names <- sprintf("%s and %s by %s (%s, %s)", deparse(call$predictor1), deparse(call$predictor2), deparse(call$response), roc1$levels[1], roc1$levels[2])
}
test <- roc.test.roc(roc1, roc2, method = method, ...)
test$data.names <- data.names
return(test)
}
roc.test.auc <- function(roc1, roc2, ...) {
# First save the names
data.names <- paste(deparse(substitute(roc1)), "and", deparse(substitute(roc2)))
# Change roc1 from an auc to a roc object but keep the auc specifications
auc1 <- roc1
attr(auc1, "roc") <- NULL
roc1 <- attr(roc1, "roc")
roc1$auc <- auc1
# Pass to roc.test.roc
testres <- roc.test.roc(roc1, roc2, ...)
testres$call <- match.call()
testres$data.names <- data.names
return(testres)
}
roc.test.smooth.roc <- function(roc1, roc2, ...) {
testres <- roc.test.roc(roc1, roc2, ...)
testres$call <- match.call()
testres$data.names <- paste(deparse(substitute(roc1)), "and", deparse(substitute(roc2)))
return(testres)
}
roc.test.roc <- function(roc1, roc2,
method = c("delong", "bootstrap", "venkatraman", "sensitivity", "specificity"),
sensitivity = NULL, specificity = NULL,
alternative = c("two.sided", "less", "greater"),
paired = NULL,
reuse.auc = TRUE,
boot.n = 2000, boot.stratified = TRUE,
ties.method = "first",
progress = NULL,
parallel = FALSE,
conf.level = 0.95,
...) {
alternative <- match.arg(alternative)
data.names <- paste(deparse(substitute(roc1)), "and", deparse(substitute(roc2)))
# If roc2 is an auc, take the roc but keep the auc specifications
if (methods::is(roc2, "auc")) {
auc2 <- roc2
attr(auc2, "roc") <- NULL
roc2 <- attr(roc2, "roc")
roc2$auc <- auc2
}
if (roc_utils_is_perfect_curve(roc1) && roc_utils_is_perfect_curve(roc2)) {
warning("roc.test() of two ROC curves with AUC == 1 has always p.value = 1 and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# store which objects are smoothed, and how
smoothing.args <- list()
if (methods::is(roc1, "smooth.roc")) {
smoothing.args$roc1 <- roc1$smoothing.args
smoothing.args$roc1$smooth <- TRUE
roc1 <- attr(roc1, "roc")
} else {
smoothing.args$roc1 <- list(smooth = FALSE)
}
if (methods::is(roc2, "smooth.roc")) {
smoothing.args$roc2 <- roc2$smoothing.args
smoothing.args$roc2$smooth <- TRUE
roc2 <- attr(roc2, "roc")
} else {
smoothing.args$roc2 <- list(smooth = FALSE)
}
# Check if we do a paired or unpaired roc.test
if (is.null(paired)) {
# then determine whether the rocs are paired or not
rocs.are.paired <- are.paired(roc1, roc2, return.paired.rocs = TRUE, reuse.auc = TRUE, reuse.ci = FALSE, reuse.smooth = TRUE)
if (rocs.are.paired) {
paired <- TRUE
roc1 <- attr(rocs.are.paired, "roc1")
roc2 <- attr(rocs.are.paired, "roc2")
} else {
paired <- FALSE
roc1 <- roc1
roc2 <- roc2
}
} else if (paired) {
# make sure the rocs are really paired
rocs.are.paired <- rocs.are.paired <- are.paired(roc1, roc2, return.paired.rocs = TRUE, reuse.auc = TRUE, reuse.ci = FALSE, reuse.smooth = TRUE)
if (!rocs.are.paired) {
stop("The paired ROC test cannot be applied to unpaired curves.")
}
roc1 <- attr(rocs.are.paired, "roc1")
roc2 <- attr(rocs.are.paired, "roc2")
} else { # assume unpaired
rocs.are.paired <- are.paired(roc1, roc2, return.paired.rocs = FALSE)
if (rocs.are.paired) {
warning("The ROC curves seem to be paired. Consider performing a paired roc.test.")
}
roc1 <- roc1
roc2 <- roc2
}
# check that the AUC was computed, or do it now
if (is.null(roc1$auc) | !reuse.auc) {
if (smoothing.args$roc1$smooth) {
roc1$auc <- auc(smooth.roc = do.call("smooth.roc", c(list(roc = roc1), smoothing.args$roc1)), ...)
# remove partial.auc.* arguments that are now in roc1$auc and that will mess later processing
# (formal argument "partial.auc(.*)" matched by multiple actual arguments)
# This removal should be safe because we always use smoothing.args with roc1 in the following processing,
# however it is a potential source of bugs.
smoothing.args$roc1$partial.auc <- NULL
smoothing.args$roc1$partial.auc.correct <- NULL
smoothing.args$roc1$partial.auc.focus <- NULL
} else {
roc1$auc <- auc(roc1, ...)
}
}
if (is.null(roc2$auc) | !reuse.auc) {
if (smoothing.args$roc2$smooth) {
roc2$auc <- auc(smooth.roc = do.call("smooth.roc", c(list(roc = roc2), smoothing.args$roc2)), ...)
# remove partial.auc.* arguments that are now in roc1$auc and that will mess later processing
# (formal argument "partial.auc(.*)" matched by multiple actual arguments)
# This removal should be safe because we always use smoothing.args with roc2 in the following processing,
# however it is a potential source of bugs.
smoothing.args$roc2$partial.auc <- NULL
smoothing.args$roc2$partial.auc.correct <- NULL
smoothing.args$roc2$partial.auc.focus <- NULL
} else {
roc2$auc <- auc(roc2, ...)
}
}
# check that the same region was requested in auc. Otherwise, issue a warning
if (!identical(attributes(roc1$auc)[names(attributes(roc1$auc)) != "roc"], attributes(roc2$auc)[names(attributes(roc2$auc)) != "roc"])) {
warning("Different AUC specifications in the ROC curves. Enforcing the inconsistency, but unexpected results may be produced.")
}
# check that the same smoothing params were requested in auc. Otherwise, issue a warning
if (!identical(smoothing.args$roc1, smoothing.args$roc2)) {
warning("Different smoothing parameters in the ROC curves. Enforcing the inconsistency, but unexpected results may be produced.")
}
# Check the method
if (missing(method) | is.null(method)) {
# determine method if missing
if (has.partial.auc(roc1)) {
# partial auc: go for bootstrap
method <- "bootstrap"
} else if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
# smoothing in one or both: bootstrap
method <- "bootstrap"
} else if (roc1$direction != roc2$direction) {
# delong doesn't work well with opposite directions (will report high significance if roc1$auc and roc2$auc are similar and high)
method <- "bootstrap"
} else {
method <- "delong"
}
} else {
method <- match.arg(method)
if (method == "delong") {
# delong NA to pAUC: warn + change
if (has.partial.auc(roc1) || has.partial.auc(roc2)) {
stop("DeLong's test is not supported for partial AUC. Use method=\"bootstrap\" instead.")
}
if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
stop("DeLong's test is not supported for smoothed ROCs. Use method=\"bootstrap\" instead.")
}
if (roc1$direction != roc2$direction) {
warning("DeLong's test should not be applied to ROC curves with a different direction.")
}
# Check if conf.level is specified correctly. This is currently
# only used for the delong paired method, which is why it lives
# here for now.
if (!is.numeric(conf.level)) {
stop("conf.level must be numeric between 0 and 1.")
} else if (0 > conf.level | 1 < conf.level) {
stop("conf.level must be between 0 and 1.")
}
} else if (method == "venkatraman") {
if (has.partial.auc(roc1)) {
stop("Partial AUC is not supported for Venkatraman's test.")
}
if (smoothing.args$roc1$smooth || smoothing.args$roc2$smooth) {
stop("Venkatraman's test is not supported for smoothed ROCs")
}
if (roc1$direction != roc2$direction) {
warning("Venkatraman's test should not be applied to ROC curves with different directions.")
}
if (alternative != "two.sided") {
stop("Only two-sided tests are available for Venkatraman.")
}
}
}
# Prepare the return value htest
if (smoothing.args$roc1$smooth) {
estimate <- do.call("smooth.roc", c(list(roc = roc1), smoothing.args$roc1))$auc
} else {
estimate <- roc1$auc
}
if (smoothing.args$roc2$smooth) {
estimate <- c(estimate, do.call("smooth.roc", c(list(roc = roc2), smoothing.args$roc2))$auc)
} else {
estimate <- c(estimate, roc2$auc)
}
if (identical(attr(roc1$auc, "partial.auc"), FALSE)) {
nest <- paste(ifelse(smoothing.args$roc1$smooth, "Smoothed ", ""), "AUC of roc1", sep = "")
} else {
nest <- paste(ifelse(attr(roc1$auc, "partial.auc.correct"), "Corrected ", ""),
ifelse(smoothing.args$roc1$smooth, "Smoothed ", ""),
"pAUC (", attr(roc1$auc, "partial.auc")[1], "-", attr(roc1$auc, "partial.auc")[2], " ", attr(roc1$auc, "partial.auc.focus"),
") of roc1",
sep = ""
)
}
if (identical(attr(roc2$auc, "partial.auc"), FALSE)) {
nest <- c(nest, paste(ifelse(smoothing.args$roc2$smooth, "Smoothed ", ""), "AUC of roc2", sep = ""))
} else {
nest <- c(nest, paste(ifelse(attr(roc2$auc, "partial.auc.correct"), "Corrected ", ""),
ifelse(smoothing.args$roc2$smooth, "Smoothed ", ""),
"pAUC (", attr(roc2$auc, "partial.auc")[1], "-", attr(roc2$auc, "partial.auc")[2], " ", attr(roc2$auc, "partial.auc.focus"),
") of roc2",
sep = ""
))
}
nest <- sub("Corrected Smoothed", "Corrected smoothed", nest) # no upper on smoothed if corrected.
names(estimate) <- nest
null.value <- 0
names(null.value) <- "difference in AUC"
htest <- list(
alternative = alternative,
data.names = data.names,
estimate = estimate,
null.value = null.value
)
class(htest) <- "htest"
if (method == "delong") {
if (paired) {
delong.calcs <- delong.paired.calculations(roc1, roc2)
stat <- delong.paired.test(delong.calcs)
stat.ci <- ci_delong_paired(delong.calcs, conf.level)
names(stat) <- "Z"
htest$statistic <- stat
htest$method <- "DeLong's test for two correlated ROC curves"
htest$conf.int <- c(stat.ci$lower, stat.ci$upper)
attr(htest$conf.int, "conf.level") <- stat.ci$level
if (alternative == "two.sided") {
pval <- 2 * pnorm(-abs(stat))
} else if (alternative == "greater") {
pval <- pnorm(-stat)
} else {
pval <- pnorm(stat)
}
htest$p.value <- pval
} else {
stats <- delong.unpaired.test(roc1, roc2)
stat <- stats[1]
df <- stats[2]
htest$statistic <- c("D" = stat)
htest$parameter <- c("df" = df)
htest$method <- "DeLong's test for two ROC curves"
if (alternative == "two.sided") {
pval <- 2 * pt(-abs(stat), df = df)
} else if (alternative == "greater") {
pval <- pt(-stat, df = df)
} else {
pval <- pt(stat, df = df)
}
htest$p.value <- pval
}
} else if (method == "venkatraman") {
if (paired) {
stats <- venkatraman.paired.test(roc1, roc2, boot.n, ties.method)
htest$method <- "Venkatraman's test for two paired ROC curves"
} else {
stats <- venkatraman.unpaired.test(roc1, roc2, boot.n, ties.method)
htest$method <- "Venkatraman's test for two unpaired ROC curves"
}
stat <- stats[[1]]
names(stat) <- "E"
htest$statistic <- stat
parameter <- c(boot.n)
names(parameter) <- "boot.n"
htest$parameter <- parameter
pval <- sum(stats[[2]] >= stats[[1]]) / boot.n
htest$p.value <- pval
names(htest$null.value) <- "difference in at least one ROC operating point"
htest$estimate <- NULL # AUC not relevant in venkatraman
} else { # method == "bootstrap" or "sensitivity" or "specificity"
# Check if called with density.cases or density.controls
if (is.null(smoothing.args) || is.numeric(smoothing.args$density.cases) || is.numeric(smoothing.args$density.controls)) {
stop("Cannot compute the statistic on ROC curves smoothed with numeric density.controls and density.cases.")
}
if (method == "specificity") {
if (!is.numeric(specificity) || length(specificity) != 1) {
stop("Argument 'specificity' must be numeric of length 1 for a specificity test.")
}
stat <- bootstrap.test(roc1, roc2, "sp", specificity, paired, boot.n, boot.stratified, smoothing.args)
if (paired) {
htest$method <- "Specificity test for two correlated ROC curves"
} else {
htest$method <- "Specificity test for two ROC curves"
}
names(htest$null.value) <- sprintf(
"difference in sensitivity at %s specificity",
specificity
)
} else if (method == "sensitivity") {
if (!is.numeric(sensitivity) || length(sensitivity) != 1) {
stop("Argument 'sensitivity' must be numeric of length 1 for a sensitivity test.")
}
stat <- bootstrap.test(roc1, roc2, "se", sensitivity, paired, boot.n, boot.stratified, smoothing.args)
if (paired) {
htest$method <- "Sensitivity test for two correlated ROC curves"
} else {
htest$method <- "Sensitivity test for two ROC curves"
}
names(htest$null.value) <- sprintf(
"difference in specificity at %s sensitivity",
sensitivity
)
} else {
stat <- bootstrap.test(roc1, roc2, "boot", NULL, paired, boot.n, boot.stratified, smoothing.args)
if (paired) {
htest$method <- "Bootstrap test for two correlated ROC curves"
} else {
htest$method <- "Bootstrap test for two ROC curves"
}
}
stat <- as.vector(stat) # remove auc attributes
names(stat) <- "D"
htest$statistic <- stat
parameter <- c(boot.n, boot.stratified)
names(parameter) <- c("boot.n", "boot.stratified")
htest$parameter <- parameter
if (alternative == "two.sided") {
pval <- 2 * pnorm(-abs(stat))
} else if (alternative == "greater") {
pval <- pnorm(-stat)
} else {
pval <- pnorm(stat)
}
htest$p.value <- pval
}
htest$roc1 <- roc1
htest$roc2 <- roc2
# Remove name from p value
htest$p.value <- unname(htest$p.value)
# Restore smoothing if necessary
if (smoothing.args$roc1$smooth) {
htest$roc1 <- do.call("smooth.roc", c(list(roc = roc1), smoothing.args$roc1))
}
if (smoothing.args$roc2$smooth) {
htest$roc2 <- do.call("smooth.roc", c(list(roc = roc2), smoothing.args$roc2))
}
return(htest)
}
pROC/R/onLoad.R 0000644 0001762 0000144 00000004311 15040443562 012617 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
.onAttach <- function(lib, pkg) {
# Remove deprecated pROCProgress option
if (!is.null(getOption("pROCProgress")) && getOption("pROCProgress")$name != "none") {
packageStartupMessage("Progress bars are deprecated in pROC 1.19. Removing pROCProgress option.")
}
options("pROCProgress" = NULL)
}
.parseRcppVersion <- function(rcpp.version) {
# Parses Rcpp version integer into a string.
# Eg "65538" -> "1.0.2"
rcpp.version <- as.integer(rcpp.version)
major <- rcpp.version %/% 65536
rcpp.version <- rcpp.version - major * 65536
minor <- rcpp.version %/% 256
rcpp.version <- rcpp.version - minor * 256
rev <- rcpp.version
return(sprintf("%s.%s.%s", major, minor, rev))
}
.checkRcppVersion <- function() {
# Check runtime version of Rcpp is the same than we had at compile time
runtime_version <- package_version(utils::packageVersion("Rcpp"))
build_version <- package_version(.parseRcppVersion(RcppVersion()))
if (runtime_version != build_version) {
warning(sprintf(
"It seems pROC was compiled with Rcpp version %s, but %s is available now. Please re-install pROC to avoid problems: install.packages(\"pROC\").",
build_version, runtime_version
))
}
}
.onAttach <- function(lib, pkg) {
packageStartupMessage("Type 'citation(\"pROC\")' for a citation.")
}
pROC/R/ci.se.R 0000644 0001762 0000144 00000013076 15040443562 012414 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
ci.se <- function(...) {
UseMethod("ci.se")
}
ci.se.formula <- function(formula, data, ...) {
data.missing <- missing(data)
roc.data <- roc_utils_extract_formula(formula, data, ...,
data.missing = data.missing,
call = match.call()
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'ci.se'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
ci.se(roc(response, predictor, ci = FALSE, ...), ...)
}
ci.se.default <- function(response, predictor, ...) {
if (methods::is(response, "multiclass.roc") || methods::is(response, "multiclass.auc")) {
stop("'ci.sp' not available for multiclass ROC curves.")
}
roc <- roc.default(response, predictor, ci = FALSE, ...)
if (methods::is(roc, "smooth.roc")) {
return(ci.se(smooth.roc = roc, ...))
} else {
return(ci.se(roc = roc, ...))
}
}
ci.se.smooth.roc <- function(smooth.roc,
specificities = seq(0, 1, .1) * ifelse(smooth.roc$percent, 100, 1),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(smooth.roc)) {
warning("ci.se() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# Check if called with density.cases or density.controls
if (is.null(smooth.roc$smoothing.args) || is.numeric(smooth.roc$smoothing.args$density.cases) || is.numeric(smooth.roc$smoothing.args$density.controls)) {
stop("Cannot compute CI of ROC curves smoothed with numeric density.controls and density.cases.")
}
# Get the non smoothed roc.
roc <- attr(smooth.roc, "roc")
roc$ci <- NULL # remove potential ci in roc to avoid infinite loop with smooth.roc()
# prepare the calls
smooth.roc.call <- as.call(c(utils::getS3method("smooth", "roc"), smooth.roc$smoothing.args))
if (boot.stratified) {
perfs <- do.call(rbind, lapply(seq_len(boot.n), stratified.ci.smooth.se, roc = roc, sp = specificities, smooth.roc.call = smooth.roc.call))
} else {
perfs <- do.call(rbind, lapply(seq_len(boot.n), nonstratified.ci.smooth.se, roc = roc, sp = specificities, smooth.roc.call = smooth.roc.call))
}
if (any(is.na(perfs))) {
warning("NA value(s) produced during bootstrap were ignored.")
perfs <- perfs[!apply(perfs, 1, function(x) any(is.na(x))), ]
}
ci <- t(apply(perfs, 2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)))
rownames(ci) <- paste(specificities, ifelse(roc$percent, "%", ""), sep = "")
class(ci) <- c("ci.se", "ci", class(ci))
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "specificities") <- specificities
attr(ci, "roc") <- smooth.roc
return(ci)
}
ci.se.roc <- function(roc,
specificities = seq(0, 1, .1) * ifelse(roc$percent, 100, 1),
conf.level = 0.95,
boot.n = 2000,
boot.stratified = TRUE,
progress = NULL,
parallel = FALSE,
...) {
if (conf.level > 1 | conf.level < 0) {
stop("'conf.level' must be within the interval [0,1].")
}
if (roc_utils_is_perfect_curve(roc)) {
warning("ci.se() of a ROC curve with AUC == 1 is always a null interval and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
if (boot.stratified) {
perfs <- do.call(rbind, lapply(seq_len(boot.n), stratified.ci.se, roc = roc, sp = specificities))
} else {
perfs <- do.call(rbind, lapply(seq_len(boot.n), nonstratified.ci.se, roc = roc, sp = specificities))
}
if (any(is.na(perfs))) {
warning("NA value(s) produced during bootstrap were ignored.")
perfs <- perfs[!apply(perfs, 1, function(x) any(is.na(x))), ]
}
ci <- t(apply(perfs, 2, quantile, probs = c(0 + (1 - conf.level) / 2, .5, 1 - (1 - conf.level) / 2)))
rownames(ci) <- paste(specificities, ifelse(roc$percent, "%", ""), sep = "")
class(ci) <- c("ci.se", "ci", class(ci))
attr(ci, "conf.level") <- conf.level
attr(ci, "boot.n") <- boot.n
attr(ci, "boot.stratified") <- boot.stratified
attr(ci, "specificities") <- specificities
attr(ci, "roc") <- roc
return(ci)
}
pROC/R/plot.ci.R 0000644 0001762 0000144 00000011151 15040443562 012753 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
plot.ci.thresholds <- function(x, length = .01 * ifelse(attr(x, "roc")$percent, 100, 1), col = par("fg"), ...) {
bounds <- cbind(x$sp, x$se)
apply(bounds, 1, function(x, ...) {
suppressWarnings(segments(x[2], x[4], x[2], x[6], col = col, ...))
suppressWarnings(segments(x[2] - length, x[4], x[2] + length, x[4], col = col, ...))
suppressWarnings(segments(x[2] - length, x[6], x[2] + length, x[6], col = col, ...))
suppressWarnings(segments(x[1], x[5], x[3], x[5], col = col, ...))
suppressWarnings(segments(x[1], x[5] + length, x[1], x[5] - length, col = col, ...))
suppressWarnings(segments(x[3], x[5] + length, x[3], x[5] - length, col = col, ...))
}, ...)
invisible(x)
}
plot.ci.sp <- function(x, type = c("bars", "shape"), length = .01 * ifelse(attr(x, "roc")$percent, 100, 1), col = ifelse(type == "bars", par("fg"), "gainsboro"), no.roc = FALSE, ...) {
type <- match.arg(type)
if (type == "bars") {
sapply(1:dim(x)[1], function(n, ...) {
se <- attr(x, "sensitivities")[n]
suppressWarnings(segments(x[n, 1], se, x[n, 3], se, col = col, ...))
suppressWarnings(segments(x[n, 1], se - length, x[n, 1], se + length, col = col, ...))
suppressWarnings(segments(x[n, 3], se - length, x[n, 3], se + length, col = col, ...))
}, ...)
} else {
if (length(x[, 1]) < 15) {
warning("Low definition shape.")
}
suppressWarnings(polygon(c(1 * ifelse(attr(x, "roc")$percent, 100, 1), x[, 1], 0, rev(x[, 3]), 1 * ifelse(attr(x, "roc")$percent, 100, 1)), c(0, attr(x, "sensitivities"), 1 * ifelse(attr(x, "roc")$percent, 100, 1), rev(attr(x, "sensitivities")), 0), col = col, ...))
if (!no.roc) {
plot(attr(x, "roc"), add = TRUE)
}
}
invisible(x)
}
plot.ci.se <- function(x, type = c("bars", "shape"), length = .01 * ifelse(attr(x, "roc")$percent, 100, 1), col = ifelse(type == "bars", par("fg"), "gainsboro"), no.roc = FALSE, ...) {
type <- match.arg(type)
if (type == "bars") {
sapply(1:dim(x)[1], function(n, ...) {
sp <- attr(x, "specificities")[n]
suppressWarnings(segments(sp, x[n, 1], sp, x[n, 3], col = col, ...))
suppressWarnings(segments(sp - length, x[n, 1], sp + length, x[n, 1], col = col, ...))
suppressWarnings(segments(sp - length, x[n, 3], sp + length, x[n, 3], col = col, ...))
}, ...)
} else {
if (length(x[, 1]) < 15) {
warning("Low definition shape.")
}
suppressWarnings(polygon(c(0, attr(x, "specificities"), 1 * ifelse(attr(x, "roc")$percent, 100, 1), rev(attr(x, "specificities")), 0), c(1 * ifelse(attr(x, "roc")$percent, 100, 1), x[, 1], 0, rev(x[, 3]), 1 * ifelse(attr(x, "roc")$percent, 100, 1)), col = col, ...))
if (!no.roc) {
plot(attr(x, "roc"), add = TRUE)
}
}
invisible(x)
}
plot.ci.coords <- function(x, type = c("bars", "shape"), length = NULL, col = ifelse(type == "bars", par("fg"), "gainsboro"), ...) {
type <- match.arg(type)
if (length(x) > 1) {
warning(sprintf("'ci.coords' object contains multiple coordinates, only %s will be plotted", names(x)[1]))
}
if (is.null(length)) {
x_range <- range(attr(x, "x"))
length <- (x_range[2] - x_range[1]) / length(attr(x, "x")) / 5
}
if (type == "bars") {
x_val <- attr(x, "x")
suppressWarnings(segments(x_val, x[[1]][, 1], x_val, x[[1]][, 3], col = col, ...))
suppressWarnings(segments(x_val - length, x[[1]][, 1], x_val + length, x[[1]][, 1], col = col, ...))
suppressWarnings(segments(x_val - length, x[[1]][, 3], x_val + length, x[[1]][, 3], col = col, ...))
} else {
if (length(x[[1]][, 1]) < 15) {
warning("Low definition shape.")
}
suppressWarnings(polygon(c(attr(x, "x"), rev(attr(x, "x"))), c(x[[1]][, 1], rev(x[[1]][, 3])), col = col, ...))
}
invisible(x)
}
pROC/R/var.R 0000644 0001762 0000144 00000012207 15040443562 012176 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
var <- function(...) {
UseMethod("var")
}
var.default <- function(...) {
stats::var(...)
}
var.auc <- function(auc, ...) {
# Change roc from an auc to a roc object but keep the auc specifications
roc <- auc
attr(auc, "roc") <- NULL
roc <- attr(roc, "roc")
roc$auc <- auc
# Pass to var.roc
var.roc(roc, ...)
}
var.smooth.roc <- function(smooth.roc, ...) {
var.roc(smooth.roc, ...) # just pass to var.roc that will do the job
}
var.roc <- function(roc,
method = c("delong", "bootstrap", "obuchowski"),
boot.n = 2000,
boot.stratified = TRUE,
reuse.auc = TRUE,
progress = NULL,
parallel = FALSE,
...) {
# We need an auc
if (is.null(roc$auc) | !reuse.auc) {
roc$auc <- auc(roc, ...)
}
if (roc_utils_is_perfect_curve(roc)) {
warning("var() of a ROC curve with AUC == 1 is always 0 and can be misleading.")
}
if (!is.null(progress)) {
warning("Progress bars are deprecated in pROC 1.19. Ignoring 'progress' argument")
}
# do all the computations in fraction, re-transform in percent later
percent <- roc$percent
if (percent) {
roc <- roc_utils_unpercent(roc)
}
# Check the method
if (missing(method) | is.null(method)) {
# determine method if missing
if (has.partial.auc(roc)) {
# partial auc: go for bootstrap
method <- "bootstrap"
} else if (inherits(roc, "smooth.roc")) {
# smoothing: bootstrap
method <- "bootstrap"
} else {
method <- "delong"
}
} else {
method <- match.arg(method)
# delong NA to pAUC: warn + change
if (method == "delong") {
if (has.partial.auc(roc)) {
stop("DeLong method is not supported for partial AUC. Use method=\"bootstrap\" instead.")
} else if ("smooth.roc" %in% class(roc)) {
stop("DeLong method is not supported for smoothed ROCs. Use method=\"bootstrap\" instead.")
}
} else if (method == "obuchowski") {
if ("smooth.roc" %in% class(roc)) {
stop("Using Obuchowski for smoothed ROCs is not supported. Using bootstrap instead.")
}
if (has.partial.auc(roc) && attr(roc$auc, "partial.auc.focus") == "sensitivity") {
stop("Using Obuchowski for partial AUC on sensitivity region is not supported. Using bootstrap instead.")
}
}
}
if (method == "delong") {
n <- length(roc$controls)
m <- length(roc$cases)
V <- delongPlacements(roc)
var <- var(V$Y) / n + var(V$X) / m
} else if (method == "obuchowski") {
var <- var_roc_obuchowski(roc) / length(roc$cases)
} else {
var <- var_roc_bootstrap(roc, boot.n, boot.stratified, parallel, ...)
}
if (percent) {
var <- var * (100^2)
}
return(var)
}
var_roc_bootstrap <- function(roc, boot.n, boot.stratified, parallel, ...) {
## Smoothed ROC curve variance
if (inherits(roc, "smooth.roc")) {
smoothing.args <- roc$smoothing.args
smoothing.args$smooth <- TRUE
non.smoothed.roc <- attr(roc, "roc")
non.smoothed.roc$percent <- FALSE # as we did earlier for the smoothed.roc
smooth.roc.call <- as.call(c(utils::getS3method("smooth", "roc"), roc$smoothing.args))
auc.args <- attributes(roc$auc)[grep("partial.auc", names(attributes(roc$auc)))]
auc.args$allow.invalid.partial.auc.correct <- TRUE
auc.call <- as.call(c(utils::getS3method("auc", "smooth.roc"), auc.args))
if (boot.stratified) {
aucs <- unlist(lapply(seq_len(boot.n), stratified.ci.smooth.auc, roc = non.smoothed.roc, smooth.roc.call = smooth.roc.call, auc.call = auc.call))
} else {
aucs <- unlist(lapply(seq_len(boot.n), nonstratified.ci.smooth.auc, roc = non.smoothed.roc, smooth.roc.call = smooth.roc.call, auc.call = auc.call))
}
}
## Non smoothed ROC curves variance
else {
if (boot.stratified) {
aucs <- unlist(lapply(seq_len(boot.n), stratified.ci.auc, roc = roc)) # ci.auc: returns aucs just as we need for var, so re-use it!
} else {
aucs <- unlist(lapply(seq_len(boot.n), nonstratified.ci.auc, roc = roc))
}
}
if ((num.NAs <- sum(is.na(aucs))) > 0) {
warning(sprintf("%i NA value(s) produced during bootstrap were ignored.", num.NAs))
aucs <- aucs[!is.na(aucs)]
}
return(var(aucs))
}
pROC/R/plot.roc.R 0000644 0001762 0000144 00000036103 15040443562 013147 0 ustar ligges users # pROC: Tools Receiver operating characteristic (ROC curves) with
# (partial) area under the curve, confidence intervals and comparison.
# Copyright (C) 2010-2014 Xavier Robin, Alexandre Hainard, Natacha Turck,
# Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez
# and Markus Müller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
plot.roc <- function(x, ...) {
UseMethod("plot.roc")
}
plot.roc.formula <- function(x, data, subset, na.action, ...) {
data.missing <- missing(data)
call <- match.call()
names(call)[2] <- "formula" # forced to be x by definition of plot
roc.data <- roc_utils_extract_formula(
formula = x, data, subset, na.action, ...,
data.missing = data.missing,
call = call
)
if (length(roc.data$predictor.name) > 1) {
stop("Only one predictor supported in 'plot.roc'.")
}
response <- roc.data$response
predictor <- roc.data$predictors[, 1]
roc <- roc(response, predictor, plot = TRUE, ...)
roc$call <- match.call()
invisible(roc)
}
plot.roc.default <- function(x, predictor, ...) {
roc <- roc(x, predictor, plot = TRUE, ...)
roc$call <- match.call()
invisible(roc)
}
plot.roc.smooth.roc <- plot.smooth.roc <- function(x, ...) {
invisible(plot.roc.roc(x, ...)) # force usage of plot.roc.roc: only print.thres not working
}
plot.roc.roc <- function(x,
add = FALSE,
reuse.auc = TRUE,
axes = TRUE,
legacy.axes = FALSE,
xlim = if (x$percent) {
c(100, 0)
} else {
c(1, 0)
},
ylim = if (x$percent) {
c(0, 100)
} else {
c(0, 1)
},
xlab = ifelse(x$percent, ifelse(legacy.axes, "100 - Specificity (%)", "Specificity (%)"), ifelse(legacy.axes, "1 - Specificity", "Specificity")),
ylab = ifelse(x$percent, "Sensitivity (%)", "Sensitivity"),
asp = 1,
mar = c(4, 4, 2, 2) + .1,
mgp = c(2.5, 1, 0),
# col, lty and lwd for the ROC line only
col = par("col"),
lty = par("lty"),
lwd = 2,
type = "l",
# Identity line
identity = !add,
identity.col = "darkgrey",
identity.lty = 1,
identity.lwd = 1,
# Print the thresholds on the plot
print.thres = FALSE,
print.thres.pch = 20,
print.thres.adj = c(-.05, 1.25),
print.thres.col = "black",
print.thres.pattern = ifelse(x$percent, "%.1f (%.1f%%, %.1f%%)", "%.3f (%.3f, %.3f)"),
print.thres.cex = par("cex"),
print.thres.pattern.cex = print.thres.cex,
print.thres.best.method = NULL,
print.thres.best.weights = c(1, 0.5),
# Print the AUC on the plot
print.auc = FALSE,
print.auc.pattern = NULL,
print.auc.x = ifelse(x$percent, 50, .5),
print.auc.y = ifelse(x$percent, 50, .5),
print.auc.adj = c(0, 1),
print.auc.col = col,
print.auc.cex = par("cex"),
# Grid
grid = FALSE,
grid.v = {
if (is.logical(grid) && grid[1] == TRUE) {
seq(0, 1, 0.1) * ifelse(x$percent, 100, 1)
} else if (is.numeric(grid)) {
seq(0, ifelse(x$percent, 100, 1), grid[1])
} else {
NULL
}
},
grid.h = {
if (length(grid) == 1) {
grid.v
} else if (is.logical(grid) && grid[2] == TRUE) {
seq(0, 1, 0.1) * ifelse(x$percent, 100, 1)
} else if (is.numeric(grid)) {
seq(0, ifelse(x$percent, 100, 1), grid[2])
} else {
NULL
}
},
# for grid.lty, grid.lwd and grid.col, a length 2 value specifies both values for vertical (1) and horizontal (2) grid
grid.lty = 3,
grid.lwd = 1,
grid.col = "#DDDDDD",
# Polygon for the auc
auc.polygon = FALSE,
auc.polygon.col = "gainsboro", # Other arguments can be passed to polygon() using "..." (for these two we cannot)
auc.polygon.lty = par("lty"),
auc.polygon.density = NULL,
auc.polygon.angle = 45,
auc.polygon.border = NULL,
# Should we show the maximum possible area as another polygon?
max.auc.polygon = FALSE,
max.auc.polygon.col = "#EEEEEE", # Other arguments can be passed to polygon() using "..." (for these two we cannot)
max.auc.polygon.lty = par("lty"),
max.auc.polygon.density = NULL,
max.auc.polygon.angle = 45,
max.auc.polygon.border = NULL,
# Confidence interval
ci = !is.null(x$ci),
ci.type = c("bars", "shape", "no"),
ci.col = ifelse(ci.type == "bars", par("fg"), "gainsboro"),
...) {
percent <- x$percent
if (max.auc.polygon | auc.polygon | print.auc) { # we need the auc here
if (is.null(x$auc) | !reuse.auc) {
x$auc <- auc(x, ...)
}
partial.auc <- attr(x$auc, "partial.auc")
partial.auc.focus <- attr(x$auc, "partial.auc.focus")
}
# compute a reasonable default for print.auc.pattern if required
if (print.auc & is.null(print.auc.pattern)) {
print.auc.pattern <- ifelse(identical(partial.auc, FALSE), "AUC: ", "Partial AUC: ")
print.auc.pattern <- paste(print.auc.pattern, ifelse(percent, "%.1f%%", "%.3f"), sep = "")
if (ci && methods::is(x$ci, "ci.auc")) {
print.auc.pattern <- paste(print.auc.pattern, " (", ifelse(percent, "%.1f%%", "%.3f"), "\u2013", ifelse(percent, "%.1f%%", "%.3f"), ")", sep = "")
}
}
# get and sort the sensitivities and specificities
se <- sort(x$sensitivities, decreasing = TRUE)
sp <- sort(x$specificities, decreasing = FALSE)
if (!add) {
opar <- par(mar = mar, mgp = mgp)
on.exit(par(opar))
# type="n" to plot background lines and polygon shapes first. We will add the line later. axes=FALSE, we'll add them later according to legacy.axis
suppressWarnings(plot(x$specificities, x$sensitivities, xlab = xlab, ylab = ylab, type = "n", axes = FALSE, xlim = xlim, ylim = ylim, lwd = lwd, asp = asp, ...))
# As we had axes=FALSE we need to add them again unless axes=FALSE
if (axes) {
box()
# axis behave differently when at and labels are passed (no decimals on 1 and 0),
# so handle each case separately and consistently across axes
if (legacy.axes) {
lab.at <- axTicks(side = 1)
lab.labels <- format(ifelse(x$percent, 100, 1) - lab.at)
suppressWarnings(axis(side = 1, at = lab.at, labels = lab.labels, ...))
lab.at <- axTicks(side = 2)
suppressWarnings(axis(side = 2, at = lab.at, labels = format(lab.at), ...))
} else {
suppressWarnings(axis(side = 1, ...))
suppressWarnings(axis(side = 2, ...))
}
}
}
# Plot the grid
# make sure grid.lty, grid.lwd and grid.col are at least of length 2
grid.lty <- rep(grid.lty, length.out = 2)
grid.lwd <- rep(grid.lwd, length.out = 2)
grid.col <- rep(grid.col, length.out = 2)
if (!is.null(grid.v)) {
suppressWarnings(abline(v = grid.v, lty = grid.lty[1], col = grid.col[1], lwd = grid.lwd[1], ...))
}
if (!is.null(grid.h)) {
suppressWarnings(abline(h = grid.h, lty = grid.lty[2], col = grid.col[2], lwd = grid.lwd[2], ...))
}
# Plot the polygon displaying the maximal area
if (max.auc.polygon) {
if (identical(partial.auc, FALSE)) {
map.y <- c(0, 1, 1, 0) * ifelse(percent, 100, 1)
map.x <- c(1, 1, 0, 0) * ifelse(percent, 100, 1)
} else {
if (partial.auc.focus == "sensitivity") {
map.y <- c(partial.auc[2], partial.auc[2], partial.auc[1], partial.auc[1])
map.x <- c(0, 1, 1, 0) * ifelse(percent, 100, 1)
} else {
map.y <- c(0, 1, 1, 0) * ifelse(percent, 100, 1)
map.x <- c(partial.auc[2], partial.auc[2], partial.auc[1], partial.auc[1])
}
}
suppressWarnings(polygon(map.x, map.y, col = max.auc.polygon.col, lty = max.auc.polygon.lty, border = max.auc.polygon.border, density = max.auc.polygon.density, angle = max.auc.polygon.angle, ...))
}
# Plot the ci shape
if (ci && !methods::is(x$ci, "ci.auc")) {
ci.type <- match.arg(ci.type)
if (ci.type == "shape") {
plot(x$ci, type = "shape", col = ci.col, no.roc = TRUE, ...)
}
}
# Plot the polygon displaying the actual area
if (auc.polygon) {
if (identical(partial.auc, FALSE)) {
suppressWarnings(polygon(c(sp, 0), c(se, 0), col = auc.polygon.col, lty = auc.polygon.lty, border = auc.polygon.border, density = auc.polygon.density, angle = auc.polygon.angle, ...))
} else {
if (partial.auc.focus == "sensitivity") {
x.all <- rev(se)
y.all <- rev(sp)
} else {
x.all <- sp
y.all <- se
}
# find the SEs and SPs in the interval
x.int <- x.all[x.all <= partial.auc[1] & x.all >= partial.auc[2]]
y.int <- y.all[x.all <= partial.auc[1] & x.all >= partial.auc[2]]
# if the upper limit is not exactly present in SPs, interpolate
if (!(partial.auc[1] %in% x.int)) {
x.int <- c(x.int, partial.auc[1])
# find the limit indices
idx.out <- match(FALSE, x.all < partial.auc[1])
idx.in <- idx.out - 1
# interpolate y
proportion.start <- (partial.auc[1] - x.all[idx.out]) / (x.all[idx.in] - x.all[idx.out])
y.start <- y.all[idx.out] - proportion.start * (y.all[idx.out] - y.all[idx.in])
y.int <- c(y.int, y.start)
}
# if the lower limit is not exactly present in SPs, interpolate
if (!(partial.auc[2] %in% x.int)) {
x.int <- c(partial.auc[2], x.int)
# find the limit indices
idx.out <- length(x.all) - match(TRUE, rev(x.all) < partial.auc[2]) + 1
idx.in <- idx.out + 1
# interpolate y
proportion.end <- (x.all[idx.in] - partial.auc[2]) / (x.all[idx.in] - x.all[idx.out])
y.end <- y.all[idx.in] + proportion.end * (y.all[idx.out] - y.all[idx.in])
y.int <- c(y.end, y.int)
}
# anchor to baseline
x.int <- c(partial.auc[2], x.int, partial.auc[1])
y.int <- c(0, y.int, 0)
if (partial.auc.focus == "sensitivity") {
# for SE, invert x and y again
suppressWarnings(polygon(y.int, x.int, col = auc.polygon.col, lty = auc.polygon.lty, border = auc.polygon.border, density = auc.polygon.density, angle = auc.polygon.angle, ...))
} else {
suppressWarnings(polygon(x.int, y.int, col = auc.polygon.col, lty = auc.polygon.lty, border = auc.polygon.border, density = auc.polygon.density, angle = auc.polygon.angle, ...))
}
}
}
# Identity line
if (identity) suppressWarnings(abline(ifelse(percent, 100, 1), -1, col = identity.col, lwd = identity.lwd, lty = identity.lty, ...))
# Actually plot the ROC curve
suppressWarnings(lines(sp, se, type = type, lwd = lwd, col = col, lty = lty, ...))
# Plot the ci bars
if (ci && !methods::is(x$ci, "ci.auc")) {
if (ci.type == "bars") {
plot(x$ci, type = "bars", col = ci.col, ...)
}
}
# Print the thresholds on the curve if print.thres is TRUE
if (isTRUE(print.thres)) {
print.thres <- "best"
}
if (is.character(print.thres)) {
print.thres <- match.arg(print.thres, c("no", "all", "local maximas", "best"))
}
if (methods::is(x, "smooth.roc")) {
if (is.numeric(print.thres)) {
stop("Numeric 'print.thres' unsupported on a smoothed ROC plot.")
} else if (print.thres == "all" || print.thres == "local maximas") {
stop("'all' and 'local maximas' 'print.thres' unsupported on a smoothed ROC plot.")
} else if (print.thres == "best") {
co <- coords(x, print.thres, best.method = print.thres.best.method, best.weights = print.thres.best.weights, transpose = FALSE)
suppressWarnings(points(co$specificity, co$sensitivity, pch = print.thres.pch, cex = print.thres.cex, col = print.thres.col, ...))
suppressWarnings(text(co$specificity, co$sensitivity, sprintf(print.thres.pattern, NA, co$specificity, co$sensitivity), adj = print.thres.adj, cex = print.thres.pattern.cex, col = print.thres.col, ...))
} # else print.thres == no > do nothing
} else if (is.numeric(print.thres) || is.character(print.thres)) {
if (is.character(print.thres) && print.thres == "no") {} # do nothing
else {
co <- coords(x, print.thres, best.method = print.thres.best.method, best.weights = print.thres.best.weights, transpose = FALSE)
suppressWarnings(points(co$specificity, co$sensitivity, pch = print.thres.pch, cex = print.thres.cex, col = print.thres.col, ...))
suppressWarnings(text(co$specificity, co$sensitivity, sprintf(print.thres.pattern, co$threshold, co$specificity, co$sensitivity), adj = print.thres.adj, cex = print.thres.pattern.cex, col = print.thres.col, ...))
}
}
# Print the AUC on the plot
if (print.auc) {
if (ci && methods::is(x$ci, "ci.auc")) {
labels <- sprintf(print.auc.pattern, x$auc, x$ci[1], x$ci[3])
suppressWarnings(text(print.auc.x, print.auc.y, labels, adj = print.auc.adj, cex = print.auc.cex, col = print.auc.col, ...))
} else {
labels <- sprintf(print.auc.pattern, x$auc)
}
suppressWarnings(text(print.auc.x, print.auc.y, labels, adj = print.auc.adj, cex = print.auc.cex, col = print.auc.col, ...))
}
invisible(x)
}
pROC/NEWS 0000644 0001762 0000144 00000034546 15042617211 011567 0 ustar ligges users 1.19.0.1 (2025-07-31)
* Move 'fun.sesp' definition to work around LudvigOlsen/cvms#44
1.19.0 (2025-07-30)
* 'ci.coords' can now take the same 'input' values as 'coords' (issue #90)
* 'ci.coords' can be 'plot'ted
* Added "lr_pos" and "lr_neg" to 'coords' (issue #102)
* 'coords' with partial.auc now interpolates bounds when needed
* Added 'ignore.partial.auc' argument to 'coords'
* Deprecated 'transpose', 'as.list', 'as.matrix' and 'drop' in 'coords'
* Deprecated the 'algorithm' argument to 'roc' and 'fun.sesp' value
* Deprecated the 'progress' and 'parallel' argument for bootstrap operations.
* Removed dependencies on 'doParallel' and retired package 'plyr' (thanks to Michael Chirico, pr #134, #135, #136, #137, #138, #139 and #140).
1.18.5 (2023-11-01):
* Fixed formula input when given as variable and combined with `with` (issue #111)
* Fixed formula containing variables with spaces (issue #120)
* Fixed broken grouping when `colour` argument was given in `ggroc` (issue #121)
1.18.4 (2023-07-04):
* Fix regression in 1.18.3 in 'legacy.axes' in 'ggroc'
1.18.3 (2023-07-02):
* Fix warning about 'aes_string' in 'ggroc'
* Improvements in tests (thanks to Michael Chirico, pr #114, #115)
* Fix upcoming CRAN warning about numeric version comparisons
1.18.2 (2023-05-13):
* Fix CRAN submission NOTE (issue #112)
1.18.1 (2023-05-07):
* Fix 'print'ing some curves built from a formula (issue #101)
* Fix tests following upstream updates in density() (https://bugs.r-project.org/show_bug.cgi?id=18337)
* Improvements in documentation
1.18.0 (2021-09-02):
* Add CI of the estimate for 'roc.test' (DeLong, paired only for now) (code contributed by Zane Billings) (pr #95)
* Fix documentation and alternative hypothesis for Venkatraman test (issue #92)
1.17.0.1 (2021-01-07):
* Fix CRAN incoming checks as requested by CRAN
1.17.0 (2020-12-29)
* Accept more values in 'input' of coords (issue #67)
* Accept 'kappa' for the 'power.roc.test' of two ROC curves (issue #82)
* The 'input' argument to 'coords' for 'smooth.roc' curves no longer has a default
* The 'x' argument to 'coords' for 'smooth.roc' can now be set to 'all' (also the default)
* Fix bootstrap roc.test and cov with 'smooth.roc' curves
* The 'ggroc' function can now plot 'smooth.roc' curves (issue #86)
* Remove warnings with 'warnPartialMatchDollar' option (issue #87)
* Make tests depending on vdiffr conditional (issue #88)
1.16.2 (2020-03-19)
* Skip test depending on Rcpp version
1.16.1 (2020-01-13)
* Skip timing-dependent test failing occasionally on CRAN
1.16.0 (2020-01-12)
* BACKWARD INCOMPATIBLE CHANGE: 'transpose' argument to 'coords' switched to FALSE by default (issue #54)
* BACKWARD INCOMPATIBLE CHANGE: 'ci.coords' return value is now of list type and easier to use
* Fix one-sided DeLong test for curves with 'direction=">"' (issue #64)
* Fix an error in 'ci.coords' due to expected NA values in some coords (like "precision") (issue #65)
* Ordrered predictors are converted to numeric in a more robust way (issue #63)
* Cleaned up 'power.roc.test' code (issue #50)
* Fix pairing with 'roc.formula' and warn if 'na.action' is not set to "na.pass" or "na.fail" (issue #68)
* Fix 'ci.coords' not working with 'smooth.roc' curves
1.15.3 (2019-07-21)
* Fix: previous version accidentally set transpose = FALSE, should only be for next major release
1.15.2 (2019-07-20)
* Fix -Inf threshold in coords for curves with 'direction = ">"' (issue #60)
* Restore lazy loading of the data and fix an 'R CMD check' warning "Variables with usage in documentation object 'aSAH' not in code"
1.15.1 (2019-07-17)
* Fix erroneous error in 'ci.coords' with 'ret="threshold"' (issue #57)
* Fix vdiffr unit tests with ggplot2 3.2.0 (issue #53)
* Keep list order in 'ggroc' (issue #58)
1.15.0 (2019-06-01)
* 'roc' now prints messages when autodetecting 'levels' and 'direction' by default. Turn off with 'quiet = TRUE' or set these values explicitly
* Speedup with 'algorithm = 2' (issue #44) and in 'coords' (issue #52)
* New 'algorithm = 6' (used by default) uses 'algorithm = 2' for numeric data, and 'algorithm = 3' for ordered vectors
* New 'roc.data.frame' method and 'roc_' function for use in pipelines
* 'coords' can now returns 'youden' and 'closest.topleft' values (issue #48)
* New 'transpose' argument for 'coords', TRUE by default (issue #54)
* Use text instead of Tcl/Tk progress bar by default (issue #51)
* Fix 'method = "density"' smoothing when called directly from 'roc' (issue #49)
* Renamed 'roc' argument 'n' to 'smooth.n'
* Fixed 'are.paired' ignoring smoothing arguments of 'roc2' with 'return.paired.rocs'
* New 'ret' option "all" in 'coords' (issue #47)
* 'drop' in 'coords' now drops the dimension of 'ret' too (#issue 43)
1.14.0 (2019-03-12)
* The 'multiclass.roc' function now accepts multivariate decision values (code contributed by Matthias Döring)
* 'ggroc' supports multiple aesthetics (issue #42)
* Make 'ggplot2' dependency optional
* CSuggested packages can be installed interactively when required
* Passing both 'cases' and 'controls' or 'response' and 'predictor' arguments is now an error
* Many small bug fixes
1.13.0 (2018-09-23)
* 'roc' now returns 'NaN' when predictor contains infinite values (issue #30)
* Better handling of near-ties near +-Infinity and 0
* 'ggroc' supports aes="group" to allow curves with identical aesthetics
1.12.1 (2018-05-06)
* Fix a regression causing the allocation of a very large vector (issue #29)
1.12.0 (2018-05-05)
* Fix bug that crashed DeLong calculations when predictor had near-ties close to the floating point precision limit that were rounded back to a predictor value (issue #25)
* Fix bug that crashed 'ci.auc' and 'var' if 'direction' was ">" and 'percent=TRUE' (issue #25)
* Fix bug causing 'ci' to return 'NaN' values with 'method="delong"' when cases or controls had a single observation (issue #27)
* Fix 'power.roc.curve' failed with curves having 'percent=TRUE'
* Fix 'ci(..., of="coords")' returned the 'ci' function instead of the CI
* C++ code now check for user interrupts regularly with Rcpp::checkUserInterrupt()
* Better error message for 'ci.coords' attempting to return 'threshold'
* New algorithm = 5 (used by default) chooses the algorithm based on the number of thresholds to avoid worst case with algorithm = 3
1.11.0 (2018-03-24)
* Added argument 'legacy.axes' to 'ggroc'
* Fix NOTE about 'apparent S3 methods exported but not registered' in 'R CMD check'
1.10.0 (2017-06-10)
* Basic ggplot2 support (one and multiple ROC curves)
* Implement 'precision' and 'recall' for 'coords'
* Fix: properly handle NAs in cases when passing cases/controls to 'roc' (thanks Thomas König for the report)
* Fix various minor bugs detected with new unit tests
1.9.1 (2017-02-05)
* Fix: 'subset' and 'na.action' arguments now handled properly in 'roc.formula' (thanks Terry Therneau for the report)
* Added policies to handle the case where a ROC curve has multiple "best" threshold in 'ci' (thanks Nicola Toschi for the report)
* Support 'xlim' and 'ylim' gracefully in 'plot.roc'
* Improved validation of input class 'levels' and 'direction'; messages when auto-detecting, use 'quiet' to turn on
* Removed extraneous 'name' attribute on the 'p.value' (thanks Paweł Kleka for the report)
* Faster DeLong algorithm (code contributed by Stefan Siegert)
1.8 (2015-05-04)
* NAMESPACE now properly exports the methods as S3 methods.
* Now uses and works with 'requireNamespace'
* Add ability to supply two ordered factors with identical levels as control / cases
* Deprecate dangerous use of a matrix as response / predictor with a warning
* Forward 'best.method' and 'best.weights' arguments to 'coords' in 'ci.thresholds'
* Fix CITATION file as per CRAN request
* pAUC correction is undefined for partial AUC below the diagonal (result < 0.5) and now returns NA (with a warning). Thanks Vincenzo Lagani for the report.
1.7.3 (2014-06-14)
* Fixed AUC of binomial-smoothed ROC off by 100^2 (thanks Bao-Li Chang for the report)
* Fix print of logcondens-smoothed ROC
1.7.2 (2014-04-05)
* Fixed bug where 'ci.coords' with 'x="best"' would fail if one or more resampled ROC curve had multiple "best" thresholds
* Fixed bug in 'ci.coords': passing more than one value in 'x' now works
* Fixed typo in documentation of 'direction' argument to 'roc' (thanks Le Kang for the report)
* Add a warning when computing statistics of ROC curve with AUC = 1
* Require latest version of Rcpp to avoid weird errors (thanks Tom Liptrot for the report)
1.7.1 (2014-02-20)
* Close SOCK cluster on Windows with parallel=TRUE
* Fixed really use algorithm 1 when microbenchmark fails
1.7 (2014-02-19)
* Faster algorithm for DeLong 'roc.test', 'power.roc.test', 'ci.auc', 'var' and 'cov' function (no large matrix allocation)
* Handling Math and Operations correctly on 'auc' and 'ci' objects (see '?groupGeneric.pROC')
* The 'formula' for 'roc.formula' can now provide several predictors and a list of ROC curves will be returned
* Fixed documentation of 'ci.coords' with examples
* Fixed binormal AUC computed with triangulation despite the claim in the documentation
* Fixed unstated requirement on Rcpp >= 0.10.5
1.6.0.1 (2013-12-28)
* Removed erroneous error message displayed when predictors and responses were not vectors
1.6 (2013-12-26)
* New 'power.roc.test' function for sample size and power computations
* New 'cov' and 'var' functions supports new "obuchowski" method
* New 'ci.coords' function to compute CI of arbitrary coords
* 'coords' accepts new 'ret' value "1-accuracy"
* Introducing various algorithms to compute sensitivities and specificites, with a more vectorized code or Rcpp. See 'algorithm' in ?roc for more details on the trade-offs of the different methods.
* Faster algorithm for DeLong 'roc.test', 'ci', 'var' and 'cov' function (thanks Kazuki Yoshida).
* 'are.paired' now also checks for identical 'levels'
* Fixed a warning generated in the examples
* Fixed several bugs related with 'smooth.roc' curves
* Additional input data sanity checks
* Now requires R >= 2.13 (in fact, since 1.5.1, thanks Emmanuel Curis for the report)
* Progress bars now defaults to text on Macs where 'tcltk' seems broken (thanks Gerard Smits for the report)
1.5.4 (2012-08-31)
* Running less smooth.roc examples with logcondens because they take too much time (requested by Uwe Ligges)
1.5.3 (2012-08-31)
* AUC specification was lost when roc.test, cov or var was passed an 'auc' object.
* Correct computation of "accuracy" in 'coords' (thanks to Kosuke Yoshihara for the report)
1.5.1 (2012-03-09)
* Faster loading of the package (thanks to Prof Brian Ripley and Glenn Lawyer for the report)
1.5 (2011-12-11)
* New 'cov' and 'var' functions
* 'coords' accepts new 'ret' values: "accuracy", "tn", "tp", "fn", "fp", "npv", "ppv", "1-specificity", "1-sensitivity", "1-npv", "1-ppv", "npe" and "ppe"
* New 'legacy.axes' argument to 'plot' 1-specificity rather than specificity
* New 'axes' argument to turn off the plotting of the axis
* New 'logcondens' and 'logcondens.smooth' (Univariate Log-Concave Density Estimation) smoothing methods
* New function 'has.partial.auc' to determine if an AUC is full or partial
* New argument 'drop' for 'coords'
* 'auc' and 'multiclass.auc' objects now also have secondary class 'numeric'
* Updated load call
* Delong's CI reversed in ROC curves with direction=">"
* Delong's CI AUC returned values > 1 or < 0 in some rare cases
* Minor improvements in documentation
1.4.4 (2011-08-09)
* Fixed alternative for one-tailed tests (thanks to Lisa Koch for the report)
* Removed COPYING file to fix a warning in r-devel.
1.4.3 (2011-03-17)
* Updated citation
1.4.2 (2011-03-03)
* Fixed bootstrap 'roc.test' generating NAs when 'smooth.roc's were used with 'reuse.auc=FALSE' (thanks to Buddy for the report)
* Documented a warning that was missing in roc.test
* Updated citation
1.4.1 (2011-01-27)
* 'venkatraman''s test for unpaired ROC curves
1.4 (2011-01-21)
* 'smooth' does not apply on 'ordered' factors anymore
* Multi-class AUC support
* Can choose how 'best' thresold is determined ('best.method' and 'best.weights' in 'coords' and 'print.thres.best.method' and 'print.thres.best.weights' in 'plot.roc')
* Minor fixes in documentation
* 'print' now prints the response instead of "response" and more informative data in 'htest's
* Bootstrap with 'ci.auc' consumes much less memory
* Unpaired bootstrap and DeLong's test
* Specificity and sensitivity tests (in 'roc.test')
1.3.2 (2010-08-24)
* 'print.auc' printed incorrect CI in 'plot.roc' (thanks to Alexander B. Leichtle for the report)
* Failed to detect local maximas in 'coords' when 2 or less points were selected
* Don't consider ROC extremities (+-Inf at 1.0/0.0 SE<->SP) as local maximas
1.3.1 (2010-08-18)
* Sensitivity and specificity were inverted in coords when results were reported as list
* Faster checks with '\dontrun{}' in 'roc.test'
1.3 (2010-08-13)
* '...' not passed correctly in 'plot.ci.se' with 'type="bars"' resulting in an error
* CI is not re-computed by default in 'smooth.roc'. You can still turn it on with 'reuse.ci=TRUE'
* New function 'are.paired'
* Local maximas could be incorrectly detected in 'coords' (and 'plot.roc') with 'predictor's containing more than 2 levels.
* New method 'venkatraman' for 'roc.test'
* MASS and tcltk packages are now only suggested instead of required
1.2.1 (2010-05-11)
* Handle 'method' arguments for 'smooth.roc' and 'ci.auc' separately in 'roc.default'
* Added 'auc.polygon.*' and 'max.auc.polygon.*' arguments for 'polygon' in 'plot.roc'
1.2 (2010-05-09)
* Added DeLong method in 'ci.auc'
* Return value of 'ci.auc' does not contain an 'aucs' item anymore
* Put most examples with bootstrap within '\dontrun{}' blocks for faster (but less useful) checks execution
1.1 (2010-05-05)
* Added 'lines.roc' functions for ROC
* Added 'type' argument for both 'lines.roc' and 'plot.roc'
* Added 'print.auc.col' argument to 'plot.roc'
* Fixed a warning in 'roc.test.default' when the class of 'predictor1' had several elements
* Fixed an encoding failure during the checks on MacOS X
1.0.1 (2010-04-28)
* Reduced examples execution time. Added low 'boot.n' in the slowest examples and 'reuse.auc' and 'reuse.ci' arguments in smooth.roc.roc
1.0 (2010-04-27)
* First public release
pROC/data/ 0000755 0001762 0000144 00000000000 13607143106 011767 5 ustar ligges users pROC/data/aSAH.RData 0000644 0001762 0000144 00000003163 13607143106 013463 0 ustar ligges users WKlTe3skh&G_2I+u~PP((ioCLB7M&b E"Rh7W9|gr3N:y;toh*P8N pnBIH]q"SiOM4n#Y.\=X M>}>CuK}
|^y ]Fx5[s;ZY}ҵyy7`ز\˦`Ou:ϲv|غ\ڵ| Yr~[[WgWE赟C ""gp&%wmZG⓷vXh̹/Gq~NI$s5)>Wu㉋Way'??Я
VUW\wL| 6PkvpW?{SˋU$٫Ξ!U:toIZV'
w֩e%zL!D&L2e-y&L2frDk&L22fbˤI0X&LNG9c&LR:Bj3gH0_{!u{ 6'<@xa#G 4E`Ù9M [}~ !M؊r8Ä'OFOv& /^&Bx,
ɺDLЮ_iZ] pROC/src/ 0000755 0001762 0000144 00000000000 15040443562 011647 5 ustar ligges users pROC/src/RcppExports.cpp 0000644 0001762 0000144 00000002413 15040443562 014644 0 ustar ligges users // Generated by using Rcpp::compileAttributes() -> do not edit by hand
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
#include
using namespace Rcpp;
#ifdef RCPP_USE_GLOBAL_ROSTREAM
Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get();
Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
#endif
// RcppVersion
String RcppVersion();
RcppExport SEXP _pROC_RcppVersion() {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
rcpp_result_gen = Rcpp::wrap(RcppVersion());
return rcpp_result_gen;
END_RCPP
}
// delongPlacementsCpp
List delongPlacementsCpp(List roc);
RcppExport SEXP _pROC_delongPlacementsCpp(SEXP rocSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< List >::type roc(rocSEXP);
rcpp_result_gen = Rcpp::wrap(delongPlacementsCpp(roc));
return rcpp_result_gen;
END_RCPP
}
static const R_CallMethodDef CallEntries[] = {
{"_pROC_RcppVersion", (DL_FUNC) &_pROC_RcppVersion, 0},
{"_pROC_delongPlacementsCpp", (DL_FUNC) &_pROC_delongPlacementsCpp, 1},
{NULL, NULL, 0}
};
RcppExport void R_init_pROC(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
}
pROC/src/RcppVersion.cpp 0000644 0001762 0000144 00000001667 13607143106 014635 0 ustar ligges users /* pROC: Tools Receiver operating characteristic (ROC curves) with
(partial) area under the curve, confidence intervals and comparison.
Copyright (C) 2016 Xavier Robin, Stefan Siegert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
using namespace Rcpp;
// [[Rcpp::export]]
String RcppVersion() {
return RCPP_VERSION;
}
pROC/src/delong.cpp 0000644 0001762 0000144 00000007045 13607143106 013627 0 ustar ligges users /* pROC: Tools Receiver operating characteristic (ROC curves) with
(partial) area under the curve, confidence intervals and comparison.
Copyright (C) 2016 Xavier Robin, Stefan Siegert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
using namespace Rcpp;
bool _cmp(std::pair l, std::pair r) {
return l.second < r.second;
}
// [[Rcpp::export]]
List delongPlacementsCpp(List roc) {
int i, j, k, m, n, mdupl, ndupl, L;
std::vector cases = roc["cases"];
std::vector controls = roc["controls"];
std::string direction = roc["direction"];
m = cases.size();
n = controls.size();
L = m + n;
// For direction ">" we must reverse the data
if (direction == ">") {
for (i = 0; i < m; i++) {
cases[i] = -cases[i];
}
for (i = 0; i < n; i++) {
controls[i] = -controls[i];
}
}
// concatenate cases and controls into a vector of L pairs of the form
// (index, value), also save class labels (1 for cases, 0 for controls)
std::vector< std::pair > Z;
std::vector< bool > labels;
for (i = 0; i < m; i++) {
Z.push_back(std::pair(i, cases.at(i)));
labels.push_back(true);
}
Rcpp::checkUserInterrupt();
for (j = 0; j < n; j++) {
Z.push_back(std::pair(m+j, controls.at(j)));
labels.push_back(false);
}
Rcpp::checkUserInterrupt();
// sort Z from smallest to largest value, so Z holds the order indices and
// order statistics of all classifiers
std::sort(Z.begin(), Z.end(), _cmp);
Rcpp::checkUserInterrupt();
// the following calculates the "Delong-placements" X and Y in a single pass
// over the vector Z, instead of having to double loop over all pairs of
// (X_i, Y_j)
std::vector< double > XY(L, 0.0); // vector to hold the unnormalised X and Y values
std::vector< int > X_inds, Y_inds; // temporary vectors to save indices of duplicates
m = n = i = 0; // initialisation
while (i < L) {
X_inds.clear();
Y_inds.clear();
mdupl = ndupl = 0;
if (i % 10000 == 0) Rcpp::checkUserInterrupt();
while(1) {
j = Z.at(i).first;
if (labels.at(j)) {
mdupl++;
X_inds.push_back(j);
} else {
ndupl++;
Y_inds.push_back(j);
}
if (i == L-1) {
break;
}
if (Z.at(i).second != Z.at(i+1).second) {
break;
}
i++;
}
for (k = 0; k < mdupl; k++) {
XY.at(X_inds.at(k)) = n + ndupl/2.0;
}
for (k = 0; k < ndupl; k++) {
XY.at(Y_inds.at(k)) = m + mdupl/2.0;
}
n += ndupl;
m += mdupl;
i++;
}
double sum = 0.0;
std::vector X, Y;
Rcpp::checkUserInterrupt();
for (i = 0; i < L; i++) {
if (labels.at(i)) {
sum += XY.at(i);
X.push_back(XY.at(i) / n);
} else {
Y.push_back(1.0 - XY.at(i) / m);
}
}
List ret;
ret["theta"] = sum / m / n;
ret["X"] = X;
ret["Y"] = Y;
return(ret);
}
pROC/NAMESPACE 0000644 0001762 0000144 00000010240 15040443562 012274 0 ustar ligges users export(are.paired)
S3method("are.paired", "auc")
S3method("are.paired", "roc")
S3method("are.paired", "smooth.roc")
export(auc)
S3method("auc", "roc")
S3method("auc", "smooth.roc")
S3method("auc", "formula")
S3method("auc", "default")
S3method("auc", "multiclass.roc")
S3method("auc", "mv.multiclass.roc")
export(ci)
S3method("ci", "roc")
S3method("ci", "smooth.roc")
S3method("ci", "default")
S3method("ci", "formula")
S3method("ci", "auc")
S3method("ci", "multiclass.roc")
S3method("ci", "multiclass.auc")
export(ci.coords)
S3method("ci.coords", "roc")
S3method("ci.coords", "smooth.roc")
S3method("ci.coords", "default")
S3method("ci.coords", "formula")
export(ci.thresholds)
S3method("ci.thresholds", "roc")
S3method("ci.thresholds", "smooth.roc")
S3method("ci.thresholds", "default")
S3method("ci.thresholds", "formula")
export(ci.sp)
S3method("ci.sp", "roc")
S3method("ci.sp", "smooth.roc")
S3method("ci.sp", "default")
S3method("ci.sp", "formula")
export(ci.se)
S3method("ci.se", "roc")
S3method("ci.se", "smooth.roc")
S3method("ci.se", "default")
S3method("ci.se", "formula")
export(ci.auc)
S3method("ci.auc", "roc")
S3method("ci.auc", "smooth.roc")
S3method("ci.auc", "default")
S3method("ci.auc", "formula")
S3method("ci.auc", "auc")
S3method("ci.auc", "multiclass.roc")
S3method("ci.auc", "multiclass.auc")
export(coords)
S3method("coords", "auc")
S3method("coords", "roc")
S3method("coords", "smooth.roc")
export(cov)
S3method("cov", "roc")
S3method("cov", "smooth.roc")
S3method("cov", "default")
S3method("cov", "auc")
export(has.partial.auc)
S3method("has.partial.auc", "roc")
S3method("has.partial.auc", "smooth.roc")
S3method("has.partial.auc", "auc")
export(multiclass.roc)
S3method("multiclass.roc", "default")
S3method("multiclass.roc", "formula")
export(power.roc.test)
S3method("power.roc.test", "roc")
S3method("power.roc.test", "numeric")
S3method("power.roc.test", "list")
S3method("print", "roc")
S3method("print", "smooth.roc")
S3method("print", "auc")
S3method("print", "ci.auc")
S3method("print", "ci.thresholds")
S3method("print", "ci.se")
S3method("print", "ci.sp")
S3method("print", "ci.coords")
S3method("print", "multiclass.roc")
S3method("print", "multiclass.auc")
S3method("print", "mv.multiclass.roc")
S3method("print", "mv.multiclass.auc")
export(roc)
S3method("roc", "default")
S3method("roc", "formula")
S3method("roc", "data.frame")
export(roc_)
export(roc.test)
S3method("roc.test", "roc")
S3method("roc.test", "smooth.roc")
S3method("roc.test", "default")
S3method("roc.test", "formula")
S3method("roc.test", "auc")
export(smooth)
S3method("smooth", "roc")
S3method("smooth", "smooth.roc")
S3method("smooth", "default")
export(var)
S3method("var", "roc")
S3method("var", "smooth.roc")
S3method("var", "default")
S3method("var", "auc")
S3method("Ops", "auc")
S3method("Ops", "ci.se")
S3method("Ops", "ci.sp")
S3method("Ops", "ci.auc")
S3method("Math", "auc")
S3method("Math", "ci.se")
S3method("Math", "ci.sp")
S3method("Math", "ci.auc")
S3method("lines", "roc")
S3method("lines", "smooth.roc")
export(lines.roc)
S3method("lines.roc", "roc")
S3method("lines.roc", "smooth.roc")
S3method("lines.roc", "formula")
S3method("lines.roc", "default")
S3method("plot", "roc")
S3method("plot", "smooth.roc")
S3method("plot", "ci.thresholds")
S3method("plot", "ci.sp")
S3method("plot", "ci.se")
S3method("plot", "ci.coords")
export(plot.roc)
S3method("plot.roc", "roc")
S3method("plot.roc", "smooth.roc")
S3method("plot.roc", "formula")
S3method("plot.roc", "default")
export(ggroc)
S3method("ggroc", "roc")
S3method("ggroc", "smooth.roc")
S3method("ggroc", "list")
export(geom_polygon_auc)
S3method("geom_polygon_auc", "auc")
S3method("geom_polygon_auc", "roc")
S3method("geom_polygon_auc", "smooth.roc")
#export(select)
#export(select_)
#importFrom("dplyr", "select")
#importFrom("dplyr", "select_")
#S3method("select", "roc")
#S3method("select_", "roc")
# Fix R CMD check warning false positives
# "apparent S3 methods exported but not registered"
# Note: these methods have an export() above
S3method("roc", "test")
S3method("ci", "coords")
S3method("ci", "se")
S3method("ci", "sp")
S3method("ci", "thresholds")
import(Rcpp, grDevices, graphics, stats)
useDynLib(pROC, .registration = TRUE)
pROC/inst/ 0000755 0001762 0000144 00000000000 14427235226 012041 5 ustar ligges users pROC/inst/CITATION 0000644 0001762 0000144 00000002037 14427235226 013200 0 ustar ligges users citHeader("If you use pROC in published research, please cite the following paper:")
bibentry(bibtype="Article",
title = "pROC: an open-source package for R and S+ to analyze and compare ROC curves",
author = c(as.person("Xavier Robin"), as.person("Natacha Turck") , as.person("Alexandre Hainard") , as.person("Natalia Tiberti") , as.person("Frédérique Lisacek") , as.person("Jean-Charles Sanchez"), as.person("Markus Müller")),
year = 2011,
journal = "BMC Bioinformatics",
volume = 12,
pages = 77,
#doi = "10.1186/1471-2105-12-77", # removed: takes too much space
#url = "http://www.biomedcentral.com/1471-2105/12/77/",
textVersion = "Xavier Robin, Natacha Turck, Alexandre Hainard, Natalia Tiberti, Frédérique Lisacek, Jean-Charles Sanchez and Markus Müller (2011). pROC: an open-source package for R and S+ to analyze and compare ROC curves. BMC Bioinformatics, 12, p. 77.\n DOI: 10.1186/1471-2105-12-77 "
)
pROC/inst/extra/ 0000755 0001762 0000144 00000000000 15040443562 013160 5 ustar ligges users pROC/inst/extra/benchmark.Rmd 0000644 0001762 0000144 00000033430 13607143106 015557 0 ustar ligges users ---
output:
github_document:
toc: true
toc_depth: 2
---
```{r, echo = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "bench/fig-"
)
```
```{r, echo = FALSE}
library(ggplot2)
```
# Benchmarks
These benchmarks compare pROC with competing ROC analysis packages in R. They can
serve as a way to detect performance bottleneck that must be fixed, and
possible regressions in performance.
The benchmarking are carried out with the **microbenchmark** package and randomly
generated data. The values of the `x` predictor variable are drawn from a normal distribution, resulting in every value being
essentially unique. Predictor values for positive examples are increased to have a mean of 1, resulting in ROC curves with an AUC of 0.76.
The benchmark code is adapted from the [cutpointr vignette by Christian Thiele](https://github.com/Thie1e/cutpointr/blob/master/vignettes/cutpointr.Rmd),
released under a GPL-3 license.
## Building the ROC curve
This first benchmark looks at the time needed to building the ROC curve only, and getting sensitivities, specificities and thresholds. Only packages allowing turn off the
calculation of the AUC, or not computing it by default, were tested.
```{r, echo = FALSE}
# Simply compute sensitivity, specificity and thresholds
rocr_roc <- function(predictor, response) {
pred <- ROCR::prediction(predictor, response)
perf <- ROCR::performance(pred, "sens", "spec")
se <- slot(perf, "y.values")[[1]]
sp <- slot(perf, "x.values")[[1]]
thr <- slot(perf, "alpha.values")[[1]]
}
proc_roc <- function(response, predictor) {
r <- pROC::roc(response, predictor, algorithm = 2, levels = c(0, 1), direction = "<",
auc = FALSE)
se <- r$sensitivities
sp <- r$specificities
thr <- r$thresholds
}
```
```{r, echo = FALSE}
n <- 1000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
roc_bench_1000 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x)
)
n <- 10000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
roc_bench_10000 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
times=50
)
n <- 1e5
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
roc_bench_1e5 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
times = 20
)
n <- 1e6
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
roc_bench_1e6 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
times = 15
)
n <- 1e7
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
roc_bench_1e7 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
times = 10
)
roc_results <- rbind(
data.frame(time = summary(roc_bench_1000)$median,
solution = summary(roc_bench_1000)$expr,
n = 1000),
data.frame(time = summary(roc_bench_10000)$median,
solution = summary(roc_bench_10000)$expr,
n = 10000),
data.frame(time = summary(roc_bench_1e5)$median,
solution = summary(roc_bench_1e5)$expr,
n = 1e5),
data.frame(time = summary(roc_bench_1e6)$median,
solution = summary(roc_bench_1e6)$expr,
n = 1e6),
data.frame(time = summary(roc_bench_1e7)$median,
solution = summary(roc_bench_1e7)$expr,
n = 1e7)
)
roc_results$solution <- as.character(roc_results$solution)
roc_results$solution[grep(pattern = "rocr", x = roc_results$solution)] <- "ROCR"
roc_results$solution[grep(pattern = "proc", x = roc_results$solution)] <- "pROC"
```
```{r, echo = FALSE}
ggplot(roc_results, aes(x = n, y = time, col = solution, shape = solution)) +
geom_point(size = 3) + geom_line() +
scale_y_log10(breaks = c(3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) +
scale_x_log10(breaks = c(1000, 1e4, 1e5, 1e6, 1e7)) +
ggtitle("ROC building benchmark results", "n = 1000, 10000, 1e5, 1e6, 1e7") +
ylab("Median time (milliseconds, log scale)") + xlab("n (log scale)")
```
```{r, echo = FALSE}
res_table <- tidyr::spread(roc_results, solution, time)
knitr::kable(res_table)
```
## AUC
This benchmark tests how long it takes to calculate the ROC curve and the area under the ROC curve (AUC).
```{r, echo = FALSE}
# Calculate the AUC
rocr_auc <- function(predictor, response) {
pred <- ROCR::prediction(predictor, response)
perf <- ROCR::performance(pred, measure = "auc")
perf@y.values[[1]]
}
proc_auc <- function(response, predictor) {
r <- pROC::roc(response, predictor, algorithm = 2, levels = c(0, 1), direction = "<")
r$auc
}
prroc_auc <- function(positives, negatives) {
r <- PRROC::roc.curve(positives, negatives)
r$auc
}
epi_auc <- function(predictor, response) {
e <- Epi::ROC(predictor, response, plot=FALSE)
e$AUC
}
```
```{r, echo = FALSE}
n <- 1000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
negatives <- dat$x[dat$y == 0]
positives <- dat$x[dat$y == 1]
auc_bench_1000 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
prroc_auc(positives, negatives),
epi_auc(dat$x, dat$y)
)
n <- 10000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
negatives <- dat$x[dat$y == 0]
positives <- dat$x[dat$y == 1]
auc_bench_10000 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
prroc_auc(positives, negatives),
epi_auc(dat$x, dat$y),
times=50
)
n <- 1e5
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
negatives <- dat$x[dat$y == 0]
positives <- dat$x[dat$y == 1]
auc_bench_1e5 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
prroc_auc(positives, negatives),
epi_auc(dat$x, dat$y),
times = 20
)
n <- 1e6
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
negatives <- dat$x[dat$y == 0]
positives <- dat$x[dat$y == 1]
auc_bench_1e6 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
prroc_auc(positives, negatives),
epi_auc(dat$x, dat$y),
times = 15
)
n <- 1e7
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
negatives <- dat$x[dat$y == 0]
positives <- dat$x[dat$y == 1]
auc_bench_1e7 <- microbenchmark::microbenchmark(unit = "ms",
rocr_roc(dat$x, dat$y),
proc_roc(dat$y, dat$x),
prroc_auc(positives, negatives),
times = 10
)
auc_results <- rbind(
data.frame(time = summary(auc_bench_1000)$median,
solution = summary(auc_bench_1000)$expr,
n = 1000),
data.frame(time = summary(auc_bench_10000)$median,
solution = summary(auc_bench_10000)$expr,
n = 10000),
data.frame(time = summary(auc_bench_1e5)$median,
solution = summary(auc_bench_1e5)$expr,
n = 1e5),
data.frame(time = summary(auc_bench_1e6)$median,
solution = summary(auc_bench_1e6)$expr,
n = 1e6),
data.frame(time = summary(auc_bench_1e7)$median,
solution = summary(auc_bench_1e7)$expr,
n = 1e7)
)
auc_results$solution <- as.character(auc_results$solution)
auc_results$solution[grep(pattern = "epi", x = auc_results$solution)] <- "Epi"
auc_results$solution[grep(pattern = "prroc", x = auc_results$solution)] <- "PRROC"
auc_results$solution[grep(pattern = "rocr", x = auc_results$solution)] <- "ROCR"
auc_results$solution[grep(pattern = "proc", x = auc_results$solution)] <- "pROC"
```
```{r, echo = FALSE}
ggplot(auc_results, aes(x = n, y = time, col = solution, shape = solution)) +
geom_point(size = 3) + geom_line() +
scale_y_log10(breaks = c(3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) +
scale_x_log10(breaks = c(1000, 1e4, 1e5, 1e6, 1e7)) +
ggtitle("ROC building benchmark results", "n = 1000, 10000, 1e5, 1e6, 1e7") +
ylab("Median time (milliseconds, log scale)") + xlab("n (log scale)")
```
```{r, echo = FALSE}
res_table <- tidyr::spread(auc_results, solution, time)
knitr::kable(res_table)
```
## Best threshold
Benchmarks packages that extract the "best" threshold. At the moment they all use the Youden index. This includes building the ROC curve first.
```{r, echo = FALSE}
# Get the best threshold as a numeric value
proc_best <- function(response, predictor) {
r <- pROC::roc(response, predictor, algorithm = 2, levels = c(0, 1), direction = "<")
pROC::coords(r, "best", ret="threshold", drop=TRUE)
}
cutpointr_best <- function(data, predictor_name, response_name) {
cu <- cutpointr::cutpointr_(data, predictor_name, response_name,
pos_class = 1, neg_class = 0,
direction = ">=", metric = cutpointr::youden,
break_ties = mean)
cu[,"optimal_cutpoint", drop=TRUE]
}
optimalcutpoints_best <- function(data, predictor_name, response_name) {
o <- OptimalCutpoints::optimal.cutpoints(predictor_name, response_name, data=data,
tag.healthy = 0, methods = "Youden")
o$Youden$Global$optimal.cutoff$cutoff
}
thresholdroc_best <- function(negatives, positives) {
tr <- ThresholdROC::thres2(negatives, positives, rho = 0.5,
method = "empirical", ci = FALSE)
tr$T$thres
}
```
```{r, echo = FALSE}
n <- 100
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
positives <- dat$x[dat$y == 1]
negatives <- dat$x[dat$y == 0]
best_bench_100 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
optimalcutpoints_best(dat, "x", "y"),
thresholdroc_best(negatives, positives),
unit = "ms"
)
n <- 1000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
positives <- dat$x[dat$y == 1]
negatives <- dat$x[dat$y == 0]
best_bench_1000 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
optimalcutpoints_best(dat, "x", "y"),
thresholdroc_best(negatives, positives),
unit = "ms"
)
n <- 10000
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
positives <- dat$x[dat$y == 1]
negatives <- dat$x[dat$y == 0]
best_bench_10000 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
optimalcutpoints_best(dat, "x", "y"),
thresholdroc_best(negatives, positives),
times = 20, unit = "ms"
)
n <- 1e5
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
positives <- dat$x[dat$y == 1]
negatives <- dat$x[dat$y == 0]
best_bench_1e5 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
times = 20, unit = "ms"
)
n <- 1e6
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
best_bench_1e6 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
times = 10, unit = "ms"
)
n <- 1e7
set.seed(123)
dat <- data.frame(x = rnorm(n), y = sample(c(0:1), size = n, replace = TRUE))
dat$x <- dat$x + dat$y
best_bench_1e7 <- microbenchmark::microbenchmark(
proc_best(dat$y, dat$x),
cutpointr_best(dat, "x", "y"),
times = 10, unit = "ms"
)
best_results <- rbind(
data.frame(time = summary(best_bench_100)$median,
solution = summary(best_bench_100)$expr,
n = 100),
data.frame(time = summary(best_bench_1000)$median,
solution = summary(best_bench_1000)$expr,
n = 1000),
data.frame(time = summary(best_bench_10000)$median,
solution = summary(best_bench_10000)$expr,
n = 10000),
data.frame(time = summary(best_bench_1e5)$median,
solution = summary(best_bench_1e5)$expr,
n = 1e5),
data.frame(time = summary(best_bench_1e6)$median,
solution = summary(best_bench_1e6)$expr,
n = 1e6),
data.frame(time = summary(best_bench_1e7)$median,
solution = summary(best_bench_1e7)$expr,
n = 1e7)
)
best_results$solution <- as.character(best_results$solution)
best_results$solution[grep(pattern = "cutpointr", x = best_results$solution)] <- "cutpointr"
best_results$solution[grep(pattern = "optimalcutpoints", x = best_results$solution)] <- "OptimalCutpoints"
best_results$solution[grep(pattern = "proc", x = best_results$solution)] <- "pROC"
best_results$solution[grep(pattern = "thresholdroc", x = best_results$solution)] <- "ThresholdROC"
```
```{r, echo = FALSE}
ggplot(best_results, aes(x = n, y = time, col = solution, shape = solution)) +
geom_point(size = 3) + geom_line() +
scale_y_log10(breaks = c(3, 5, 10, 25, 100, 250, 1000, 5000, 1e4, 15000)) +
scale_x_log10(breaks = c(100, 1000, 1e4, 1e5, 1e6, 1e7)) +
ggtitle("Benchmark results", "n = 1000, 10000, 1e5, 1e6, 1e7") +
ylab("Median time (milliseconds, log scale)") + xlab("n (log scale)")
```
```{r, echo = FALSE}
res_table <- tidyr::spread(best_results, solution, time)
knitr::kable(res_table)
```
pROC/inst/extra/benchmark.md 0000644 0001762 0000144 00000007214 13607143106 015436 0 ustar ligges users
# Benchmarks
These benchmarks compare pROC with competing ROC analysis packages in R.
They can serve as a way to detect performance bottleneck that must be
fixed, and possible regressions in performance.
The benchmarking are carried out with the **microbenchmark** package and
randomly generated data. The values of the `x` predictor variable are
drawn from a normal distribution, resulting in every value being
essentially unique. Predictor values for positive examples are increased
to have a mean of 1, resulting in ROC curves with an AUC of 0.76.
The benchmark code is adapted from the [cutpointr vignette by Christian
Thiele](https://github.com/Thie1e/cutpointr/blob/master/vignettes/cutpointr.Rmd),
released under a GPL-3 license.
## Building the ROC curve
This first benchmark looks at the time needed to building the ROC curve
only, and getting sensitivities, specificities and thresholds. Only
packages allowing turn off the calculation of the AUC, or not computing
it by default, were tested.

| n | pROC | ROCR |
| -------: | -----------: | ----------: |
| 1e+03 | 0.6579095 | 2.059954 |
| 1e+04 | 3.6905450 | 5.727894 |
| 1e+05 | 41.4205780 | 49.021695 |
| 1e+06 | 600.3593600 | 643.874491 |
| 1e+07 | 8220.1797555 | 9012.922116 |
| \#\# AUC | | |
This benchmark tests how long it takes to calculate the ROC curve and
the area under the ROC curve (AUC).

| n | Epi | pROC | PRROC | ROCR |
| ----: | ----------: | ----------: | ---------: | ----------: |
| 1e+03 | 5.635899 | 0.683097 | 0.33761 | 2.184626 |
| 1e+04 | 66.644144 | 5.037177 | 2.21852 | 7.965816 |
| 1e+05 | 579.622447 | 35.752837 | 15.31815 | 44.327074 |
| 1e+06 | 8352.085559 | 583.754913 | 181.14614 | 757.437651 |
| 1e+07 | NA | 8276.516090 | 2899.50254 | 9149.835111 |
## Best threshold
Benchmarks packages that extract the “best” threshold. At the moment
they all use the Youden index. This includes building the ROC curve
first.
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found
#> Multiple optimal cutpoints found

| n | cutpointr | OptimalCutpoints | pROC | ThresholdROC |
| ----: | ----------: | ---------------: | ----------: | -----------: |
| 1e+02 | 4.779029 | 1.959683 | 0.569432 | 1.032499 |
| 1e+03 | 5.395060 | 30.739701 | 1.034866 | 22.389875 |
| 1e+04 | 7.195595 | 2902.387499 | 4.311928 | 2018.123223 |
| 1e+05 | 26.105981 | NA | 39.171103 | NA |
| 1e+06 | 276.263793 | NA | 579.522941 | NA |
| 1e+07 | 4258.031252 | NA | 8329.708682 | NA |
pROC/inst/extra/bench/ 0000755 0001762 0000144 00000000000 13607143106 014235 5 ustar ligges users pROC/inst/extra/bench/fig-unnamed-chunk-5-1.png 0000644 0001762 0000144 00000106631 13607143106 020552 0 ustar ligges users PNG
IHDR Hc pHYs od IDATxw\SlH[pbQnqB`¶Vցj{m{:VmN\npZ*V6ǹ7T IN_|$y'!9ߜ`E! `~P ; CP ; CP ;do_~$ɐɓ't碢yiӆ;99u}*nOGqƍe04t{ݭ={>|Ky3>F֭omX,˭1|,YѺy LAZ;@s̟~ɓ::p &:t(**jcƌ1{xGGGWWgϞYQ }hÖ3g_>==}x''ӧOwU7Ι3>HMM[RiBBױc_VXѫWɓ'ݼ,(@,--
c .ס'OWUU8p#M6#G-֭+))駟!|rTzС-+Voɩ_~ЩSp0~n
6DDDD{_p&Gumƌ7n2dX,nѢźusή]}^xgϞ/iAݾ}{Сnnn=d4Ʊcz-
-Z$oz*}kHH{9cƌ~-**J,GGGgggwb800c
ׯo@ puu߿k&%%mڴsٲe/=ﻺS.z^Sm?>ð /۷oG={͛7#9BQZfov=B-[|nZ6++K"zSee%B(444 oYtźz*}-Z|dž!I299;vӋ/FEGGY?r...111>***w}yfQQB'Oo]~=B(&&fÆ
$ID4\xfwy͚5_}'Oc