Repeated measurements over time · Choose a method

Tumour growth curves: how to compare treatment groups when mice reach the humane endpoint

Compare tumour growth rates on the log scale using every measurement up to culling, with a mixed model or per-mouse slopes. Comparing only the mice still measured on the last day underestimates the effect. Python and R code.

By Licklider · Published · Last reviewed · How this page was made · Markdown

On this page
  1. Which analysis for your question
  2. Why the last-day comparison misleads
  3. Worked example: 8 mice per group, 5 control mice culled at the limit after day 18
  4. Before you analyse
  5. Check what an AI assistant ran
  6. Report it
  7. References

Quick answer. Analyse tumour volume on the log scale and compare growth rates, using every measurement of every mouse up to the day it was culled: preferably a linear mixed model (a growth line per mouse, log(volume) ~ day * group + (day | mouse), where * means group, day and their interaction, and (day | mouse) gives each mouse its own starting size and slope), which stays valid when mice leave for a reason already recorded in the measured volumes, as with a size limit; or, more simply, one growth-rate slope per mouse compared between groups, which works well when growth is close to linear on the log scale and few mice leave early. Report the difference in growth rate with its 95% confidence interval (the ratio of rates and the doubling times can be added as descriptions). Do not compare only the mice still alive on the last day: control mice with the largest tumours were culled first, so the survivors make the drug look weaker, and a t-test on each day multiplies the chances of a false positive. If reaching the size limit is itself the outcome, compare time to endpoint with survival methods.

Terms used below. Tumour volume: usually estimated from calliper length and width as length × width² / 2. Log scale: the natural logarithm of volume; exponential growth becomes a straight line. Growth rate: the slope of log volume against time, per day. Doubling time: ln 2 divided by the growth rate. Humane endpoint: the tumour size or condition at which a mouse must be culled. Informative dropout: measurements missing for a reason related to the outcome, here because the tumour grew large. Survivors: mice still measured on a given day. T/C: mean tumour volume of treated mice divided by that of control mice on one day (here geometric means, on the log scale). Linear mixed model: a regression that fits a line for each mouse and the average line for each group. Random effect: the part of the model that lets each mouse have its own starting size and growth rate. Missing at random: whether a value is missing depends only on values already observed. 95% confidence interval (CI): the range of effects compatible with the data. Welch’s t-test: compares two means without assuming equal spread. Geometric mean: the mean on the log scale, converted back to volume. Fixed effects: the group, day and group × day terms the model estimates. Random intercept and slope: the two random effects here, for starting size and for growth rate. Satterthwaite df: an approximation to the degrees of freedom for tests in a mixed model. Wald CI: an interval of estimate ± 1.96 standard errors. Power: the chance of detecting an effect that is really there. Post hoc test: a comparison made after an overall test, here between groups on each day. Kaplan–Meier curve: the share of mice not yet at the endpoint over time. Log-rank test and Cox model: standard survival comparisons (see the linked guide). Hazard ratio: how much faster one group reaches the endpoint than the other. Spaghetti plot: one line per mouse. Size-limit culling is informative dropout (the largest tumours leave), but it is missing at random given the volumes already measured, which is why the mixed model can use it.

Which analysis for your question

Your question Analysis Report
Does the drug slow tumour growth? Linear mixed model on log volume with a group × day term, or per-mouse slopes compared with Welch’s t-test Difference (or ratio) in growth rate with 95% CI; doubling times
Does the drug delay reaching the humane endpoint? Time to endpoint: Kaplan–Meier curves and a log-rank test or Cox model (log-rank vs Cox); the crossing time is known only to lie between two measurement days, so state the convention (for example the first day at or above the limit) Median time to endpoint, hazard ratio with CI
How large is the tumour at a fixed day? Comparison of log volume on a day, planned in advance, before any mouse has been culled; not on a later day T/C or volume ratio with CI
Do some tumours shrink (regress), or are responses mixed? Plot every mouse’s curve; a mixed model with heterogeneous responses (Laajala et al. 2012) Numbers of mice responding, with the definition used

Hather and colleagues found that comparing growth rates is more efficient than comparing volumes on one day: “the rate-based T/C requires fewer animals to achieve the same power as the traditional T/C”, and switching to it allowed “a reduction from 10 animals to 7 animals with no reduction in Z-score” (Hather et al. 2014). Laajala and colleagues describe mixed-effects models as a way to model experimental factors “while accounting for variation expressed by individual animals or tumors (random effects)” (Laajala et al. 2012).

Why the last-day comparison misleads

Mice are culled when their tumour reaches the size limit your institution sets; the UK guidelines give limits on mean tumour diameter (for therapeutic studies in mice, normally 1.5 cm) (Workman et al. 2010); convert that diameter limit into a volume with the formula you use. So the largest control tumours leave the study first. Wu describes the usual practice of using “the T/C ratio at the last time point with complete observations” and notes that analysing only the last time point “discards useful data and could result in a considerable loss of efficency [sic]” (Wu 2010). Comparing a later day using only the survivors is worse: the remaining controls are those whose tumours were still below the limit, so the control mean is too low.

