TLG Catalog - Stable
  • Stable
    • Dev
  1. Graphs
  2. Efficacy
  3. MMRMG02
  • Introduction

  • Tables
    • ADA
      • ADAT01
      • ADAT02
      • ADAT03
      • ADAT04A
      • ADAT04B
    • Adverse Events
      • AET01
      • AET01_AESI
      • AET02
      • AET02_SMQ
      • AET03
      • AET04
      • AET04_PI
      • AET05
      • AET05_ALL
      • AET06
      • AET06_SMQ
      • AET07
      • AET09
      • AET09_SMQ
      • AET10
    • Concomitant Medications
      • CMT01
      • CMT01A
      • CMT01B
      • CMT02_PT
    • Deaths
      • DTHT01
    • Demography
      • DMT01
    • Disclosures
      • DISCLOSUREST01
      • EUDRAT01
      • EUDRAT02
    • Disposition
      • DST01
      • PDT01
      • PDT02
    • ECG
      • EGT01
      • EGT02
      • EGT03
      • EGT04
      • EGT05_QTCAT
    • Efficacy
      • AOVT01
      • AOVT02
      • AOVT03
      • CFBT01
      • CMHT01
      • COXT01
      • COXT02
      • DORT01
      • LGRT02
      • MMRMT01
      • ONCT05
      • RATET01
      • RBMIT01
      • RSPT01
      • TTET01
    • Exposure
      • EXT01
    • Lab Results
      • LBT01
      • LBT02
      • LBT03
      • LBT04
      • LBT05
      • LBT06
      • LBT07
      • LBT08
      • LBT09
      • LBT10
      • LBT10_BL
      • LBT11
      • LBT11_BL
      • LBT12
      • LBT12_BL
      • LBT13
      • LBT14
      • LBT15
    • Medical History
      • MHT01
    • Pharmacokinetic
      • PKCT01
      • PKPT02
      • PKPT03
      • PKPT04
      • PKPT05
      • PKPT06
      • PKPT07
      • PKPT08
      • PKPT11
    • Risk Management Plan
      • RMPT01
      • RMPT03
      • RMPT04
      • RMPT05
      • RMPT06
    • Safety
      • ENTXX
    • Vital Signs
      • VST01
      • VST02
  • Listings
    • ADA
      • ADAL02
    • Adverse Events
      • AEL01
      • AEL01_NOLLT
      • AEL02
      • AEL02_ED
      • AEL03
      • AEL04
    • Concomitant Medications
      • CML01
      • CML02A_GL
      • CML02B_GL
    • Development Safety Update Report
      • DSUR4
    • Disposition
      • DSL01
      • DSL02
    • ECG
      • EGL01
    • Efficacy
      • ONCL01
    • Exposure
      • EXL01
    • Lab Results
      • LBL01
      • LBL01_RLS
      • LBL02A
      • LBL02A_RLS
      • LBL02B
    • Medical History
      • MHL01
    • Pharmacokinetic
      • ADAL01
      • PKCL01
      • PKCL02
      • PKPL01
      • PKPL02
      • PKPL04
    • Vital Signs
      • VSL01
  • Graphs
    • Efficacy
      • FSTG01
      • FSTG02
      • KMG01
      • MMRMG01
      • MMRMG02
    • Other
      • BRG01
      • BWG01
      • CIG01
      • IPPG01
      • LTG01
      • MNG01
    • Pharmacokinetic
      • PKCG01
      • PKCG02
      • PKCG03
      • PKPG01
      • PKPG02
      • PKPG03
      • PKPG04
      • PKPG06

  • Appendix
    • Reproducibility

  • Index

On this page

  • Reproducibility
    • Timestamp
    • Session Info
    • .lock file
  • Edit this page
  • Report an issue
  1. Graphs
  2. Efficacy
  3. MMRMG02

MMRMG02

Forest Plot for Mixed-Effect Model Repeated Measures


  • Comparing Multiple Populations
  • Data Setup

For the following part, an MMRM model is fitted for the dataset and from this result forest plots are constructed for each set of subgroups, treatment arm, and visit that is of interest.

First an MMRM model is fitted for the whole dataset.

Code
mmrm_results <- fit_mmrm(
  data = adqs_f_with_groups,
  vars = list(
    response = "AVAL",
    covariates = c(),
    id = "USUBJID",
    arm = "ARMCD",
    visit = "AVISIT"
  ),
  cor_struct = "unstructured",
  weights_emmeans = "equal",
  parallel = TRUE
)
mmrm() registered as emmeans extension

