5 Results

5.1 Compute concentrations

Rearranging the 4-PL equation for concentration \(c\) gives:

\[\log_2{c} = \dfrac{1}{n} \left[ \log{\left( \dfrac{\mathrm{A_{max}} - A}{A - \mathrm{A_{min}}}\right)} + n \cdot \log_2{\mathrm{EC_{50}}} \right] \].

We compute the concentrations of our biological samples using the estimated calibration curve and plot the results:

log2concentration.est <- sapply(donors.av$absorbance.av,
  function(A)
  (1/n.est) * (log( ((Amax.est - A)/(A - Amin))) + log2EC50.est*n.est))

# Get confidence intervals
# TODO: experimental -- to double-check
fgh <- deriv(
  log2concentration ~ (1/n) * (log( ((Amax - A)/(A - Amin))) + log2EC50*n),
  c("Amax", "log2EC50", "n"), function(Amax, log2EC50, n, A) {}
)
f.new <- fgh(Amax.est, log2EC50.est, n.est, donors.av$absorbance.av)
g.new <- attr(f.new, "gradient")
gs <- rowSums((g.new %*% cov.fit) * g.new)
alpha <- 0.05
delta.f <- sqrt(gs) * qt(1 - alpha/2, 15)
results <- donors.av %>% 
  dplyr::mutate(concentration.est = 2^log2concentration.est) %>%
  dplyr::mutate(log2concentration.est = log2concentration.est) %>%
  dplyr::mutate(log2conf = delta.f) 

# Inspect results
head(results)
## # A tibble: 6 x 7
##   donor  time absorbance.av ID     concentration.est log2concentration… log2conf
##   <fct> <int>         <dbl> <chr>              <dbl>              <dbl>    <dbl>
## 1 1         0         0.336 AB1981            0.0685              -3.87    0.241
## 2 1         7         0.596 AB1981            0.135               -2.89    0.155
## 3 1        30         0.710 AB1981            0.170               -2.56    0.147
## 4 1        60         0.804 AB1981            0.203               -2.30    0.147
## 5 1       180         0.482 AB1981            0.104               -3.27    0.178
## 6 2         0         0.534 CD1982            0.118               -3.09    0.165

5.2 Plot results

plot.results <- ggplot(
    data = results,
    aes(time, concentration.est, color = donor)
  ) +
  geom_line(aes(time, concentration.est, group = donor), 
    alpha = 0.6, lwd = 0.5
  ) +
  labs(
    x = "Days after vaccination",
    y = "Relative concentration",
    title = "[Illustrative example] IgG in serum after vaccination"
  ) +
  scale_color_viridis(
    begin = 0.2, end = 0.8, discrete = TRUE,
    labels = paste("Donor", seq(n.donors)), guide = guide_legend(title = "")
  ) +
  scale_x_continuous(breaks = tpoints) +
  background_grid(
    major = "yx", minor = "", colour.major = "grey90", size.major = 0.2
  ) +
  theme_plot() +
  geom_pointrange(
    aes(ymin = concentration.est / 2^log2conf, 
        ymax = concentration.est * 2^log2conf), 
    shape = 21, size = 0.4
  ) +
  scale_y_continuous(labels = scales::percent)

plot.results