Worked example: 8 mice per group, 5 control mice culled at the limit after day 18

Constructed data: tumour volume every 3 days from day 0 to day 21 in 8 vehicle and 8 drug-treated mice. By construction log volume grows by 0.15 per day in controls (doubling about every 4.6 days) and 0.10 per day with the drug (about 6.9 days), and each mouse is culled after its first measurement at or above 1,500 mm³ (an illustrative limit). The random seed was fixed before the first run and was not chosen for its result. Stored code and data: tumours.csv, model.py (the growth and culling model), make_data.py, analysis.py, analysis.R and the analysis output (analysis.py and analysis.R print the same output); the mixed model is in mixed_model.R with its output.

Analysis Result
Mice measured on day 21 Vehicle 3 of 8 (5 culled at the limit); drug 8 of 8
Day 21, survivors only (biased) T/C 0.45, p = 0.0015
Welch’s t-test on each day (inflates false positives; see the simulation) p < 0.05 on 6 of the 7 days after day 0
Growth rate per mouse Vehicle 0.154, drug 0.102 per day; difference −0.052 per day (95% CI −0.073 to −0.030), p = 0.00014; rate ratio 0.66; doubling time 4.5 vs 6.8 days
Linear mixed model (lme4) Difference −0.052 per day (Wald 95% CI −0.071 to −0.032; Satterthwaite df 13.9), p = 0.00014; the interval differs slightly because the model weights mice by their number of measurements

Both growth-rate analyses agree: the drug slows growth by about a third. The day-21 T/C of 0.45 uses only the three controls still below the limit on day 18 (a mix of slower growth and smaller starting size); without culling, the true day-21 T/C in this model is 0.35. In 10,000 simulated experiments of this design (simulation.py, the simulation output):

Scenario Growth-rate comparison Day 21, survivors only Any single day p < 0.05
No drug effect (false positives) 4.2% 4.1% 18.5%
Drug slows growth (power) 98.8% 61.0% 93.9%

Among the survivors, the median day-21 T/C was 0.50 against the true 0.35, and in 3.2% of experiments too few controls were left on day 21 for any test. The per-mouse slope uses each mouse’s measurements up to culling and works well when growth is close to linear on the log scale and few mice leave early; the mixed model does the same while weighting mice by how many measurements they have, and it is valid when dropout depends on volumes already measured, as with a size limit (longitudinal models are “valid under the assumption of data missing at random”, Wu 2010). Prefer the mixed model when many mice leave early; use per-mouse slopes if the model will not fit. In Python, statsmodels’ mixedlm fits the same model but gives no small-sample degrees of freedom, so the per-mouse slopes are the safer Python route with groups this small.

# Condensed: the full script, which also prints the day-21 and day-by-day tests, is analysis.py
import numpy as np, pandas as pd
from scipy import stats

d = pd.read_csv("tumours.csv")                       # columns: mouse, group, day, volume_mm3; one row per measurement
# wide sheet (one column per day)? d = d_wide.melt(id_vars=["mouse", "group"], var_name="day", value_name="volume_mm3")
#   then make day a number: d["day"] = d["day"].str.extract(r"(\d+)", expand=False).astype(float)
d["logv"] = np.log(d.volume_mm3)
d = d.groupby("mouse").filter(lambda m: len(m) >= 2)  # a slope needs two measurements; report any mouse dropped
rate = d.groupby(["group", "mouse"]).apply(lambda m: np.polyfit(m.day, m.logv, 1)[0], include_groups=False)
v, g = rate["vehicle"], rate["drug"]                 # growth rate per day for each mouse (pandas >= 2.2)
t = stats.ttest_ind(g, v, equal_var=False)           # Welch
ci = t.confidence_interval()                         # 95% CI of the difference in mean rate
print(v.mean(), g.mean(), g.mean() - v.mean(), ci.low, ci.high, t.pvalue)   # doubling time = ln 2 / rate
d <- read.csv("tumours.csv")
d$group <- factor(d$group, levels = c("vehicle", "drug"))
library(lmerTest)                                    # lme4 with p-values (Satterthwaite df)
fit <- lmer(log(volume_mm3) ~ day * group + (day | mouse), data = d)
summary(fit)$coefficients["day:groupdrug", ]         # difference in growth rate per day
confint(fit, parm = "day:groupdrug", method = "Wald")
emmeans::emtrends(fit, ~ group, var = "day")         # growth rate in each group
# warning "boundary (singular) fit: see help('isSingular')" or no convergence? use (1 | mouse),
#   say so in the Methods, and check that the per-mouse slopes agree
# wide sheet? d <- tidyr::pivot_longer(d_wide, -c(mouse, group), names_to = "day", values_to = "volume_mm3")
#   then make day a number: d$day <- readr::parse_number(d$day)