Applying the tern.mmrm::extract_mmrm_subgroups function prepares the obtained mmrm_results for a specific visit - in this case we use the SCREENING visit - and treatment arm relative to the reference arm. From these results a table is obtained using the tern.mmrm::tabulate_mmrm_subgroups function from which the graphic can be directly obtained with tern::g_forest.

Here we compare ARM A with the reference arm, ARM B.

Code
df_a <- extract_mmrm_subgroups(
  fit = mmrm_results,
  visit = "SCREENING",
  subgroups = c("group", "SEX"),
  treatment_arm = "ARM A"
)

tab_a <- basic_table() %>%
  tabulate_mmrm_subgroups(
    df = df_a,
    vars = c("n_tot", "diff", "ci", "pval")
  )

plot <- g_forest(
  tab_a,
  logx = FALSE,
  xlim = c(-5, 2.5),
  x_at = c(-5, -2.5, 0, 2.5),
  vline = 0
)
plot

Then we compare ARM C with ARM B.

Code
df_c <- extract_mmrm_subgroups(
  fit = mmrm_results,
  visit = "SCREENING",
  subgroups = c("group", "SEX"),
  treatment_arm = "ARM C"
)

tab_c <- basic_table() %>%
  tabulate_mmrm_subgroups(
    df = df_c,
    vars = c("n_tot", "diff", "ci", "pval")
  )

plot <- g_forest(
  tab_c,
  logx = FALSE,
  xlim = c(-5, 2.5),
  x_at = c(-5, -2.5, 0, 2.5),
  vline = 0
)
plot

Code
library(dplyr)
library(tern.mmrm)
library(nestcolor)

adsl <- random.cdisc.data::cadsl
adqs <- random.cdisc.data::cadqs

adqs_f <- adqs %>%
  dplyr::filter(PARAMCD == "FKSI-FWB" & !AVISIT %in% c("BASELINE")) %>%
  droplevels() %>%
  dplyr::mutate(ARMCD = factor(ARMCD, levels = c("ARM B", "ARM A", "ARM C"))) %>%
  dplyr::mutate(
    AVISITN = rank(AVISITN) %>%
      as.factor() %>%
      as.numeric() %>%
      as.factor()
  )

# Simulation of groups.
set.seed(2)
adqs_f_with_groups <- rbind(
  within(
    adqs_f[sample(seq_len(nrow(adqs_f)), size = 1 / 2 * nrow(adqs_f)), ],
    group <- "subpopulation 1"
  ),
  within(
    adqs_f,
    {
      group <- "subpopulation 2"
      AVAL <- AVAL + rnorm(length(AVAL), mean = 10, sd = 2)
      USUBJID <- paste0(USUBJID, "-S2")
    }
  )
)
adqs_f_with_groups$group <- factor(adqs_f_with_groups$group)

Reproducibility

Timestamp

[1] "2025-07-05 17:59:08 UTC"

Session Info

