From d04c7be6a26b8ce16332f2181391b9314952e044 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 18:16:54 -0800 Subject: [PATCH 01/12] new test --- .Rbuildignore | 1 + R/graph.decay.curves.R | 2 +- man/plot_curve_params_one_ab.Rd | 2 +- .../plot_curve_params_one_ab/curve-r1.svg | 78 +++++++++++++++++++ .../testthat/test-plot_curve_params_one_ab.R | 22 ++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg create mode 100644 tests/testthat/test-plot_curve_params_one_ab.R diff --git a/.Rbuildignore b/.Rbuildignore index 77aa1893..0c2cb4a4 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -31,3 +31,4 @@ allpopsamples_hlye.csv$ ^\.quarto$ ^man/check_strata\.Rd$ ^man/df_to_array\.Rd$ +^man/plot_curve_params_one_ab\.Rd$ diff --git a/R/graph.decay.curves.R b/R/graph.decay.curves.R index a9248be8..45626176 100644 --- a/R/graph.decay.curves.R +++ b/R/graph.decay.curves.R @@ -36,7 +36,7 @@ #' load_curve_params("https://osf.io/download/rtw5k/") %>% #' dplyr::filter(antigen_iso == "HlyE_IgG") %>% #' serocalculator:::plot_curve_params_one_ab() -#' +#' @dev plot_curve_params_one_ab <- function( object, verbose = FALSE, diff --git a/man/plot_curve_params_one_ab.Rd b/man/plot_curve_params_one_ab.Rd index 9b312a07..09bcd61f 100644 --- a/man/plot_curve_params_one_ab.Rd +++ b/man/plot_curve_params_one_ab.Rd @@ -118,5 +118,5 @@ library(dplyr) # loads the `\%>\%` operator and `dplyr::filter()` load_curve_params("https://osf.io/download/rtw5k/") \%>\% dplyr::filter(antigen_iso == "HlyE_IgG") \%>\% serocalculator:::plot_curve_params_one_ab() - } +\keyword{internal} diff --git a/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg b/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg new file mode 100644 index 00000000..8cc8690b --- /dev/null +++ b/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 +10 +100 +1,000 +10,000 + + + + + + + + + + + + +0 +5 +10 +15 +20 +25 +Days since fever onset +Antibody concentration +Antibody Response Curve + + diff --git a/tests/testthat/test-plot_curve_params_one_ab.R b/tests/testthat/test-plot_curve_params_one_ab.R new file mode 100644 index 00000000..7ab6ae6e --- /dev/null +++ b/tests/testthat/test-plot_curve_params_one_ab.R @@ -0,0 +1,22 @@ +test_that("`plot_curve_params_one_ab()` produces consistent results", { + params <- + data.frame( + y0 = 10, + y1 = 10 ^ 4, + t1 = 9.5, + alpha = 0.01, + r = 1, + antigen_iso = "test" + ) |> + as_curve_params() + + + fig1 <- + params |> + plot_curve_params_one_ab(n_points = 10^5, + xlim = c(0,25)) + + fig1 |> + vdiffr::expect_doppelganger(title = "curve_r1") + +}) From 0ff8f0dd11a4ff36672a7101dbe26de3281521a7 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:18:11 -0800 Subject: [PATCH 02/12] fixed bug when r = 1 --- R/ab0.R | 12 ++- tests/testthat/_snaps/ab0.md | 28 +++++ .../plot_curve_params_one_ab/curve-r1.svg | 100 +++++++++--------- tests/testthat/test-ab0.R | 44 ++++++++ .../testthat/test-plot_curve_params_one_ab.R | 3 +- 5 files changed, 134 insertions(+), 53 deletions(-) create mode 100644 tests/testthat/_snaps/ab0.md create mode 100644 tests/testthat/test-ab0.R diff --git a/R/ab0.R b/R/ab0.R index c661753d..05fe602a 100644 --- a/R/ab0.R +++ b/R/ab0.R @@ -1,7 +1,5 @@ # uses r > 1 scale for shape -ab0 <- function( - t, - curve_params) { +ab0 <- function(t, curve_params) { y0 <- curve_params[["y0"]] y1 <- curve_params[["y1"]] t1 <- curve_params[["t1"]] @@ -13,7 +11,13 @@ ab0 <- function( yt <- 0 yt_phase_1 <- y0 * exp(beta * t) - yt_phase_2 <- (y1^(1 - shape) - (1 - shape) * alpha * (t - t1))^(1 / (1 - shape)) + if (shape == 1) { + yt_phase_2 <- y1 * exp(-alpha * (t - t1)) + # see https://www.wolframalpha.com/input?i=lim+%5By%5E%281%2Fr%29+-+k%2Fr%5D%5Er+as+r+-%3E+inf + } else { + yt_phase_2 <- (y1 ^ (1 - shape) - (1 - shape) * alpha * (t - t1)) ^ (1 / (1 - shape)) + } + yt <- dplyr::if_else(t <= t1, yt_phase_1, yt_phase_2) return(yt) } diff --git a/tests/testthat/_snaps/ab0.md b/tests/testthat/_snaps/ab0.md new file mode 100644 index 00000000..674e99cc --- /dev/null +++ b/tests/testthat/_snaps/ab0.md @@ -0,0 +1,28 @@ +# `ab0()` produces consistent results + + Code + calc1 + Output + [1] 9298.6747 + +--- + + Code + calc2 + Output + [1] 9990.005 + +--- + + Code + calc3 + Output + [1] 9298.6747 + +--- + + Code + calc4 + Output + [1] 909.09091 + diff --git a/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg b/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg index 8cc8690b..1e722303 100644 --- a/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg +++ b/tests/testthat/_snaps/plot_curve_params_one_ab/curve-r1.svg @@ -21,58 +21,62 @@ - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - -1 -10 -100 -1,000 -10,000 - - - - - - - - - - - - -0 -5 -10 -15 -20 -25 -Days since fever onset + +0 +2500 +5000 +7500 +10000 + + + + + + + + + + + + +0 +5 +10 +15 +20 +25 +Days since fever onset Antibody concentration -Antibody Response Curve +Antibody Response Curve diff --git a/tests/testthat/test-ab0.R b/tests/testthat/test-ab0.R new file mode 100644 index 00000000..73631bce --- /dev/null +++ b/tests/testthat/test-ab0.R @@ -0,0 +1,44 @@ +test_that("`ab0()` produces consistent results", { + params1 <- + data.frame( + y0 = 10, + y1 = 10 ^ 4, + t1 = 9.5, + alpha = 0.01, + r = 1, + antigen_iso = "test" + ) |> + as_curve_params() + + calc1 = + ab0(curve_params = params1, t = 9.4) + + expect_snapshot(calc1) + + calc2 = + ab0(curve_params = params1, t = 9.6) + + expect_snapshot(calc2) + + params2 <- + data.frame( + y0 = 10, + y1 = 10^4, + t1 = 9.5, + alpha = 0.01, + r = 2, + antigen_iso = "test" + ) |> + as_curve_params() + + calc3 = + ab0(curve_params = params2, t = 9.4) + + expect_snapshot(calc3) + + calc4 = + ab0(curve_params = params2, t = 9.6) + + expect_snapshot(calc4) + +}) diff --git a/tests/testthat/test-plot_curve_params_one_ab.R b/tests/testthat/test-plot_curve_params_one_ab.R index 7ab6ae6e..c43603a9 100644 --- a/tests/testthat/test-plot_curve_params_one_ab.R +++ b/tests/testthat/test-plot_curve_params_one_ab.R @@ -14,7 +14,8 @@ test_that("`plot_curve_params_one_ab()` produces consistent results", { fig1 <- params |> plot_curve_params_one_ab(n_points = 10^5, - xlim = c(0,25)) + xlim = c(0,25), + log_y = FALSE) fig1 |> vdiffr::expect_doppelganger(title = "curve_r1") From 8c6aa1a69a558a587cb4e1945c3c5821342f2867 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:22:07 -0800 Subject: [PATCH 03/12] update version and news --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6b5dd1e1..2069a351 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: serocalculator Title: Estimating Infection Rates from Serological Data -Version: 1.2.0.9022 +Version: 1.2.0.9023 Authors@R: c( person("Peter", "Teunis", , "p.teunis@emory.edu", role = c("aut", "cph"), comment = "Author of the method and original code."), diff --git a/NEWS.md b/NEWS.md index f352a8a7..ecb644c6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## New features +* Fixed a bug in computing the antibody response curve when $r=1$ (#323) + * Added example datasets with documentation for examples and testing (#314) * Improved error messaging for `autoplot.pop_data()` (#234). From 720857c5bf7b536df804ec9ee598a402890903ac Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:28:35 -0800 Subject: [PATCH 04/12] switch to snapshot value --- tests/testthat/_snaps/ab0.md | 20 ++++---------------- tests/testthat/test-ab0.R | 8 ++++---- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/tests/testthat/_snaps/ab0.md b/tests/testthat/_snaps/ab0.md index 674e99cc..a991286f 100644 --- a/tests/testthat/_snaps/ab0.md +++ b/tests/testthat/_snaps/ab0.md @@ -1,28 +1,16 @@ # `ab0()` produces consistent results - Code - calc1 - Output - [1] 9298.6747 + 9298.67465260527 --- - Code - calc2 - Output - [1] 9990.005 + 9990.00499833375 --- - Code - calc3 - Output - [1] 9298.6747 + 9298.67465260527 --- - Code - calc4 - Output - [1] 909.09091 + 909.090909090912 diff --git a/tests/testthat/test-ab0.R b/tests/testthat/test-ab0.R index 73631bce..dd5775ab 100644 --- a/tests/testthat/test-ab0.R +++ b/tests/testthat/test-ab0.R @@ -13,12 +13,12 @@ test_that("`ab0()` produces consistent results", { calc1 = ab0(curve_params = params1, t = 9.4) - expect_snapshot(calc1) + expect_snapshot_value(calc1, style = "deparse") calc2 = ab0(curve_params = params1, t = 9.6) - expect_snapshot(calc2) + expect_snapshot_value(calc2, style = "deparse") params2 <- data.frame( @@ -34,11 +34,11 @@ test_that("`ab0()` produces consistent results", { calc3 = ab0(curve_params = params2, t = 9.4) - expect_snapshot(calc3) + expect_snapshot_value(calc3, style = "deparse") calc4 = ab0(curve_params = params2, t = 9.6) - expect_snapshot(calc4) + expect_snapshot_value(calc4, style = "deparse") }) From 6a5d83482536b0595b8fd8a3df9e48378a6151e6 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:30:01 -0800 Subject: [PATCH 05/12] lint --- tests/testthat/test-ab0.R | 11 +++++------ tests/testthat/test-plot_curve_params_one_ab.R | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/testthat/test-ab0.R b/tests/testthat/test-ab0.R index dd5775ab..ddd8cab1 100644 --- a/tests/testthat/test-ab0.R +++ b/tests/testthat/test-ab0.R @@ -2,7 +2,7 @@ test_that("`ab0()` produces consistent results", { params1 <- data.frame( y0 = 10, - y1 = 10 ^ 4, + y1 = 10^4, t1 = 9.5, alpha = 0.01, r = 1, @@ -10,12 +10,12 @@ test_that("`ab0()` produces consistent results", { ) |> as_curve_params() - calc1 = + calc1 <- ab0(curve_params = params1, t = 9.4) expect_snapshot_value(calc1, style = "deparse") - calc2 = + calc2 <- ab0(curve_params = params1, t = 9.6) expect_snapshot_value(calc2, style = "deparse") @@ -31,14 +31,13 @@ test_that("`ab0()` produces consistent results", { ) |> as_curve_params() - calc3 = + calc3 <- ab0(curve_params = params2, t = 9.4) expect_snapshot_value(calc3, style = "deparse") - calc4 = + calc4 <- ab0(curve_params = params2, t = 9.6) expect_snapshot_value(calc4, style = "deparse") - }) diff --git a/tests/testthat/test-plot_curve_params_one_ab.R b/tests/testthat/test-plot_curve_params_one_ab.R index c43603a9..f631191d 100644 --- a/tests/testthat/test-plot_curve_params_one_ab.R +++ b/tests/testthat/test-plot_curve_params_one_ab.R @@ -13,11 +13,11 @@ test_that("`plot_curve_params_one_ab()` produces consistent results", { fig1 <- params |> - plot_curve_params_one_ab(n_points = 10^5, - xlim = c(0,25), + plot_curve_params_one_ab(n_points = 10 ^ 5, + xlim = c(0, 25), log_y = FALSE) fig1 |> - vdiffr::expect_doppelganger(title = "curve_r1") + vdiffr::expect_doppelganger(title = "curve_r1") }) From da10ca98bb9fcb3d0446a123ad14db5f4e453c95 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:45:52 -0800 Subject: [PATCH 06/12] internal --- .Rbuildignore | 1 - R/graph.decay.curves.R | 4 ++-- man/plot_curve_params_one_ab.Rd | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 0c2cb4a4..77aa1893 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -31,4 +31,3 @@ allpopsamples_hlye.csv$ ^\.quarto$ ^man/check_strata\.Rd$ ^man/df_to_array\.Rd$ -^man/plot_curve_params_one_ab\.Rd$ diff --git a/R/graph.decay.curves.R b/R/graph.decay.curves.R index 45626176..d05b60f2 100644 --- a/R/graph.decay.curves.R +++ b/R/graph.decay.curves.R @@ -35,8 +35,8 @@ #' #' load_curve_params("https://osf.io/download/rtw5k/") %>% #' dplyr::filter(antigen_iso == "HlyE_IgG") %>% -#' serocalculator:::plot_curve_params_one_ab() -#' @dev +#' serocalculator::plot_curve_params_one_ab() +#' @keywords internal plot_curve_params_one_ab <- function( object, verbose = FALSE, diff --git a/man/plot_curve_params_one_ab.Rd b/man/plot_curve_params_one_ab.Rd index 09bcd61f..886bf624 100644 --- a/man/plot_curve_params_one_ab.Rd +++ b/man/plot_curve_params_one_ab.Rd @@ -117,6 +117,6 @@ library(dplyr) # loads the `\%>\%` operator and `dplyr::filter()` load_curve_params("https://osf.io/download/rtw5k/") \%>\% dplyr::filter(antigen_iso == "HlyE_IgG") \%>\% - serocalculator:::plot_curve_params_one_ab() + serocalculator::plot_curve_params_one_ab() } \keyword{internal} From 8b8af51e6e24c2b7cb7c23232372fb6f06d1c58c Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:47:53 -0800 Subject: [PATCH 07/12] lint --- R/ab0.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ab0.R b/R/ab0.R index 05fe602a..d5193cea 100644 --- a/R/ab0.R +++ b/R/ab0.R @@ -13,7 +13,7 @@ ab0 <- function(t, curve_params) { yt_phase_1 <- y0 * exp(beta * t) if (shape == 1) { yt_phase_2 <- y1 * exp(-alpha * (t - t1)) - # see https://www.wolframalpha.com/input?i=lim+%5By%5E%281%2Fr%29+-+k%2Fr%5D%5Er+as+r+-%3E+inf + # see wolfram alpha result: https://bit.ly/3ZB69Yn } else { yt_phase_2 <- (y1 ^ (1 - shape) - (1 - shape) * alpha * (t - t1)) ^ (1 / (1 - shape)) } From 605f07b53fa2de8eaadbc52666825eadae1999d1 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:53:46 -0800 Subject: [PATCH 08/12] comment --- R/ab0.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/ab0.R b/R/ab0.R index d5193cea..637a328e 100644 --- a/R/ab0.R +++ b/R/ab0.R @@ -14,6 +14,8 @@ ab0 <- function(t, curve_params) { if (shape == 1) { yt_phase_2 <- y1 * exp(-alpha * (t - t1)) # see wolfram alpha result: https://bit.ly/3ZB69Yn + # this is a version the product-limit characterization of the + # exponential function } else { yt_phase_2 <- (y1 ^ (1 - shape) - (1 - shape) * alpha * (t - t1)) ^ (1 / (1 - shape)) } From 93b0f8b78b933952354e454b4251f7f97847f3d7 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 19:59:21 -0800 Subject: [PATCH 09/12] lint --- R/ab0.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/ab0.R b/R/ab0.R index 637a328e..b515524a 100644 --- a/R/ab0.R +++ b/R/ab0.R @@ -4,20 +4,21 @@ ab0 <- function(t, curve_params) { y1 <- curve_params[["y1"]] t1 <- curve_params[["t1"]] alpha <- curve_params[["alpha"]] - shape <- curve_params[["r"]] + r <- curve_params[["r"]] beta <- bt(y0, y1, t1) yt <- 0 yt_phase_1 <- y0 * exp(beta * t) - if (shape == 1) { + if (r == 1) { yt_phase_2 <- y1 * exp(-alpha * (t - t1)) # see wolfram alpha result: https://bit.ly/3ZB69Yn # this is a version the product-limit characterization of the # exponential function } else { - yt_phase_2 <- (y1 ^ (1 - shape) - (1 - shape) * alpha * (t - t1)) ^ (1 / (1 - shape)) + yt_phase_2 <- + (y1^(1 - r) - (1 - r) * alpha * (t - t1))^(1 / (1 - r)) } yt <- dplyr::if_else(t <= t1, yt_phase_1, yt_phase_2) From 5bd7e468a0bba8abf35ae83d23906486b411ab92 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 20:12:01 -0800 Subject: [PATCH 10/12] put it back the way it was --- R/graph.decay.curves.R | 3 +-- man/plot_curve_params_one_ab.Rd | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/R/graph.decay.curves.R b/R/graph.decay.curves.R index d05b60f2..67501449 100644 --- a/R/graph.decay.curves.R +++ b/R/graph.decay.curves.R @@ -35,8 +35,7 @@ #' #' load_curve_params("https://osf.io/download/rtw5k/") %>% #' dplyr::filter(antigen_iso == "HlyE_IgG") %>% -#' serocalculator::plot_curve_params_one_ab() -#' @keywords internal +#' serocalculator:::plot_curve_params_one_ab() plot_curve_params_one_ab <- function( object, verbose = FALSE, diff --git a/man/plot_curve_params_one_ab.Rd b/man/plot_curve_params_one_ab.Rd index 886bf624..3fcb3fc2 100644 --- a/man/plot_curve_params_one_ab.Rd +++ b/man/plot_curve_params_one_ab.Rd @@ -117,6 +117,5 @@ library(dplyr) # loads the `\%>\%` operator and `dplyr::filter()` load_curve_params("https://osf.io/download/rtw5k/") \%>\% dplyr::filter(antigen_iso == "HlyE_IgG") \%>\% - serocalculator::plot_curve_params_one_ab() + serocalculator:::plot_curve_params_one_ab() } -\keyword{internal} From 2b540a6d2d6200451c99772050693e6a75c10788 Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 20:12:37 -0800 Subject: [PATCH 11/12] revert --- R/graph.decay.curves.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/graph.decay.curves.R b/R/graph.decay.curves.R index 67501449..387b1445 100644 --- a/R/graph.decay.curves.R +++ b/R/graph.decay.curves.R @@ -36,6 +36,7 @@ #' load_curve_params("https://osf.io/download/rtw5k/") %>% #' dplyr::filter(antigen_iso == "HlyE_IgG") %>% #' serocalculator:::plot_curve_params_one_ab() + plot_curve_params_one_ab <- function( object, verbose = FALSE, From 902be9a2c9035fad96f34a3e1d803e5a32e33cfa Mon Sep 17 00:00:00 2001 From: Douglas Ezra Morrison Date: Tue, 3 Dec 2024 20:12:58 -0800 Subject: [PATCH 12/12] revert --- R/graph.decay.curves.R | 2 +- man/plot_curve_params_one_ab.Rd | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/R/graph.decay.curves.R b/R/graph.decay.curves.R index 387b1445..a9248be8 100644 --- a/R/graph.decay.curves.R +++ b/R/graph.decay.curves.R @@ -36,7 +36,7 @@ #' load_curve_params("https://osf.io/download/rtw5k/") %>% #' dplyr::filter(antigen_iso == "HlyE_IgG") %>% #' serocalculator:::plot_curve_params_one_ab() - +#' plot_curve_params_one_ab <- function( object, verbose = FALSE, diff --git a/man/plot_curve_params_one_ab.Rd b/man/plot_curve_params_one_ab.Rd index 3fcb3fc2..9b312a07 100644 --- a/man/plot_curve_params_one_ab.Rd +++ b/man/plot_curve_params_one_ab.Rd @@ -118,4 +118,5 @@ library(dplyr) # loads the `\%>\%` operator and `dplyr::filter()` load_curve_params("https://osf.io/download/rtw5k/") \%>\% dplyr::filter(antigen_iso == "HlyE_IgG") \%>\% serocalculator:::plot_curve_params_one_ab() + }