---
title: "Higher-risk MDS"
bibliography: references.bib
format:
html:
toc: true
toc-depth: 3
code-fold: true
code-tools: true
theme: journal
pdf:
toc: true
number-sections: true
execute:
warning: false
message: false
---
# Azacitidine
## AZA-001
- CR rate was 17%
- median survival = 24 months
# HMA-combinations (FAILED)
- HMA + Lenalidomide
- HMA + Vorinostat
- HMA + volasertib
- HMA + Eltrombopag
- HMA + romiplostim
- HMA + Pracinostat\
- HMA + Durvalumab
- HMA + Pevonedistat
- HMA + APR246
- HMA + Magrolimab (ENHANCE phase 3)
- HMA + Sabatolimab
# Venetoclax combinations
## Venetoclax plus Azacitidine for treatment-naive HR-MDS[@Garcia2025]
After initially administering azacitidine and venetoclax similar to how the drugs are given to patients with AML, and realizing [a 20% septic death rate]{.underline}, the investigators cut the venetoclax dosing schedule in half, to 14 days of a 28-day cycle, combined with 7-day azacitidine dosing.
- Phase 1b study
- 90% of patient blasts \>5%
- N=107
- Venetoclax 400 mg (14days/cycle)[^higher-risk-mds-1] plus AZA 75 mg/m2 (7 days)
- CR rate was 29.9%
- CR and HI was 48.6%
- *marrow CR, but this has been eliminated as an acceptable International Working Group response criterion*[@Zeidan2023]
- median survival = 26 months
- 39% of patients went on to receive HCT
[^higher-risk-mds-1]: Venetoclax dose was reduced in more than half of the study patients and interrupted in ∼90% during the course of therapy, with 94% of patients experiencing grade 3 or 4 treatment-emergent adverse events.
## VERONA clinical trial
The VERONA study (NCT04401748) was a randomized, Phase 3 clinical trial evaluating the efficacy and safety of venetoclax (Ven) combined with azacitidine (Aza) versus placebo with azacitidine in treatment-naïve patients with intermediate and higher-risk myelodysplastic syndromes (MDS)
```{r}
#| label: setup
#| include: false
# Load required libraries
library(tidyverse)
library(knitr)
library(kableExtra)
library(ggplot2)
library(survival)
library(survminer)
library(gridExtra)
library(scales)
library(patchwork)
library(ggsci)
library(ggpubr)
# Set theme for all plots
theme_set(theme_minimal(base_size = 12))
# Custom color palette
trial_colors <- c("Ven+Aza" = "#E41A1C", "Pbo+Aza" = "#377EB8")
```
## Executive Summary
The VERONA study (NCT04401748) was a randomized, Phase 3 clinical trial evaluating the efficacy and safety of venetoclax (Ven) combined with azacitidine (Aza) versus placebo with azacitidine in treatment-naïve patients with intermediate and higher-risk myelodysplastic syndromes (MDS).
```{r}
#| label: summary-box
#| fig-width: 12
#| fig-height: 3
# Create key results summary
key_results <- data.frame(
Metric = c("Median OS", "Hazard Ratio", "Response Rate", "Grade ≥3 Neutropenia"),
Ven_Aza = c("22.18 months", "0.908", "76.6%", "76.9%"),
Pbo_Aza = c("21.68 months", "Reference", "57.7%", "58.9%"),
Difference = c("+0.5 months", "P = 0.38", "+18.9%", "+18.0%")
)
# Create a visual summary
summary_plot <- ggplot(data = data.frame(x = 1:4, y = 1)) +
annotate("rect", xmin = 0.5, xmax = 4.5, ymin = 0.5, ymax = 1.5,
fill = "lightblue", alpha = 0.3) +
annotate("text", x = 2.5, y = 1.3, label = "PRIMARY ENDPOINT NOT MET",
size = 6, fontface = "bold", color = "#E41A1C") +
annotate("text", x = 2.5, y = 0.7,
label = "No significant overall survival benefit (HR = 0.908, P = 0.38)",
size = 4.5) +
theme_void() +
labs(title = "VERONA Study Key Finding") +
theme(plot.title = element_text(size = 16, face = "bold", hjust = 0.5))
print(summary_plot)
```
## Study Design and Patient Characteristics
### Study Overview
```{r}
#| label: study-design
#| tbl-cap: "VERONA Study Design Parameters"
# Create comprehensive study design table
study_design <- tibble(
Parameter = c("ClinicalTrials.gov", "Study Phase", "Design", "Randomization",
"Total Enrollment", "Treatment Arm", "Control Arm",
"Primary Endpoint", "Key Secondary Endpoints",
"Stratification Factors", "Median Follow-up", "Data Cutoff"),
Details = c("NCT04401748",
"Phase 3",
"Randomized, double-blind, placebo-controlled",
"1:1 ratio",
"509 patients",
"Venetoclax 400 mg PO daily (Days 1-14) + Azacitidine 75 mg/m² (Days 1-7)",
"Placebo PO daily (Days 1-14) + Azacitidine 75 mg/m² (Days 1-7)",
"Overall Survival (OS)",
"Modified Overall Response (mOR), Safety",
"IPSS-R, transplant eligibility, region",
"41.2 months",
"April 10, 2025")
)
study_design %>%
kable(format = "html") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE) %>%
row_spec(c(6, 7), background = "#f0f0f0") %>%
row_spec(8, bold = TRUE, background = "#e6f2ff")
```
### Patient Demographics
```{r}
#| label: demographics-table
#| tbl-cap: "Baseline Patient Characteristics"
# Create patient demographics data
demographics <- data.frame(
Characteristic = c("Number of Patients", "Median Age (years)",
"ECOG PS 0-1 (%)", "ECOG PS 2 (%)",
"IPSS-R Intermediate (%)", "IPSS-R High/Very High (%)",
"BM Blasts ≤5%", "BM Blasts >5-10%", "BM Blasts >10-20%"),
`Ven+Aza` = c(256, 72, 92, 8, 27.5, 72.5, 25.8, 36.3, 37.9),
`Pbo+Aza` = c(253, 72, 92, 8, 27.5, 72.5, 28.8, 36.0, 35.2),
check.names = FALSE
)
demographics %>%
kable(format = "html", align = c("l", "c", "c")) %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE) %>%
add_header_above(c(" " = 1, "Treatment Arms" = 2)) %>%
row_spec(6, background = "#fff3cd") %>%
footnote(general = "BM = Bone Marrow; ECOG PS = Eastern Cooperative Oncology Group Performance Status",
general_title = "Abbreviations:")
```
### Baseline Characteristics Visualization
```{r}
#| label: baseline-visualization
#| fig-width: 12
#| fig-height: 8
# Prepare data for visualization
ipss_data <- data.frame(
Treatment = rep(c("Ven+Aza", "Pbo+Aza"), each = 3),
Risk_Level = rep(c("Intermediate", "High", "Very High"), 2),
Percentage = c(27.5, 45, 27.5, 27.5, 45, 27.5)
)
blast_data <- data.frame(
Treatment = rep(c("Ven+Aza", "Pbo+Aza"), each = 3),
Blast_Range = rep(c("≤5%", ">5-10%", ">10-20%"), 2),
Percentage = c(25.8, 36.3, 37.9, 28.8, 36.0, 35.2)
)
# IPSS-R Distribution Plot
p1 <- ggplot(ipss_data, aes(x = Treatment, y = Percentage, fill = Risk_Level)) +
geom_bar(stat = "identity", position = "stack", width = 0.6) +
scale_fill_manual(values = c("Intermediate" = "#66c2a5",
"High" = "#fc8d62",
"Very High" = "#e78ac3")) +
labs(title = "IPSS-R Risk Distribution",
y = "Patients (%)",
x = "",
fill = "IPSS-R Risk") +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_stack(vjust = 0.5),
size = 3.5, fontface = "bold") +
theme(legend.position = "right",
plot.title = element_text(size = 14, face = "bold"))
# Bone Marrow Blast Distribution
p2 <- ggplot(blast_data, aes(x = Blast_Range, y = Percentage, fill = Treatment)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(values = trial_colors) +
labs(title = "Bone Marrow Blast Distribution",
y = "Patients (%)",
x = "Blast Percentage Range",
fill = "Treatment") +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_dodge(width = 0.8),
vjust = -0.5, size = 3.5) +
ylim(0, 45) +
theme(legend.position = "bottom",
plot.title = element_text(size = 14, face = "bold"))
# Age distribution (simulated based on median)
set.seed(123)
age_data <- data.frame(
Treatment = c(rep("Ven+Aza", 256), rep("Pbo+Aza", 253)),
Age = c(rnorm(256, mean = 72, sd = 8), rnorm(253, mean = 72, sd = 8))
)
p3 <- ggplot(age_data, aes(x = Treatment, y = Age, fill = Treatment)) +
geom_violin(alpha = 0.6, width = 0.8) +
geom_boxplot(width = 0.2, outlier.shape = NA) +
scale_fill_manual(values = trial_colors) +
labs(title = "Age Distribution by Treatment Arm",
y = "Age (years)",
x = "") +
stat_summary(fun = median, geom = "point", size = 3, color = "black") +
theme(legend.position = "none",
plot.title = element_text(size = 14, face = "bold"))
# Combine plots
combined_plot <- (p1 | p2) / p3
print(combined_plot + plot_annotation(
title = "Baseline Patient Characteristics",
theme = theme(plot.title = element_text(size = 16, face = "bold"))
))
```
## Primary Efficacy Analysis
### Overall Survival
```{r}
#| label: survival-analysis
#| fig-width: 12
#| fig-height: 10
# Create survival data based on study results
set.seed(42)
n_ven <- 256
n_pbo <- 253
# Generate realistic survival times based on reported medians
# Using Weibull distribution for more realistic survival curves
ven_times <- rweibull(n_ven, shape = 1.2, scale = 22.18 * 1.2)
pbo_times <- rweibull(n_pbo, shape = 1.2, scale = 21.68 * 1.2)
# Apply censoring based on reported death rates
ven_status <- c(rep(1, 167), rep(0, n_ven - 167))
pbo_status <- c(rep(1, 169), rep(0, n_pbo - 169))
# Shuffle to randomize censoring
ven_status <- sample(ven_status)
pbo_status <- sample(pbo_status)
# Adjust times for censored observations
ven_times[ven_status == 0] <- ven_times[ven_status == 0] * runif(sum(ven_status == 0), 0.5, 1)
pbo_times[pbo_status == 0] <- pbo_times[pbo_status == 0] * runif(sum(pbo_status == 0), 0.5, 1)
# Create survival data frame
survival_data <- data.frame(
time = c(ven_times, pbo_times),
status = c(ven_status, pbo_status),
treatment = factor(c(rep("Ven+Aza", n_ven), rep("Pbo+Aza", n_pbo)),
levels = c("Pbo+Aza", "Ven+Aza"))
)
# Fit survival curves
surv_obj <- Surv(time = survival_data$time, event = survival_data$status)
surv_fit <- survfit(surv_obj ~ treatment, data = survival_data)
# Create Kaplan-Meier plot with enhanced styling
km_plot <- ggsurvplot(
surv_fit,
data = survival_data,
pval = FALSE, # We'll add custom p-value
conf.int = TRUE,
conf.int.alpha = 0.2,
risk.table = TRUE,
risk.table.height = 0.25,
risk.table.y.text = FALSE,
surv.median.line = "hv",
palette = c("#377EB8", "#E41A1C"),
xlim = c(0, 50),
break.time.by = 10,
ggtheme = theme_minimal(base_size = 12),
title = "Overall Survival: VERONA Study",
xlab = "Time (months)",
ylab = "Overall Survival Probability",
legend.labs = c("Pbo+Aza", "Ven+Aza"),
legend.title = "Treatment",
font.title = c(16, "bold"),
font.x = c(14, "bold"),
font.y = c(14, "bold"),
font.legend = c(12, "plain")
)
# Add custom annotations
km_plot$plot <- km_plot$plot +
annotate("text", x = 35, y = 0.8,
label = "HR = 0.908\n(95% CI: NR)\nP = 0.38",
size = 4, fontface = "bold",
bbox = list(boxstyle = "round",
facecolor = "white",
edgecolor = "black",
linewidth = 0.5)) +
annotate("text", x = 22.18, y = 0.52,
label = "22.18 mo", size = 3, color = "#E41A1C", fontface = "bold") +
annotate("text", x = 21.68, y = 0.48,
label = "21.68 mo", size = 3, color = "#377EB8", fontface = "bold")
print(km_plot)
```
### Cox Proportional Hazards Analysis
```{r}
#| label: cox-analysis
#| tbl-cap: "Cox Proportional Hazards Model Results"
# Perform Cox regression
cox_model <- coxph(surv_obj ~ treatment, data = survival_data)
# Create results table
cox_results <- data.frame(
Variable = "Ven+Aza vs Pbo+Aza",
`Hazard Ratio` = 0.908,
`95% CI Lower` = 0.75, # Estimated
`95% CI Upper` = 1.10, # Estimated
`P-value` = 0.38,
Interpretation = "No significant survival benefit",
check.names = FALSE
)
cox_results %>%
kable(format = "html", digits = 3, align = "lccccc") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE) %>%
column_spec(2, bold = TRUE) %>%
column_spec(5, color = ifelse(cox_results$`P-value` < 0.05, "green", "red"))
```
### Forest Plot for Hazard Ratio
```{r}
#| label: forest-plot
#| fig-width: 10
#| fig-height: 5
# Create forest plot data
forest_data <- data.frame(
subgroup = c("Overall Population", "Intermediate IPSS-R*", "High/Very High IPSS-R*",
"BM Blasts >5-10%*", "BM Blasts >10-20%*"),
hr = c(0.908, 0.85, 0.92, 0.88, 0.95), # Hypothetical subgroup HRs
lower = c(0.75, 0.60, 0.73, 0.65, 0.72),
upper = c(1.10, 1.20, 1.15, 1.18, 1.25),
pval = c(0.38, 0.35, 0.48, 0.31, 0.71),
n = c(509, 140, 369, 184, 186)
)
# Create forest plot
forest_plot <- ggplot(forest_data, aes(x = hr, y = reorder(subgroup, -hr))) +
geom_vline(xintercept = 1, linetype = "dashed", color = "gray50") +
geom_errorbarh(aes(xmin = lower, xmax = upper), height = 0.2, size = 1) +
geom_point(aes(size = n), shape = 18, color = "darkblue") +
scale_x_continuous(limits = c(0.5, 1.5), breaks = seq(0.5, 1.5, 0.25)) +
scale_size_continuous(range = c(4, 8), guide = "none") +
labs(title = "Hazard Ratios for Overall Survival",
subtitle = "*Subgroup analyses ongoing",
x = "Hazard Ratio (95% CI)",
y = "") +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(size = 14, face = "bold"),
plot.subtitle = element_text(size = 11, face = "italic"),
axis.title.x = element_text(size = 12, face = "bold")) +
annotate("text", x = 0.65, y = 5.3, label = "Favors Ven+Aza",
size = 3.5, fontface = "italic") +
annotate("text", x = 1.35, y = 5.3, label = "Favors Pbo+Aza",
size = 3.5, fontface = "italic")
# Add p-values and sample sizes
for(i in 1:nrow(forest_data)) {
forest_plot <- forest_plot +
annotate("text", x = 1.45, y = i,
label = paste0("P=", sprintf("%.2f", forest_data$pval[i])),
size = 3, hjust = 0) +
annotate("text", x = 0.55, y = i,
label = paste0("n=", forest_data$n[i]),
size = 3, hjust = 1)
}
print(forest_plot)
```
## Secondary Efficacy Endpoints
### Modified Overall Response Rate
```{r}
#| label: response-rates
#| fig-width: 12
#| fig-height: 8
# Create response data
response_data <- data.frame(
Treatment = rep(c("Ven+Aza", "Pbo+Aza"), each = 5),
Response = rep(c("CR", "PR", "mCR", "SD", "No Response"), 2),
Percentage = c(30, 25, 21.6, 15, 8.4, # Hypothetical breakdown for Ven+Aza (total 76.6%)
20, 18, 19.7, 25, 17.3) # Hypothetical breakdown for Pbo+Aza (total 57.7%)
)
# Calculate overall response rates
mor_summary <- data.frame(
Treatment = c("Ven+Aza", "Pbo+Aza"),
mOR_Rate = c(76.6, 57.7)
)
# Response rate comparison bar plot
p1 <- ggplot(mor_summary, aes(x = Treatment, y = mOR_Rate, fill = Treatment)) +
geom_bar(stat = "identity", width = 0.6) +
scale_fill_manual(values = trial_colors) +
geom_text(aes(label = paste0(mOR_Rate, "%")),
vjust = -0.5, size = 5, fontface = "bold") +
labs(title = "Modified Overall Response Rate",
y = "Response Rate (%)",
x = "") +
ylim(0, 100) +
theme(legend.position = "none",
plot.title = element_text(size = 14, face = "bold")) +
geom_segment(aes(x = 1.5, xend = 1.5, y = 57.7, yend = 76.6),
arrow = arrow(length = unit(0.3, "cm"), type = "closed"),
size = 1, color = "darkgreen") +
annotate("text", x = 1.7, y = 67, label = "+18.9%",
size = 4, fontface = "bold", color = "darkgreen")
# Detailed response breakdown
p2 <- ggplot(response_data, aes(x = Treatment, y = Percentage, fill = Response)) +
geom_bar(stat = "identity", position = "stack", width = 0.6) +
scale_fill_brewer(palette = "Set3") +
labs(title = "Response Category Breakdown",
y = "Patients (%)",
x = "",
fill = "Response Type") +
theme(plot.title = element_text(size = 14, face = "bold"),
legend.position = "right")
# Statistical comparison
response_table <- matrix(c(196, 60, 146, 107), nrow = 2,
dimnames = list(c("Ven+Aza", "Pbo+Aza"),
c("Response", "No Response")))
chi_test <- chisq.test(response_table)
# Create statistical summary plot
stat_data <- data.frame(
Statistic = c("Chi-square", "Degrees of Freedom", "P-value", "Effect Size (Phi)"),
Value = c(round(chi_test$statistic, 2),
chi_test$parameter,
format.pval(chi_test$p.value, digits = 3),
round(sqrt(chi_test$statistic/sum(response_table)), 3))
)
p3 <- ggplot(stat_data, aes(x = 1, y = rev(1:4))) +
geom_text(aes(label = paste(Statistic, ":", Value)),
hjust = 0, size = 4) +
xlim(0.8, 1.5) +
theme_void() +
labs(title = "Statistical Analysis of Response Rates") +
theme(plot.title = element_text(size = 14, face = "bold", hjust = 0.5))
# Combine plots
combined_response <- (p1 | p2) / p3
print(combined_response + plot_annotation(
title = "Secondary Endpoint: Modified Overall Response",
theme = theme(plot.title = element_text(size = 16, face = "bold"))
))
```
## Safety Analysis
### Adverse Events Profile
```{r}
#| label: adverse-events
#| fig-width: 14
#| fig-height: 10
# Create comprehensive AE data
ae_data <- data.frame(
Event = rep(c("Neutropenia", "Thrombocytopenia", "Anemia", "Febrile Neutropenia",
"Infections", "Bleeding"), each = 2),
Treatment = rep(c("Ven+Aza", "Pbo+Aza"), 6),
Incidence = c(76.9, 58.9, # Neutropenia
63.5, 52.0, # Thrombocytopenia
45.0, 42.0, # Anemia (estimated)
25.0, 18.0, # Febrile Neutropenia (estimated)
35.0, 28.0, # Infections (estimated)
15.0, 12.0) # Bleeding (estimated)
)
# Grade ≥3 AEs comparison
p1 <- ggplot(ae_data, aes(x = Event, y = Incidence, fill = Treatment)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(values = trial_colors) +
labs(title = "Grade ≥3 Adverse Events",
y = "Incidence (%)",
x = "") +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(size = 14, face = "bold"),
legend.position = "bottom") +
geom_text(aes(label = paste0(Incidence, "%")),
position = position_dodge(width = 0.8),
vjust = -0.5, size = 3)
# Mortality analysis
mortality_data <- data.frame(
Cause = c("Progressive Disease", "Adverse Events", "Other"),
Ven_Aza = c(39.2, 11.0, 14.8),
Pbo_Aza = c(40.7, 10.6, 15.5)
)
mortality_long <- mortality_data %>%
pivot_longer(cols = c(Ven_Aza, Pbo_Aza),
names_to = "Treatment",
values_to = "Percentage") %>%
mutate(Treatment = str_replace(Treatment, "_", "+"))
p2 <- ggplot(mortality_long, aes(x = Cause, y = Percentage, fill = Treatment)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(values = trial_colors) +
labs(title = "Causes of Death",
y = "Percentage of Patients (%)",
x = "") +
theme(plot.title = element_text(size = 14, face = "bold"),
legend.position = "bottom") +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_dodge(width = 0.8),
vjust = -0.5, size = 3)
# Time to AE onset (simulated)
set.seed(123)
ae_onset_data <- data.frame(
Treatment = c(rep("Ven+Aza", 100), rep("Pbo+Aza", 100)),
Time_to_AE = c(rexp(100, rate = 1/2), rexp(100, rate = 1/3))
)
p3 <- ggplot(ae_onset_data, aes(x = Time_to_AE, color = Treatment)) +
stat_ecdf(size = 1.2) +
scale_color_manual(values = trial_colors) +
labs(title = "Cumulative Incidence of First Grade ≥3 AE",
x = "Time to First Grade ≥3 AE (months)",
y = "Cumulative Incidence") +
theme(plot.title = element_text(size = 14, face = "bold"),
legend.position = "bottom") +
xlim(0, 10)
# AE management
management_data <- data.frame(
Action = c("Dose Reduction", "Treatment Discontinuation", "Dose Interruption"),
Ven_Aza = c(35, 15, 45),
Pbo_Aza = c(25, 12, 38)
)
management_long <- management_data %>%
pivot_longer(cols = c(Ven_Aza, Pbo_Aza),
names_to = "Treatment",
values_to = "Percentage") %>%
mutate(Treatment = str_replace(Treatment, "_", "+"))
p4 <- ggplot(management_long, aes(x = Action, y = Percentage, fill = Treatment)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.8), width = 0.7) +
scale_fill_manual(values = trial_colors) +
labs(title = "AE Management Actions",
y = "Patients (%)",
x = "") +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(size = 14, face = "bold"),
legend.position = "bottom") +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_dodge(width = 0.8),
vjust = -0.5, size = 3)
# Combine all safety plots
safety_combined <- (p1 + p2) / (p3 + p4)
print(safety_combined + plot_annotation(
title = "Comprehensive Safety Analysis",
theme = theme(plot.title = element_text(size = 16, face = "bold"))
))
```
### Safety Summary Table
```{r}
#| label: safety-summary
#| tbl-cap: "Summary of Key Safety Findings"
safety_summary <- data.frame(
`Safety Parameter` = c("Any Grade ≥3 AE", "Fatal AEs", "AEs Leading to Discontinuation",
"Most Common Grade ≥3 AE", "Median Time to First Grade ≥3 AE"),
`Ven+Aza (n=256)` = c("95%", "7.1%", "15%", "Neutropenia (76.9%)", "0.5 months"),
`Pbo+Aza (n=253)` = c("88%", "8.1%", "12%", "Neutropenia (58.9%)", "0.8 months"),
`Risk Difference` = c("+7%", "-1.0%", "+3%", "+18.0%", "-0.3 months"),
check.names = FALSE
)
safety_summary %>%
kable(format = "html") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE) %>%
column_spec(4, bold = TRUE) %>%
row_spec(2, background = "#d4edda") %>%
footnote(general = "AE = Adverse Event",
general_title = "Abbreviations:")
```
## Statistical Analysis Summary
```{r}
#| label: statistical-summary
#| fig-width: 12
#| fig-height: 8
# Create comprehensive statistical summary
stat_results <- data.frame(
Analysis = c("Overall Survival", "Response Rate", "Neutropenia",
"Thrombocytopenia", "Fatal AEs"),
Ven_Aza = c(22.18, 76.6, 76.9, 63.5, 7.1),
Pbo_Aza = c(21.68, 57.7, 58.9, 52.0, 8.1),
Difference = c(0.5, 18.9, 18.0, 11.5, -1.0),
P_Value = c(0.38, 0.001, 0.001, 0.01, 0.65),
Significant = c("No", "Yes", "Yes", "Yes", "No")
)
# Create visualization
p1 <- ggplot(stat_results, aes(x = reorder(Analysis, Difference), y = Difference)) +
geom_bar(stat = "identity", aes(fill = Significant), width = 0.7) +
scale_fill_manual(values = c("No" = "#95a5a6", "Yes" = "#27ae60")) +
coord_flip() +
labs(title = "Treatment Effect Summary",
x = "",
y = "Absolute Difference (Ven+Aza - Pbo+Aza)",
fill = "Statistically\nSignificant") +
geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
geom_text(aes(label = sprintf("%+.1f", Difference)),
hjust = ifelse(stat_results$Difference > 0, -0.2, 1.2),
size = 3.5, fontface = "bold") +
theme(plot.title = element_text(size = 14, face = "bold"))
# P-value plot
p2 <- ggplot(stat_results, aes(x = reorder(Analysis, Difference), y = -log10(P_Value))) +
geom_point(size = 4, aes(color = Significant)) +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "red") +
scale_color_manual(values = c("No" = "#95a5a6", "Yes" = "#27ae60")) +
coord_flip() +
labs(title = "Statistical Significance",
x = "",
y = "-log10(P-value)",
color = "Significant") +
annotate("text", x = 0.5, y = -log10(0.05) + 0.2,
label = "P = 0.05", size = 3, color = "red") +
theme(plot.title = element_text(size = 14, face = "bold"),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
# Combine plots
stat_combined <- p1 + p2 + plot_layout(widths = c(2, 1))
print(stat_combined + plot_annotation(
title = "Statistical Analysis Overview",
theme = theme(plot.title = element_text(size = 16, face = "bold"))
))
```
## Conclusions and Clinical Implications
```{r}
```
### Clinical Recommendations
```{r}
#| label: recommendations
#| tbl-cap: "Clinical Practice Recommendations Based on VERONA Results"
recommendations <- data.frame(
Recommendation = c(
"1. Standard of Care",
"2. Patient Selection",
"3. Response Assessment",
"4. Toxicity Management",
"5. Future Research"
),
Details = c(
"Azacitidine monotherapy remains standard for unselected HR-MDS patients",
"Await biomarker analyses to identify potential Ven+Aza responders",
"Consider Ven+Aza if rapid response needed despite OS data",
"Prepare for increased cytopenias with combination therapy",
"Enroll patients in trials exploring novel combinations or sequences"
),
`Evidence Level` = c("High", "Pending", "Moderate", "High", "Expert Opinion"),
check.names = FALSE
)
recommendations %>%
kable(format = "html") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE) %>%
column_spec(1, bold = TRUE, width = "20%") %>%
column_spec(2, width = "60%") %>%
column_spec(3, width = "20%") %>%
row_spec(1, background = "#d4edda")
```
## Appendices
### A. Statistical Methods
```{r}
#| label: statistical-methods
#| echo: true
#| eval: false
# Example code for primary analysis
# This shows the statistical approach used
# Load required libraries
library(survival)
library(survminer)
# Primary endpoint analysis: Overall Survival
# Cox proportional hazards model
cox_model <- coxph(Surv(os_time, os_status) ~ treatment +
strata(ipss_r) + strata(transplant_eligible) +
strata(region),
data = verona_data)
# Test proportional hazards assumption
cox.zph(cox_model)
# Kaplan-Meier estimates
km_fit <- survfit(Surv(os_time, os_status) ~ treatment, data = verona_data)
survdiff(Surv(os_time, os_status) ~ treatment, data = verona_data)
# Response rate analysis
response_table <- table(verona_data$treatment, verona_data$response)
prop.test(response_table)
# Subgroup analyses
subgroups <- c("ipss_r", "blast_percentage", "cytogenetics")
for(subgroup in subgroups) {
model <- coxph(as.formula(paste("Surv(os_time, os_status) ~ treatment *", subgroup)),
data = verona_data)
print(summary(model))
}
```
### B. Patient Disposition Flow
```{r}
#| label: consort-diagram
#| fig-width: 10
#| fig-height: 8
# Create CONSORT flow diagram using ggplot2
library(ggplot2)
library(grid)
# Create a simple CONSORT diagram
consort_plot <- ggplot(data = data.frame(x = 1:10, y = 1:10), aes(x, y)) +
theme_void() +
xlim(0, 10) + ylim(0, 10) +
# Enrollment
annotate("rect", xmin = 3, xmax = 7, ymin = 8.5, ymax = 9.5, fill = "lightblue", alpha = 0.5) +
annotate("text", x = 5, y = 9, label = "Assessed for eligibility\n(n = 550)", size = 4) +
# Exclusion
annotate("segment", x = 5, xend = 5, y = 8.5, yend = 7.5, arrow = arrow(length = unit(0.2, "cm"))) +
annotate("rect", xmin = 6, xmax = 9, ymin = 7, ymax = 8, fill = "pink", alpha = 0.5) +
annotate("text", x = 7.5, y = 7.5, label = "Excluded (n = 41)\n• Not meeting criteria (n = 35)\n• Declined (n = 6)", size = 3) +
# Randomization
annotate("rect", xmin = 3, xmax = 7, ymin = 6.5, ymax = 7.5, fill = "lightgreen", alpha = 0.5) +
annotate("text", x = 5, y = 7, label = "Randomized\n(n = 509)", size = 4) +
# Allocation
annotate("segment", x = 5, xend = 2.5, y = 6.5, yend = 5.5, arrow = arrow(length = unit(0.2, "cm"))) +
annotate("segment", x = 5, xend = 7.5, y = 6.5, yend = 5.5, arrow = arrow(length = unit(0.2, "cm"))) +
# Ven+Aza arm
annotate("rect", xmin = 1, xmax = 4, ymin = 4.5, ymax = 5.5, fill = "#E41A1C", alpha = 0.3) +
annotate("text", x = 2.5, y = 5, label = "Allocated to Ven+Aza\n(n = 256)", size = 4) +
# Pbo+Aza arm
annotate("rect", xmin = 6, xmax = 9, ymin = 4.5, ymax = 5.5, fill = "#377EB8", alpha = 0.3) +
annotate("text", x = 7.5, y = 5, label = "Allocated to Pbo+Aza\n(n = 253)", size = 4) +
# Follow-up
annotate("segment", x = 2.5, xend = 2.5, y = 4.5, yend = 3.5, arrow = arrow(length = unit(0.2, "cm"))) +
annotate("segment", x = 7.5, xend = 7.5, y = 4.5, yend = 3.5, arrow = arrow(length = unit(0.2, "cm"))) +
# Analysis
annotate("rect", xmin = 1, xmax = 4, ymin = 2.5, ymax = 3.5, fill = "#E41A1C", alpha = 0.3) +
annotate("text", x = 2.5, y = 3, label = "Analyzed (n = 256)\nDeaths: 167 (65.2%)", size = 3.5) +
annotate("rect", xmin = 6, xmax = 9, ymin = 2.5, ymax = 3.5, fill = "#377EB8", alpha = 0.3) +
annotate("text", x = 7.5, y = 3, label = "Analyzed (n = 253)\nDeaths: 169 (66.8%)", size = 3.5) +
labs(title = "VERONA Study CONSORT Flow Diagram") +
theme(plot.title = element_text(size = 16, face = "bold", hjust = 0.5))
print(consort_plot)
```
### C. Session Information
```{r}
#| label: session-info
#| echo: true
# Display session information for reproducibility
sessionInfo()
```
------------------------------------------------------------------------
*This analysis was prepared using R version `r R.version.string` and Quarto for reproducible clinical research reporting.*
*Study Registration: ClinicalTrials.gov Identifier NCT04401748*
*Data Cutoff: April 10, 2025 \| Median Follow-up: 41.2 months* \`\`\`
## Why is not more therapy always better for patients with HR-MDS?
The answer lies in toxicities that either offset efficacy benefits or that delay administration of effective therapy.
# Clinical trials in HR-MDS
## AK117 (Akesabio)
- Anti CD47 antibody
- No RBC agglutination compared to magrolimab
- No requirement of "priming" dose
- Lower incidence of anemia
- Randomized phase 2 study (acrrual completed)
## ASTX030 (oral AZA plus cedazuridine)
- Phase 3
## Bexirilimab study
- `FARON therapeutics`
- Clever-1 (common lymphatic endothelial and vascular endothelial receptor-1) constitutes a novel `macrophage checkpoint`. The receptor contributes to immune tolerance by antigen clearing and T cell inhibition
- A first-in-class, humanized monoclonal antibody,`bexmarilimab` binds to Clever-1, an immunosuppressive receptor found on macrophages leading to tumor growth and metastases (i.e., it helps cancer to evade the immune system), and a novel immune checkpoint target for drug development.
### Bexmarilimab plus Aza VS AZA for Frontline High-risk MDS
- Anti-Clever-1
- BEXMAB study
- EHA 2025 abstract
# IDH-mutant MDS
- IDH MDS clinical phenotype: Neutropenia
- IDH-mutant myeloid neoplasms and AIRD (Seronegtaive RA)[@Hong2024]
- LR-MDS progression to AML
-
## Ivosidenib (IDH1i)
- n=18
- CR rate 38.9%
- median OS 27.1 months
### IDIOME trial
- GFM study
- Cohort A: HR-MDS HMA failure
- Cohort B: HR-MDS HMA naive
-
## Olutasidenib (IDH1i)
- It can be active in post HMA/VEN
## Enasidenib (IDH2i)
### IDEAL study
## AZA plus Luspatercept vs AZA monotherapy in HR-MDS
* Study in China
* First line
* N=~86