Starting cancer medicine trials with children

Analysis of start of trials with children in relation to marketing authorisation for adults
dataset
procedures
Author

Ralf Herold

Published

2022-04-23

Modified

2026-01-28

Background and method

Medicines developed and authorised for cancers in adults are often relevant to be investigated for cancers in children (Jaffee et al. 2017). Investigating potential cancer medicines in children is recommended to be started early and before authorisation (Pearson et al. 2017).

This time relation is addressed on this page, to allow inspecting changes over the last decades and to further inform policies. In the U.S., requirements for molecularly targeted paediatric cancer investigations apply from mid-2020 (U.S. Food and Drug Administration 2018) and will be tracked in the future.

Information from the EU Clinical Trials Register and ClinicalTrials.Gov was used for this analysis using ctrdata. Paediatric trials were identified based on the protocol-related information that any of the paediatric age groups was to be included in the trial. Information on cancer medicines authorisations was retrieved from the EMA website. To reproduce the analysis, the R code is included below.

Start of trials with children in relation to when medicine was authorised in Europe

The figure shows all cancer medicines that are centrally authorised in Europe.

Dots indicate the date of the authorisation. Green dots marks cancer medicines that are authorised for children (full list is in another post). Whether the trial is part of a paediatric development plan (PIP) is not visualised here.

Code
# Code by ralf.herold@gmx.net

# last updates:
# - 2019-12-31 to match ctrdata 1.1 package
# - 2022-04-23 to match ctrdata 1.9 package
# - 2025-10-14 to Quarto document
# - 2026-01-25 to ctrdata 1.26.0 package

### Options for subsequent chunks

# knitr
knitr::opts_chunk$set(
  dev = 'svglite', 
  fig.width = 6, 
  fig.height = 12,
  out.width = '100%', 
  out.height = '1200px',
  width = '100%',
  eval = FALSE,
  echo = TRUE, 
  results = "asis",
  warning = FALSE, 
  message = FALSE,
  cache = FALSE
)

# Helper function
getAnnotationElements <- function(x, element = "AS") {
  
  # example from annotation.text: 
  # x <- "|AS:tisagenlecleucel| |AS:tisagenlecleucel|"
  
  x <- strsplit(x = x, split = "\\|")
  x <- unlist(x)
  x <- x[grepl(paste0("^", element, ":"), x)]
  x <- strsplit(x = x, split = ":")
  x <- unlist(x)
  x <- x[!grepl("AS", x)]
  sort(unique(x))
  
}

# Initialise
library(ggplot2)
library(stringr)
library(tidyr)
library(ctrdata)
library(dplyr)
library(stopwords)
library(glue)
library(ggiraph)
Code
# Get centrally authorised medicines

# https://www.ema.europa.eu/en/about-us/about-website/download-website-data-json-data-format
emaCapsJson <- "https://www.ema.europa.eu/en/documents/report/medicines-output-medicines_json-report_en.json"

# Read and transform
emaCapsList <- 
  url(emaCapsJson) |>
  jqr::jq(x = _, ".data") |>
  jsonlite::fromJSON() |>
  as_tibble()

# Select cancer medicines
emaAntiCancerList <- 
  emaCapsList |>
  filter(
    category == "Human",
    grepl("[Tt]reatment|[Tt]herapy", therapeutic_indication),
    generic_or_hybrid == "No",
    biosimilar == "No", 
    (grepl("ntineoplas", pharmacotherapeutic_group_human) |
       grepl("eoplasms|arcoma|ymphoproliferative", therapeutic_area_mesh))
  )

# Indication includes paediatric population
emaAntiCancerList <- 
  emaAntiCancerList |> 
  mutate(
    paediatricIndication = grepl(
      "children|adolescent|paediatric",
      therapeutic_indication
    )
  ) 

# Dates to date formats
emaAntiCancerList <- 
  emaAntiCancerList |> 
  mutate(
    across(
      ends_with("date"), 
      ~ as.Date(.x, format = "%d/%m/%Y")
    )
  ) 

