Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
53491ce
# add one more input quantiles
Kwan-Jenny Apr 19, 2025
ed4b2ba
# update test file of graph.curve.params
Kwan-Jenny Apr 19, 2025
0ee71d5
# version update
Kwan-Jenny Apr 19, 2025
e12d269
update NEWS.md file
Kwan-Jenny Apr 19, 2025
55f0294
# devtools::test() to generate test file of updating part in figure
Kwan-Jenny Apr 19, 2025
6d6d8b1
# Add updated testthat snapshot files after changes to graph.curve.pa…
Kwan-Jenny Apr 21, 2025
26902a4
# Add updated snapshot .csv files for graph.curve.params changes
Kwan-Jenny Apr 21, 2025
bb7d94e
# Fix lint issues in graph.curve.params.R
Kwan-Jenny Apr 21, 2025
d951038
Merge branch 'main' into update_graph_curve
d-morrison Apr 21, 2025
f14b4b9
# Refactor graph.curve.params(): numeric quantiles, remove show_quant…
Kwan-Jenny Apr 24, 2025
225939a
# Accept change on svg files
Kwan-Jenny Apr 24, 2025
3dd5078
# back to original code
Kwan-Jenny Apr 24, 2025
26c72c2
# Back to original code for labelling MCMC chain part
Kwan-Jenny Apr 24, 2025
5f28a62
# Qualify any column names inside
Kwan-Jenny Apr 24, 2025
4b1da96
# tidyselect deprecation warnings
Kwan-Jenny Apr 25, 2025
f3ec434
# update space in function to avoid error in lintr
Kwan-Jenny Apr 25, 2025
a95f10c
# update error from lintr issues
Kwan-Jenny Apr 25, 2025
9dd4229
# spaces
Kwan-Jenny Apr 25, 2025
fe2cbdd
# spaces again
Kwan-Jenny Apr 25, 2025
e8945ee
space again
Kwan-Jenny Apr 25, 2025
8fa1f7c
# correct spaces for line109
Kwan-Jenny Apr 25, 2025
8543801
# change to snake_case
Kwan-Jenny Apr 25, 2025
9664e3a
# nolint: object_name_linter on the two lines
Kwan-Jenny Apr 25, 2025
ce7a423
second # nolint: object_name_linter
Kwan-Jenny Apr 25, 2025
c635372
# remove the .data$ prefix from select() and unnest()
Kwan-Jenny Apr 25, 2025
e2edd1c
# Use Addins in Rstudio to check lint
Kwan-Jenny Apr 25, 2025
a78154d
# problem with tidyselect
Kwan-Jenny Apr 25, 2025
fe4ad61
Declare name and quantiles_df as known globals in graph.curve.params.…
Kwan-Jenny Apr 25, 2025
72f6376
# fix for lint but... other issues
Kwan-Jenny Apr 25, 2025
b64902b
# Sam's idea to help
Kwan-Jenny Apr 25, 2025
e60bbdb
Update R/graph.curve.params.R
Kwan-Jenny May 1, 2025
bdfbd9c
Update R/graph.curve.params.R
Kwan-Jenny May 1, 2025
1c08c7a
# update based on Sam's suggestion
Kwan-Jenny May 1, 2025
752949c
# forgot to do devtools::document()
Kwan-Jenny May 1, 2025
92b2442
# update code based on Sam's suggestions
Kwan-Jenny May 17, 2025
e62c82c
# forgot update documentation
Kwan-Jenny May 17, 2025
f27e31c
Update R/graph.curve.params.R
Kwan-Jenny May 30, 2025
15ecabb
# Sam's review + devtools::document()
Kwan-Jenny May 30, 2025
1339caf
Merge branch 'update_graph_curve' of https://github.com/UCD-SERG/sero…
Kwan-Jenny May 30, 2025
1abd307
Merge branch 'main' into update_graph_curve
d-morrison Jun 24, 2025
f72ead0
Update NEWS.md
Kwan-Jenny Jul 3, 2025
ab3fe13
Update R/graph.curve.params.R
Kwan-Jenny Jul 4, 2025
d9bbaec
# add external exmaple file in examples folder
Kwan-Jenny Jul 4, 2025
74f412d
# Reverted to original formatting — avoided unnecessary changes per a…
Kwan-Jenny Jul 4, 2025
06abe06
# Didn't recognize ab1 function and create ab function separately in …
Kwan-Jenny Jul 4, 2025
db37250
# I changed 'object' to 'curve_params' which term is more familiar bu…
Kwan-Jenny Jul 4, 2025
4971cf6
# I somehow changed it, possibly due to masking or linting issues — I…
Kwan-Jenny Jul 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: serocalculator
Title: Estimating Infection Rates from Serological Data
Version: 1.3.0.9047
Version: 1.3.0.9048
Authors@R: c(
person("Peter", "Teunis", , "p.teunis@emory.edu", role = c("aut", "cph"),
comment = "Author of the method and original code."),
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* Improved y-limit calculation in `graph.curve.params()` (#368)
* Added option for `graph.curve.params()` to show all curves (#368)
* Added color-coding for `graph.curve.params()` (#383)
* Added `quantiles` parameter to `graph.curve.params()` and corresponding test in `test-graph.curve.params.R` (#434)
* Removed `warn.missing.strata()` from API (#366)

* Added more details about contributing PRs in `Contributing.md` (#280)
Expand Down
224 changes: 86 additions & 138 deletions R/graph.curve.params.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,24 @@
#' @param antigen_isos antigen isotypes
#' @param alpha_samples `alpha` parameter passed to [ggplot2::geom_line]
#' (has no effect if `show_all_curves = FALSE`)
#' @param show_quantiles whether to show point-wise (over time) quantiles
#' @param quantiles Optional [numeric] [vector] of quantiles to plot
#' (e.g., 10%, 50%, and 90% = `c(0.1, 0.5, 0.9)`). If `NULL`, no quantile
#' lines are shown.
#'
#' @returns a [ggplot2::ggplot()] object
#' @returns a [ggplot2::ggplot()] object showing the antibody dynamic
#' kinetics of selected antigen/isotype combinations, with optional posterior
#' distribution quantile curves.
#' @export
#'
#' @examples
#' curve <-
#' typhoid_curves_nostrat_100 |>
#' dplyr::filter(antigen_iso %in% c("HlyE_IgA", "HlyE_IgG"))
#' @examples inst/examples/exm-graph.curve.params.R
#'
#' plot1 <- graph.curve.params(curve)
#'
#' print(plot1)
#'
#' plot2 <- graph.curve.params(curve, show_all_curves = TRUE)
#' show(plot2)
#'
graph.curve.params <- function( # nolint: object_name_linter
graph.curve.params <- function(# nolint: object_name_linter
curve_params,
antigen_isos = unique(curve_params$antigen_iso),
verbose = FALSE,
show_quantiles = TRUE,
show_all_curves = FALSE,
alpha_samples = 0.3
alpha_samples = 0.3,
quantiles = c(0.1, 0.5, 0.9) # numeric, flexible
Comment thread
Kwan-Jenny marked this conversation as resolved.
) {
if (verbose) {
message(
Expand All @@ -39,34 +33,12 @@
)
}

curve_params <- curve_params |>
object <- object |>
dplyr::filter(.data$antigen_iso %in% antigen_isos)

tx2 <- 10^seq(-1, 3.1, 0.025)

bt <- function(y0, y1, t1) {
log(y1 / y0) / t1
}

# uses r > 1 scale for shape
ab <- function(t, y0, y1, t1, alpha, shape) {
beta <- bt(y0, y1, t1)

yt <- 0

if (t <= t1) {
yt <- y0 * exp(beta * t)
}

if (t > t1) {
yt <- (y1^(1 - shape) - (1 - shape) * alpha * (t - t1))^(1 / (1 - shape))
}

return(yt)
}


d <- curve_params
d <- object

dT <- # nolint: object_linter
data.frame(t = tx2) |>
Expand All @@ -83,149 +55,125 @@
)
)


serocourse_all <-
cbind(d, dT) |>
tidyr::pivot_longer(
cols = dplyr::starts_with("time"),
values_to = "t"
) |>
select(-"name") |>
rowwise() |>
mutate(res = ab(
.data$t,
.data$y0,
.data$y1,
.data$t1,
.data$alpha,
.data$r
)) |>
ungroup()

if (verbose) message("starting to compute quantiles")
serocourse_sum <- serocourse_all |>
summarise(
.by = c("antigen_iso", "t"),
res.med = quantile(.data$res, 0.5),
res.low = quantile(.data$res, 0.025),
res.high = quantile(.data$res, 0.975),
res.p75 = quantile(.data$res, 0.75),
res.p25 = quantile(.data$res, 0.25),
res.p10 = quantile(.data$res, 0.10),
res.p90 = quantile(.data$res, 0.90)
dplyr::select(-c("name")) |>
dplyr::rowwise() |>
dplyr::mutate(
res = ab1(
.data$t,
.data$y0,
.data$y1,
.data$t1,
.data$alpha,
.data$r
)
) |>
pivot_longer(
names_to = "quantile",
cols = c(
"res.med",
"res.low",
"res.high",
"res.p25",
"res.p75",
"res.p10",
"res.p90"
),
names_prefix = "res.",
values_to = "res"
)

dplyr::ungroup()

if (!is.null(quantiles)) {
serocourse_sum <- serocourse_all |>
dplyr::group_by(.data$antigen_iso, .data$t) |>
dplyr::summarise(

Check notice on line 81 in R/graph.curve.params.R

View check run for this annotation

codefactor.io / CodeFactor

R/graph.curve.params.R#L81

Remove unnecessary c() of a constant. (unnecessary_concatenation_linter)
res_vals = list(.data$res),
.groups = "drop"
) |>
dplyr::mutate(
quantiles_df = purrr::map(
.data$res_vals,
~ tibble::tibble(
quantile = quantiles,
res = stats::quantile(.x, probs = quantiles, na.rm = TRUE)
)
)
) |>
tidyr::unnest(c("quantiles_df"))
}

range <-
serocourse_sum |>
dplyr::filter(.data$quantile %in% c("med", "p10", "p90")) |>
serocourse_all |>
dplyr::summarize(
min = min(.data$res, 0.9),
max = max(.data$res, 2000)
min = min(.data$res, na.rm = TRUE),
max = max(.data$res, na.rm = TRUE)
Comment on lines -137 to +101

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not entirely sure since this part was coded a few months ago, but I think I changed it to make the function more general and data-driven. Instead of using hardcoded limits, it now reflects the actual range of the model output, and na.rm = TRUE helps handle any potential missing values. It seemed like a safer and more flexible approach for broader use.

)


plot1 <-
serocourse_sum |>
ggplot2::ggplot() +
ggplot2::aes(x = .data$t,
y = .data$res) +
ggplot2::facet_wrap(
~ .data$antigen_iso,
ncol = 2
) +
plot1 <- ggplot2::ggplot() +
ggplot2::aes(x = .data$t, y = .data$res) +
ggplot2::facet_wrap(~ antigen_iso, ncol = 2) +
ggplot2::theme_minimal() +
ggplot2::theme(axis.line = ggplot2::element_line()) +
ggplot2::labs(x = "Days since fever onset",
y = "ELISA units",
col = if_else(show_all_curves, "MCMC chain", "")) +
ggplot2::labs(
x = "Days since fever onset",
y = "ELISA units",

Check notice on line 111 in R/graph.curve.params.R

View check run for this annotation

codefactor.io / CodeFactor

R/graph.curve.params.R#L111

Remove unnecessary c() of a constant. (unnecessary_concatenation_linter)
col = if (show_all_curves) "MCMC chain" else NULL
) +
ggplot2::theme(legend.position = "bottom")

if (show_all_curves) {

range <-
serocourse_all |>
dplyr::summarize(
min = min(.data$res, 0.9),
max = max(.data$res, 2000)
)

group_vars <-
c("iter", "chain") |>
if (show_all_curves) {
group_vars <- c("iter", "chain") |>
intersect(names(serocourse_all))

if (length(group_vars) > 1) {
serocourse_all <-
serocourse_all |>
mutate(
iter = interaction(across(all_of(group_vars)))
dplyr::mutate(
iter = interaction(
dplyr::across(dplyr::all_of(group_vars))
)
)

plot1 <-
plot1 +
geom_line(
ggplot2::geom_line(
data = serocourse_all,
alpha = alpha_samples,
aes(
color = .data$chain |> factor(),
color = factor(.data$chain),
group = .data$iter
)
) +
ggplot2::expand_limits(y = range)
)
} else {

plot1 <-
plot1 +
geom_line(data = serocourse_all,
alpha = alpha_samples,
aes(group = .data$iter)) +
ggplot2::expand_limits(y = range)

ggplot2::geom_line(
data = serocourse_all,
alpha = alpha_samples,
aes(group = .data$iter)
)
}

plot1 <-
plot1 + ggplot2::expand_limits(y = unlist(range))
}

plot1 <-
plot1 +
plot1 <- plot1 +
ggplot2::scale_y_log10(
limits = unlist(range),
labels = scales::label_comma(),
minor_breaks = NULL
)

if (show_quantiles) {
plot1 <-
plot1 +
ggplot2::geom_line(
ggplot2::aes(col = "median"),
data = serocourse_sum |> filter(.data$quantile == "med"),
linewidth = 1
) +
if (!is.null(quantiles)) {
plot1 <- plot1 +
ggplot2::geom_line(
ggplot2::aes(col = "10% quantile"),
data = serocourse_sum |> filter(quantile == "p10"),
linewidth = .5
) +
ggplot2::geom_line(
ggplot2::aes(col = "90% quantile"),
data = serocourse_sum |> filter(quantile == "p90"),
linewidth = .5
data = serocourse_sum,
aes(
color = paste0(.data$quantile * 100, "% quantile"),
group = .data$quantile
),
linewidth = 0.75
)

if (show_all_curves) {
plot1 <- plot1 +
ggplot2::labs(col = "MCMC chain")
}
}

return(plot1)

return(plot1)
}
15 changes: 15 additions & 0 deletions inst/examples/exm-graph.curve.params.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Load example dataset
curve <- typhoid_curves_nostrat_100 |>
dplyr::filter(antigen_iso %in% c("HlyE_IgA", "HlyE_IgG"))

# Plot without showing all curves
plot1 <- graph.curve.params(curve)
print(plot1)

# Plot with additional quantiles and show all curves
plot2 <- graph.curve.params(
curve,
show_all_curves = TRUE,
quantiles = c(0.1, 0.5, 0.9)
)
print(plot2)
19 changes: 12 additions & 7 deletions man/graph.curve.params.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading