Validates grouped binomial counts, combines rows with the same dose, and
calculates total subjects and observed response probabilities.
Metadata is optional: plain three-column inputs remain supported.
Supplied study_id, host, dose_unit, and endpoint must each contain
one non-missing, non-blank value throughout the input. study_id identifies
one experiment. Split different experiments into separate data frames before
fitting or testing poolability. Other metadata is preserved, but must agree
between rows sharing a dose. total and numeric response are recalculated;
use endpoint for the measured outcome, such as infection, illness, or death.
Value
A tibble with one row per dose and columns dose, positive,
negative, total, and numeric response, followed by optional metadata.
Details
Recognized column names are dose, positive / pos / positive_response,
and negative / neg / negative_response. Detection lowercases names and
replaces punctuation with underscores, so Positive.Response is recognized.
Other names require explicit mapping with the dose, positive, and
negative arguments, or renaming before calling this function. Data frames
and tibbles, including those created by tibble::tribble(), follow the same
rules. A total or response proportion cannot replace the two count columns.
Doses must be finite numeric values greater than zero; counts must be finite, non-negative whole numbers, with at least one subject per row. After combining repeated doses, at least three distinct doses and more than one positive response in total are required. Mapping names does not bypass these checks.
Examples
library(dplyr)
#>
#> Attaching package: ‘dplyr’
#> The following objects are masked from ‘package:stats’:
#>
#> filter, lag
#> The following objects are masked from ‘package:base’:
#>
#> intersect, setdiff, setequal, union
# Plain three-column data still works.
counts <- data.frame(dose = c(1, 10, 100), positive = c(1, 5, 9),
negative = c(9, 5, 1))
as_dose_response(counts)
#> # A tibble: 3 × 5
#> dose positive negative total response
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 9 10 0.1
#> 2 10 5 5 10 0.5
#> 3 100 9 1 10 0.9
# Recognized aliases need no mapping.
aliases <- dplyr::rename(counts, pos = positive, neg = negative)
as_dose_response(aliases)
#> # A tibble: 3 × 5
#> dose positive negative total response
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1 9 10 0.1
#> 2 10 5 5 10 0.5
#> 3 100 9 1 10 0.9
# Unrecognized names fail detection; map them or rename them first.
trial <- tibble::tribble(
~dose_amount, ~infected, ~uninfected,
1, 1, 9,
10, 5, 5,
100, 9, 1
)
tryCatch(as_dose_response(trial), error = function(e) message(conditionMessage(e)))
#> Could not detect the dose column; supply its name explicitly.
mapped <- as_dose_response(
trial, dose = "dose_amount", positive = "infected", negative = "uninfected"
)
renamed <- trial %>%
dplyr::rename(dose = dose_amount, positive = infected, negative = uninfected) %>%
as_dose_response()
identical(mapped, renamed)
#> [1] TRUE
# Add optional experiment identity and descriptive metadata.
counts$study_id <- "example_trial"
counts$host <- "human"
counts$dose_unit <- "FFU"
counts$endpoint <- "infection"
counts$citation <- "Synthetic teaching example"
as_dose_response(counts)
#> # A tibble: 3 × 10
#> dose positive negative total response study_id host dose_unit endpoint
#> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr>
#> 1 1 1 9 10 0.1 example_trial human FFU infection
#> 2 10 5 5 10 0.5 example_trial human FFU infection
#> 3 100 9 1 10 0.9 example_trial human FFU infection
#> # ℹ 1 more variable: citation <chr>
# Use endpoint for the outcome label, not the calculated response column.