# Selectively reword active substance 
# to more specifically identify trials
emaAntiCancerList$international_non_proprietary_name_common_name[
  emaAntiCancerList$name_of_medicine == "Spectrila"
] <- "recombinant asparaginase"
emaAntiCancerList$international_non_proprietary_name_common_name[
  emaAntiCancerList$name_of_medicine == "Abraxane"
] <- "nabpaclitaxel"


# Normalise active substances 
emaAntiCancerList$activeSubstancesToDo <- 
  emaAntiCancerList |> 
  pull(international_non_proprietary_name_common_name) |>
  stringi::stri_replace_all_regex(str = _, "[();,]", " ") |>
  stringi::stri_replace_all_regex(
    str = _, pattern = paste0(" ", stopwords("en", "smart"), " "), 
    replacement = " ", vectorize_all = FALSE) |>
  stringi::stri_replace_all_regex(str = _, " +", " ") 

# Keep earliest authorisation
emaAntiCancerList <- 
  emaAntiCancerList |> 
  filter(grepl("Authorised|Opinion", medicine_status)) |>
  group_by(activeSubstancesToDo) |>
  slice_min(marketing_authorisation_date, n = 1L) |>
  ungroup()

# Extract for search
activeSubstancesToDo <- 
  emaAntiCancerList |> 
  filter(activeSubstancesToDo != "") |>
  pull(activeSubstancesToDo) |>
  unique() |>
  sort()
Code
# Connect trial database
db <- nodbi::src_sqlite(
  # dbname = "cancertrials.sqlite",
  dbname = "posts/cancertrialschildren/trials.sqlite",
  collection = "emaAntiCancerList"
)

# Get any active substances already in 
# database as per the annotation field
if (nrow(dbQueryHistory(db)) > 0L) {
  
  # get active substances from annotations  
  asDone <- dbGetFieldsIntoDf(c("annotation"), con = db)
  asDone <- getAnnotationElements(x = asDone$annotation, element = "AS")
  
  # remove already downloaded active substances
  activeSubstancesToDo <- activeSubstancesToDo[
    !(activeSubstancesToDo %in% asDone)]
}

# Download trials by active substance
# this will take around 10 seconds per
# active substance, ca. 30 mins for all
for (thisAs in activeSubstancesToDo) {
  
  # - user info  
  message(rep("-", 80), "\n", thisAs)
  
  # - generate queries for all registers
  query <- ctrGenerateQueries(intervention = thisAs)
  
  # - download from relevant registers
  results <- suppressMessages(lapply(
    query[-4], 
    ctrLoadQueryIntoDb, 
    annotation.text = paste0("|AS:", thisAs, "|"),
    con = db))
  
  # - extract from results
  print(sapply(results, "[[", "n"))
  
}

# Database size approximately 2.5 GB
Code
# get trials
trialsSet <- dbGetFieldsIntoDf(
  fields = c(
    "annotation"
  ),
  calculate = c(
    "f.startDate",
    "f.trialTitle",
    "f.trialPopulation",
    "f.isUniqueTrial"
  ), 
  con = db)

# saveRDS(trialsSet, "trialsSet.rds")
# trialsSet <- readRDS("trialsSet.rds")

# deduplicate trials, keep
# trials with single-agent, 
# keep earliest trial that
# includes paediatric pop
trialsSet <- 
  trialsSet |>
  filter(.isUniqueTrial) |>
  filter(grepl("P", .trialPopulationAgeGroup)) |>
  rowwise() |>
  mutate(
    activeSubstancesToDo = list(getAnnotationElements(annotation)),
    activeSubstancesNumber = length(activeSubstancesToDo))  |>
  filter(activeSubstancesNumber == 1L) |> 
  mutate(activeSubstancesToDo = unlist(activeSubstancesToDo)) |>
  group_by(activeSubstancesToDo) |>
  slice_min(.startDate, n = 1L) |>
  ungroup() 