─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.5.0 (2025-04-11)
 os       Ubuntu 24.04.2 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Etc/UTC
 date     2025-07-05
 pandoc   3.7.0.2 @ /usr/bin/ (via rmarkdown)
 quarto   1.7.32 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package           * version  date (UTC) lib source
 backports           1.5.0    2024-05-23 [1] RSPM
 brio                1.1.5    2024-04-24 [1] RSPM
 broom               1.0.8    2025-03-28 [1] RSPM
 checkmate           2.3.2    2024-07-29 [1] RSPM
 cli                 3.6.5    2025-04-23 [1] RSPM
 coda                0.19-4.1 2024-01-31 [1] CRAN (R 4.5.0)
 codetools           0.2-20   2024-03-31 [2] CRAN (R 4.5.0)
 cowplot             1.1.3    2024-01-22 [1] RSPM
 curl                6.4.0    2025-06-22 [1] RSPM
 dichromat           2.0-0.1  2022-05-02 [1] CRAN (R 4.5.0)
 digest              0.6.37   2024-08-19 [1] RSPM
 dplyr             * 1.1.4    2023-11-17 [1] RSPM
 emmeans             1.11.1   2025-05-04 [1] RSPM
 estimability        1.5.1    2024-05-12 [1] RSPM
 evaluate            1.0.4    2025-06-18 [1] RSPM
 farver              2.1.2    2024-05-13 [1] RSPM
 fastmap             1.2.0    2024-05-15 [1] RSPM
 formatters        * 0.5.11   2025-04-09 [1] RSPM
 generics            0.1.4    2025-05-09 [1] RSPM
 ggplot2             3.5.2    2025-04-09 [1] RSPM
 glue                1.8.0    2024-09-30 [1] RSPM
 gtable              0.3.6    2024-10-25 [1] RSPM
 htmltools           0.5.8.1  2024-04-04 [1] RSPM
 htmlwidgets         1.6.4    2023-12-06 [1] RSPM
 jsonlite            2.0.0    2025-03-27 [1] RSPM
 knitr               1.50     2025-03-16 [1] RSPM
 labeling            0.4.3    2023-08-29 [1] RSPM
 lattice             0.22-7   2025-04-02 [2] CRAN (R 4.5.0)
 lifecycle           1.0.4    2023-11-07 [1] RSPM
 magrittr          * 2.0.3    2022-03-30 [1] RSPM
 MASS                7.3-65   2025-02-28 [2] CRAN (R 4.5.0)
 Matrix              1.7-3    2025-03-11 [1] CRAN (R 4.5.0)
 mmrm                0.3.15   2025-06-10 [1] RSPM
 multcomp            1.4-28   2025-01-29 [1] RSPM
 mvtnorm             1.3-3    2025-01-10 [1] RSPM
 nestcolor         * 0.1.3    2025-01-21 [1] RSPM
 nlme                3.1-168  2025-03-31 [2] CRAN (R 4.5.0)
 parallelly          1.45.0   2025-06-02 [1] RSPM
 pillar              1.11.0   2025-07-04 [1] RSPM
 pkgcache            2.2.4    2025-05-26 [1] RSPM
 pkgconfig           2.0.3    2019-09-22 [1] RSPM
 processx            3.8.6    2025-02-21 [1] RSPM
 ps                  1.9.1    2025-04-12 [1] RSPM
 purrr               1.0.4    2025-02-05 [1] RSPM
 R6                  2.6.1    2025-02-15 [1] RSPM
 random.cdisc.data   0.3.16   2024-10-10 [1] RSPM
 rbibutils           2.3      2024-10-04 [1] RSPM
 RColorBrewer        1.1-3    2022-04-03 [1] RSPM
 Rcpp                1.1.0    2025-07-02 [1] RSPM
 Rdpack              2.6.4    2025-04-09 [1] RSPM
 rlang               1.1.6    2025-04-11 [1] RSPM
 rmarkdown           2.29     2024-11-04 [1] RSPM
 rtables           * 0.6.13   2025-06-19 [1] RSPM
 sandwich            3.1-1    2024-09-15 [1] RSPM
 scales              1.4.0    2025-04-24 [1] RSPM
 sessioninfo         1.2.3    2025-02-05 [1] any (@1.2.3)
 stringi             1.8.7    2025-03-27 [1] RSPM
 stringr             1.5.1    2023-11-14 [1] RSPM
 survival            3.8-3    2024-12-17 [2] CRAN (R 4.5.0)
 tern              * 0.9.9    2025-06-20 [1] RSPM
 tern.mmrm         * 0.3.3    2025-07-04 [1] RSPM
 testthat            3.2.3    2025-01-13 [1] RSPM
 TH.data             1.1-3    2025-01-17 [1] RSPM
 tibble              3.3.0    2025-06-08 [1] RSPM
 tidyr               1.3.1    2024-01-24 [1] RSPM
 tidyselect          1.2.1    2024-03-11 [1] RSPM
 TMB                 1.9.17   2025-03-10 [1] RSPM
 vctrs               0.6.5    2023-12-01 [1] RSPM
 withr               3.0.2    2024-10-28 [1] RSPM
 xfun                0.52     2025-04-02 [1] RSPM
 xtable              1.8-4    2019-04-21 [1] RSPM
 yaml                2.3.10   2024-07-26 [1] RSPM
 zoo                 1.8-14   2025-04-10 [1] RSPM

 [1] /usr/local/lib/R/site-library
 [2] /usr/local/lib/R/library
 [3] /github/home/R/x86_64-pc-linux-gnu-library/4.5
 * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────

.lock file

Download the .lock file and use renv::restore() on it to recreate environment used to generate this website.