Before you analyse

  1. Plot every mouse. A spaghetti plot of log volume against day shows whether growth is roughly linear on the log scale, whether some tumours regress, and when each mouse left.
  2. Use the log scale. Variation in volume grows with size; on the log scale growth is close to linear and the spread steadier. If some tumours are unmeasurable (zero), decide in advance how to handle them, for example a small floor value, and report it.
  3. Decide the summary in advance. Growth rate, time to endpoint, or volume on a fixed day while all mice are alive; choosing after looking at several of them is a form of multiple testing.
  4. Randomise after tumours are established, so that starting volumes are balanced, and measure blind to group (randomisation and blinding). Calliper volumes have more measurement error than imaging: Jensen and colleagues report intra-observer coefficients of variation of “7% and 14% for microCT and caliper measurements, respectively”, and found that callipers overestimate volume more for large tumours, so that “volume changes measured with caliper in small and large tumors are not comparable” (Jensen et al. 2008). Use one trained observer, and imaging or tumour weight at the end as a check.
  5. One tumour per mouse in the analysis, or a model term for mouse if each mouse carries two (what counts as n).
  6. Know why mice left. The mixed model handles culling at a size limit; if mice were culled for reasons not reflected in the measured volumes (ulceration, weight loss), report them and consider a time-to-endpoint analysis as well.
  7. State the T/C convention. Write treated / control and the day; publications differ in direction and in using arithmetic or geometric means.

Check what an AI assistant ran

  1. A two-way ANOVA with a post hoc test on every day. Ask for one growth-rate comparison (mixed model or per-mouse slopes) and the CI of the difference.
  2. A t-test on the last day using only the mice still alive. Ask how many mice per group were included and why the others are missing.
  3. Raw volumes instead of log volumes. Ask for the log scale, or a check that the model fits.
  4. Missing values carried forward from the last measurement (last observation carried forward). Ask for a method that uses the observed measurements, such as the mixed model.

Report it

Methods:

Tumour volume was estimated as length × width² / 2 from calliper measurements every [3] days, blind to group. Mice were culled when tumour volume reached [1,500] mm³. Log-transformed volumes were analysed with a linear mixed model with group, day and their interaction as fixed effects and a random intercept and slope for each mouse (lme4 [1.1-35.1] and lmerTest [3.1-3], R [4.3.3]); all measurements up to culling were used; because culling was triggered by the measured tumour volume, the missing later measurements were missing at random given the observed volumes. The primary outcome, specified in advance, was the difference in growth rate between groups.

If you used per-mouse slopes instead:

A least-squares slope of log volume against day was fitted for each mouse, using all measurements up to culling; mean slopes were compared between groups with Welch’s t-test.

Results:

Tumours grew more slowly with the drug: growth rate [0.102] vs [0.154] per day (doubling time [6.8] vs [4.5] days); difference [−0.052] per day (95% CI [−0.071] to [−0.032]; p = [0.00014]). [5] of [8] vehicle-treated mice reached the humane endpoint before day [21], and none of the drug-treated mice.

Replace the bracketed values with your own.

References

  • Hather G, Liu R, Bandi S, et al. (2014). Growth rate analysis and efficient experimental design for tumor xenograft studies. Cancer Informatics 13(Suppl 4):65–72. doi:10.4137/CIN.S13974
  • Laajala TD, Corander J, Saarinen NM, et al. (2012). Improved statistical modeling of tumor growth and treatment effect in preclinical animal studies with highly heterogeneous responses in vivo. Clinical Cancer Research 18:4385–4396. doi:10.1158/1078-0432.CCR-11-3215
  • Wu J (2010). Statistical inference for tumor growth inhibition T/C ratio. Journal of Biopharmaceutical Statistics 20:954–964. doi:10.1080/10543401003618983
  • Workman P, Aboagye EO, Balkwill F, et al. (2010). Guidelines for the welfare and use of animals in cancer research. British Journal of Cancer 102:1555–1577. doi:10.1038/sj.bjc.6605642
  • Jensen MM, Jørgensen JT, Binderup T, Kjær A (2008). Tumor volume in subcutaneous mouse xenografts measured by microCT is more accurate and reproducible than determined by 18F-FDG-microPET or external caliper. BMC Medical Imaging 8:16. doi:10.1186/1471-2342-8-16

How this page was made

  • Written and published by Licklider. Recommendations cite peer-reviewed methods papers and animal-welfare guidelines listed under References; cited passages were checked against the source text.
  • The worked example uses constructed data. Its numbers were produced by stored code (Python 3.13 with pandas 3.0.5 and SciPy 1.18.1; R 4.3.3, with lme4 1.1-35.1, lmerTest 3.1-3 and emmeans 1.10.0 for the mixed model), and the two languages print identical output; the simulation was run in Python.
  • Separate review passes checked the statistics, the citations and readability before publication.