# merge trials and medicines
plotSet <- full_join(
  emaAntiCancerList,
  trialsSet,
  multiple = "all",
  relationship = "many-to-many",
  by = join_by(activeSubstancesToDo)
)

# inspect and handle duplicate cases
plotSet <- 
  plotSet |>
  filter(
    name_of_medicine != "Evotopin",
    `_id` != "NCT00042354"
  )

# format plot data
plotSet <- 
  plotSet |>
  arrange(marketing_authorisation_date) |>
  mutate(
    activeSubstance = str_trunc(
      activeSubstancesToDo, 20L),
    activeSubstance = factor(activeSubstance, levels = activeSubstance), 
    tooltip = glue(
      "{active_substance} ({name_of_medicine}):
       - authorised on: {marketing_authorisation_date}
       - authorised for children: {paediatricIndication}
       - first trial with children start: {.startDate}
       - first trial with children ID: {`_id`}"),
    timetrialma = difftime(
      marketing_authorisation_date, 
      .startDate, units = "days"),
    dotcolor = case_when(
      paediatricIndication ~ "green", 
      .default = "red"
    ), 
    segmentcolor = case_when(
      timetrialma > 5 * 365.25 ~ "green", 
      .default = "red"
    )
  )
Code
# Plot
trialMaPlot <- 
  ggplot(data = plotSet) +
  scale_color_identity() + 
  geom_point_interactive(
    aes(
      x = marketing_authorisation_date, 
      y = activeSubstance, 
      color = dotcolor,
      tooltip = tooltip,
      data_id = activeSubstance
    )
  ) + 
  geom_segment(
    aes(
      x = .startDate, 
      y = activeSubstance,
      xend = marketing_authorisation_date,
      color = segmentcolor, 
      group = activeSubstance
    )
  ) +
  xlim(as.Date(c("1988-01-01", "2030-01-01"))) + 
  labs(
    title = "Time relation of EU cancer medicines authorisation
             and start of first trial including children with cancer", 
    subtitle = paste0(
      "Data from EUCTR, CTIS, CTOV, ISRCTN\n", 
      "Line colour green if more than 5 years, otherwise red\n",
      "https://regulatorysciencedata.eu, ", format(Sys.Date(), format = "%Y-%m-%d"))
  ) +
  theme_gray(base_size = 8L)

# Interactive
iaPlot <- girafe(
  ggobj = trialMaPlot, 
  height_svg = 12L)

# Save for later static production
saveRDS(iaPlot, file = "./posts/cancertrialschildren/iaPlot.rds")

Lines indicate the time of start of a trial of the respective active substance that included the paediatric population (irrespective of subset, such as adolescents or broader paediatric age ranges) to initial marketing authorisation for the active substance. Green lines indicate that this trial was started at least 5 years before the marketing authorisation.

Hover over the symbols to see details.

Code
readRDS(file = "iaPlot.rds")

References

Jaffee, Elizabeth M., Chi Van Dang, David B. Agus, Brian M. Alexander, Kenneth C. Anderson, Alan Ashworth, Anna D. Barker, et al. 2017. “Future Cancer Research Priorities in the USA: A Lancet Oncology Commission.” The Lancet Oncology 18 (11): e653–706. https://doi.org/10.1016/S1470-2045(17)30698-8.
Pearson, Andrew D J, Stefan M Pfister, Andre Baruchel, Jean-Pierre Bourquin, Michela Casanova, Louis Chesler, François Doz, et al. 2017. “From Class Waivers to Precision Medicine in Paediatric Oncology.” The Lancet Oncology 18 (7): e394–404. https://doi.org/10.1016/S1470-2045(17)30442-4.
U.S. Food and Drug Administration. 2018. FDA Briefing Document - Relevant Molecular Targets in Pediatric Cancers: Applicability to Pediatric Therapeutic Investigations Required Under FDARA 2017.” https://www.fda.gov/media/112230/download.