Download

MMRMG01
BRG01
Source Code
---
title: MMRMG02
subtitle: Forest Plot for Mixed-Effect Model Repeated Measures
---

------------------------------------------------------------------------

{{< include ../../_utils/envir_hook.qmd >}}

```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
library(dplyr)
library(tern.mmrm)
library(nestcolor)

adsl <- random.cdisc.data::cadsl
adqs <- random.cdisc.data::cadqs

adqs_f <- adqs %>%
  dplyr::filter(PARAMCD == "FKSI-FWB" & !AVISIT %in% c("BASELINE")) %>%
  droplevels() %>%
  dplyr::mutate(ARMCD = factor(ARMCD, levels = c("ARM B", "ARM A", "ARM C"))) %>%
  dplyr::mutate(
    AVISITN = rank(AVISITN) %>%
      as.factor() %>%
      as.numeric() %>%
      as.factor()
  )

# Simulation of groups.
set.seed(2)
adqs_f_with_groups <- rbind(
  within(
    adqs_f[sample(seq_len(nrow(adqs_f)), size = 1 / 2 * nrow(adqs_f)), ],
    group <- "subpopulation 1"
  ),
  within(
    adqs_f,
    {
      group <- "subpopulation 2"
      AVAL <- AVAL + rnorm(length(AVAL), mean = 10, sd = 2)
      USUBJID <- paste0(USUBJID, "-S2")
    }
  )
)
adqs_f_with_groups$group <- factor(adqs_f_with_groups$group)
```

::: panel-tabset
## Comparing Multiple Populations

For the following part, an MMRM model is fitted for the dataset and from this result forest plots are constructed for each set of subgroups, treatment arm, and visit that is of interest.

First an MMRM model is fitted for the whole dataset.

```{r mmrm_results}
#| code-fold: show

mmrm_results <- fit_mmrm(
  data = adqs_f_with_groups,
  vars = list(
    response = "AVAL",
    covariates = c(),
    id = "USUBJID",
    arm = "ARMCD",
    visit = "AVISIT"
  ),
  cor_struct = "unstructured",
  weights_emmeans = "equal",
  parallel = TRUE
)
```

Applying the `tern.mmrm::extract_mmrm_subgroups` function prepares the obtained `mmrm_results` for a specific visit - in this case we use the `SCREENING` visit - and treatment arm relative to the reference arm. From these results a table is obtained using the `tern.mmrm::tabulate_mmrm_subgroups` function from which the graphic can be directly obtained with `tern::g_forest`.

Here we compare `ARM A` with the reference arm, `ARM B`.

```{r plot1, test = list(plot_v1 = "plot"), fig.width = 15, fig.height = 4}
df_a <- extract_mmrm_subgroups(
  fit = mmrm_results,
  visit = "SCREENING",
  subgroups = c("group", "SEX"),
  treatment_arm = "ARM A"
)

tab_a <- basic_table() %>%
  tabulate_mmrm_subgroups(
    df = df_a,
    vars = c("n_tot", "diff", "ci", "pval")
  )

plot <- g_forest(
  tab_a,
  logx = FALSE,
  xlim = c(-5, 2.5),
  x_at = c(-5, -2.5, 0, 2.5),
  vline = 0
)
plot
```

Then we compare `ARM C` with `ARM B`.

```{r plot2, test = list(plot_v2 = "plot"), fig.width = 15, fig.height = 4}
df_c <- extract_mmrm_subgroups(
  fit = mmrm_results,
  visit = "SCREENING",
  subgroups = c("group", "SEX"),
  treatment_arm = "ARM C"
)

tab_c <- basic_table() %>%
  tabulate_mmrm_subgroups(
    df = df_c,
    vars = c("n_tot", "diff", "ci", "pval")
  )

plot <- g_forest(
  tab_c,
  logx = FALSE,
  xlim = c(-5, 2.5),
  x_at = c(-5, -2.5, 0, 2.5),
  vline = 0
)
plot
```

```{r test parameters, test = list(width = "width", width = "width"), echo = FALSE}
width <- 15
height <- 4
```

## Data Setup

```{r setup}
#| code-fold: show
```
:::

{{< include ../../_utils/save_results.qmd >}}

{{< include ../../repro.qmd >}}

Made with ❤️ by the NEST Team

  • Edit this page
  • Report an issue
Cookie Preferences