TL Catalog
  1. Tables
  2. Electrocardiograms
  3. TSFECG01
  • Introduction

  • Index

  • Tables
    • Adverse Events
      • TSFAE01A
      • TSFAE01B
      • TSFAE02
      • TSFAE02A
      • TSFAE03
      • TSFAE03A
      • TSFAE04
      • TSFAE04A
      • TSFAE05
      • TSFAE05A
      • TSFAE06A
      • TSFAE06B
      • TSFAE07A
      • TSFAE07B
      • TSFAE08
      • TSFAE09
      • TSFAE10
      • TSFAE11
      • TSFAE12
      • TSFAE13
      • TSFAE14
      • TSFAE15
      • TSFAE16
      • TSFAE17A
      • TSFAE17B
      • TSFAE17C
      • TSFAE17D
      • TSFAE19A
      • TSFAE19B
      • TSFAE19C
      • TSFAE19D
      • TSFAE20A
      • TSFAE20B
      • TSFAE20C
      • TSFAE21A
      • TSFAE21B
      • TSFAE21C
      • TSFAE21D
      • TSFAE22A
      • TSFAE22B
      • TSFAE22C
      • TSFAE23A
      • TSFAE23B
      • TSFAE23C
      • TSFAE23D
      • TSFAE24A
      • TSFAE24B
      • TSFAE24C
      • TSFAE24D
      • TSFAE24F
      • TSFDTH01
    • Clinical Laboratory Evaluation
      • TSFLAB01
      • TSFLAB01A
      • TSFLAB02
      • TSFLAB02A
      • TSFLAB02B
      • TSFLAB03
      • TSFLAB03A
      • TSFLAB04A
      • TSFLAB04B
      • TSFLAB05
      • TSFLAB06
      • TSFLAB07
    • Demographic
      • TSIDEM01
      • TSIDEM02
      • TSIMH01
    • Disposition of Subjects
      • TSIDS01
      • TSIDS02
      • TSIDS02A
    • Electrocardiograms
      • TSFECG01
      • TSFECG01A
      • TSFECG02
      • TSFECG03
      • TSFECG04
      • TSFECG05
    • Exposure
      • TSIEX01
      • TSIEX02
      • TSIEX03
      • TSIEX04
      • TSIEX06
      • TSIEX07
      • TSIEX08
      • TSIEX09
      • TSIEX10
      • TSIEX11
    • Pharmacokinetics
      • TPK01A
      • TPK01B
      • TPK02
      • TPK03
    • Prior and Concomitant Therapies
      • TSICM01
      • TSICM02
      • TSICM03
      • TSICM04
      • TSICM05
      • TSICM06
      • TSICM07
      • TSICM08
    • Vital Signs and Physical Findings
      • TSFVIT01
      • TSFVIT01A
      • TSFVIT02
      • TSFVIT03
      • TSFVIT04
      • TSFVIT05
      • TSFVIT06
  • Listings
    • Adverse Events
      • LSFAE01
      • LSFAE02
      • LSFAE03
      • LSFAE04
      • LSFAE05
      • LSFAE06A
      • LSFAE06B
      • LSFDTH01
    • Clinical Laboratory Evaluation
      • LSFLAB01
    • Demographic
      • LSIDEM01
      • LSIDEM02
      • LSIMH01
    • Disposition of Subjects
      • LSIDS01
      • LSIDS02
      • LSIDS03
      • LSIDS04
      • LSIDS05
    • Electrocardiograms
      • LSFECG01
      • LSFECG02
    • Exposure
      • LSIEX01
      • LSIEX02
      • LSIEX03
    • Prior and Concomitant Therapies
      • LSICM01
    • Vital Signs and Physical Findings
      • LSFVIT01
      • LSFVIT02

  • Reproducibility

  • Changelog

On this page

  • Output
  • Edit this page
  • Report an issue
  1. Tables
  2. Electrocardiograms
  3. TSFECG01

TSFECG01

Mean Change From Baseline for ECG Data Over Time


Output

  • Preview
Code
# Program Name:              tsfecg01

# Prep Environment

library(envsetup)
library(tern)
library(dplyr)
library(rtables)
library(junco)

# Define script level parameters:

tblid <- "TSFECG01"
fileid <- tblid
titles <- get_titles_from_file(input_path = '../../_data/', tblid)
string_map <- default_str_map

popfl <- "SAFFL"
trtvar <- "TRT01A"
ctrl_grp <- "Placebo"

# Note on ancova parameter
# when ancova = TRUE
# ancova model will be used to calculate all mean/mean change columns
# not just those from the Difference column
# model specification
summ_vars <- list(arm = trtvar, covariates = NULL)

# when ancova = FALSE, all mean/mean change columns will be from descriptive stats
# for the difference column descriptive stats will be based upon two-sample t-test
ancova <- FALSE

comp_btw_group <- TRUE

selparamcd <- c("EGHRMN", "PRAG", "QRSAG", "QTC", "QTCBAG", "QTCFAG", "RRAG")
# see further, an alternative method to identify all non-unscheduled visits based upon data
selvisit <- c(
  "Baseline",
  "Month 1",
  "Month 3",
  "Month 6",
  "Month 9",
  "Month 12",
  "Month 15",
  "Month 18",
  "Month 24"
)

# Process Data:

adsl <- pharmaverseadamjnj::adsl %>%
  filter(.data[[popfl]] == "Y") %>%
  select(
    STUDYID,
    USUBJID,
    all_of(c(popfl, trtvar)),
    SEX,
    AGEGR1,
    RACE,
    ETHNIC,
    AGE
  )

adsl$colspan_trt <- factor(
  ifelse(adsl[[trtvar]] == ctrl_grp, " ", "Active Study Agent"),
  levels = c("Active Study Agent", " ")
)

adsl$rrisk_header <- "Difference in Mean Change (95% CI)"
adsl$rrisk_label <- paste(adsl[[trtvar]], paste("vs", ctrl_grp))


adeg00 <- pharmaverseadamjnj::adeg %>%
  select(
    USUBJID,
    AVISITN,
    AVISIT,
    PARAMCD,
    PARAM,
    AVAL,
    BASE,
    CHG,
    starts_with("ANL"),
    ABLFL,
    APOBLFL
    # ,EGSTAT
  ) %>%
  inner_join(adsl)

# selection of all non-unscheduled visits from data
visits <- adeg00 %>%
  select(AVISIT) %>%
  filter(!grepl("UNSCHEDULED", toupper(AVISIT)))

visits$AVISIT <- droplevels(visits$AVISIT)
selvisit_data <- levels(visits$AVISIT)

### if preferred to get it from data, rather than hardcoded list of visits
# selvisit <- selvisit_data

## retrieve the precision of AVAL on the input dataset
## review outcome and make updates manually if needed
## the precision variable will be used for the parameter-based formats in layout

## decimal = 4 is a cap in this derivation: if decimal precision of variable > decimal, the result will end up as decimal
## eg if AVAL has precision of 6 for parameter x, and decimal = 4, the resulting decimal value for parameter x is 4

## note that precision is on the raw values, as we are presenting mean/ci, and extra digit will be added
## eg precision = 2 will result in mean/ci format xx.xxx (xx.xxx, xx.xxx)

eg_precision <- tidytlg:::make_precision_data(
  df = adeg00,
  decimal = 4,
  precisionby = "PARAMCD",
  precisionon = "AVAL"
)


### data preparation

filtered_adeg <- adeg00 %>%
  filter(PARAMCD %in% selparamcd) %>%
  filter(AVISIT %in% selvisit) %>%
  ### unique record per timepoint:
  filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y"))

## issue with sysntethic data for Xanomeline Low Dose : 600 records rather than 300
check1 <- filtered_adeg %>%
  group_by(TRT01A, PARAM, AVISIT) %>%
  summarize(n_rec = n(), n_sub = n_distinct(USUBJID))


#### perform check on unique record per subject/param/timepoint
check_unique <- filtered_adeg %>%
  group_by(USUBJID, PARAMCD, AVISIT) %>%
  mutate(n_recsub = n()) %>%
  filter(n_recsub > 1)

if (nrow(check_unique) > 0) {
  stop(
    "Your input dataset needs extra attention, as some subjects have more than one record per parameter/visit"
  )
  ### you will run into issues with fraction portion in count_denom_fraction, as count > denom, and fraction > 1 if you don't adjust your input dataset

  # Possible extra derivation - just to ensure program can run without issues
  ### Study team is responsible for adding this derivation onto ADaM dataset and ensure proper derivation rule for ANL02FL is implemented !!!!!!!!!!
  filtered_adegx <- adeg00 %>%
    filter(PARAMCD %in% selparamcd) %>%
    filter(AVISIT %in% selvisit) %>%
    ### unique record per timepoint:
    filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y")) %>%
    group_by(USUBJID, PARAM, AVISIT) %>%
    mutate(n_sub = n()) %>%
    arrange(USUBJID, PARAM, AVISIT, ADT) %>%
    mutate(i = vctrs::vec_group_id(ADT)) %>%
    mutate(
      ANL02FL = case_when(
        n_sub == 1 ~ "Y",
        i == 1 ~ "Y"
      )
    ) %>%
    select(-c(i, n_sub)) %>%
    ungroup()

  filtered_adeg <- filtered_adegx %>%
    filter(PARAMCD %in% selparamcd) %>%
    filter(AVISIT %in% selvisit) %>%
    ### unique record per timepoint:
    filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y"))

  ## now your data should contain 1 record per subject per parameter
}


### for denominator per timepoint: all records from adeg on this timepoint: ignoring anl01fl/anl02fl/param
filtered_adeg_timepoints <- unique(
  adeg00 %>%
    filter(AVISIT %in% selvisit) %>%
    select(USUBJID, AVISITN, AVISIT)
) %>%
  inner_join(adsl)

params <- unique(filtered_adeg %>% select(PARAMCD, PARAM))

filtered_adeg_timepoints <- filtered_adeg_timepoints %>%
  mutate(dummy_join = 1) %>%
  full_join(
    params %>% mutate(dummy_join = 1),
    relationship = "many-to-many"
  ) %>%
  select(-dummy_join)

### identify subjects in filtered_advs_timepoints and not in filtered_advs

extra_sub <- anti_join(filtered_adeg_timepoints, filtered_adeg)

### only add these extra_sub to
### this will ensure we still meet the one record per subject per timepoint
### this will ensure length(x) can be used for the denominator derivation inside summarize_aval_chg_diff function

filtered_adeg <- bind_rows(filtered_adeg, extra_sub) %>%
  arrange(USUBJID, PARAM, AVISITN)

filtered_adeg <- filtered_adeg %>%
  inner_join(eg_precision, by = "PARAMCD")

### important: previous actions lost the label of variables
### in order to be able to use obj_label(filtered_advs$PARAM) in layout, need to redefine the label
filtered_adeg <- var_relabel_list(filtered_adeg, var_labels(adeg00, fill = T))

check1 <- filtered_adeg %>%
  group_by(TRT01A, PARAM, AVISIT) %>%
  summarize(n_rec = n(), n_sub = n_distinct(USUBJID))

colspan_trt_map <- create_colspan_map(
  adsl,
  non_active_grp = ctrl_grp,
  non_active_grp_span_lbl = " ",
  active_grp_span_lbl = "Active Study Agent",
  colspan_var = "colspan_trt",
  trt_var = trtvar
)

# Define layout and build table:

summ_vars <- list(arm = trtvar, covariates = NULL)
ref_path <- c("colspan_trt", " ", trtvar, ctrl_grp)
multivars <- c("AVAL", "AVAL", "CHG")

extra_args_3col <- list(
  format_na_str = rep("NA", 3),
  d = "decimal",
  variables = summ_vars,
  ref_path = ref_path,
  ancova = ancova,
  comp_btw_group = comp_btw_group,
  multivars = multivars
)


lyt <- basic_table(show_colcounts = FALSE, colcount_format = "N=xx") %>%
  ### first columns
  split_cols_by(
    "colspan_trt",
    split_fun = trim_levels_to_map(map = colspan_trt_map)
  ) %>%
  split_cols_by(trtvar, show_colcounts = TRUE, colcount_format = "N=xx") %>%
  split_rows_by(
    "PARAM",
    label_pos = "topleft",
    split_label = obj_label(filtered_adeg$PARAM),
    section_div = " ",
    split_fun = drop_split_levels
  ) %>%
  ## note the child_labels = hidden for AVISIT, these labels will be taken care off by
  ## applying function summarize_aval_chg_diff further in the layout
  split_rows_by(
    "AVISIT",
    label_pos = "topleft",
    split_label = "Study Visit",
    split_fun = drop_split_levels,
    child_labels = "hidden"
  ) %>%
  ## set up a 3 column split
  split_cols_by_multivar(
    multivars,
    varlabels = c(
      "n/N (%)",
      "Mean (95% CI)",
      "Mean Change From Baseline (95% CI)"
    )
  ) %>%
  ### restart for the rrisk_header columns - note the nested = FALSE option
  ### also note the child_labels = "hidden" in both PARAM and AVISIT
  split_cols_by("rrisk_header", nested = FALSE) %>%
  split_cols_by(
    trtvar,
    split_fun = remove_split_levels(ctrl_grp),
    labels_var = "rrisk_label",
    show_colcounts = TRUE,
    colcount_format = "N=xx"
  ) %>%
  ### difference columns : just 1 column & analysis needs to be done on change
  split_cols_by_multivar(multivars[3], varlabels = c(" ")) %>%
  ### the variable passed here in analyze is not used (STUDYID), it is a dummy var passing,
  ### the function summarize_aval_chg_diff grabs the required vars from cols_by_multivar calls
  analyze(
    "STUDYID",
    afun = a_summarize_aval_chg_diff_j,
    extra_args = extra_args_3col
  )

result <- build_table(lyt, filtered_adeg, alt_counts_df = adsl)

# Post-Processing:

remove_col_count2 <- function(result, string = paste("vs", ctrl_grp)) {
  mcdf <- make_col_df(result, visible_only = FALSE)
  mcdfsel <- mcdf %>%
    filter(stringr::str_detect(toupper(label), toupper(string))) %>%
    pull(path)

  for (i in seq_along(mcdfsel)) {
    facet_colcount(result, mcdfsel[[i]]) <- NA
  }

  return(result)
}

result <- remove_col_count2(result)

# Add titles and footnotes:

result <- set_titles(result, titles)

# Convert to tbl file and output table

tt_to_tlgrtf(string_map = string_map, tt = 
  result,
  file = fileid,
  nosplitin = list(cols = c(trtvar, "rrisk_header")),
  orientation = "landscape"
)

TSFECG01: Mean Change From Baseline for ECG Data Over Time; Safety Analysis Set (Study jjcs - core)

Active Study Agent

Difference in Mean Change (95% CI)

Xanomeline High Dose

Xanomeline Low Dose

Placebo

Xanomeline High Dose vs Placebo

Xanomeline Low Dose vs Placebo

Parameter

N=53

N=73

N=59

Study Visit

n/N (%)

Mean (95% CI)

Mean Change From Baseline (95% CI)

n/N (%)

Mean (95% CI)

Mean Change From Baseline (95% CI)

n/N (%)

Mean (95% CI)

Mean Change From Baseline (95% CI)

ECG Mean Heart Rate
 (beats/min)

Baseline

53/53 (100.0%)

317.6 (275.1, 360.1)

73/73 (100.0%)

325.2 (282.7, 367.7)

59/59 (100.0%)

261.3 (216.2, 306.3)

Month 1

53/53 (100.0%)

242.6 (192.4, 292.7)

-75.1 (-139.6, -10.5)

71/71 (100.0%)

283.9 (239.6, 328.2)

-45.5 (-106.2, 15.2)

58/58 (100.0%)

276.4 (229.7, 323.1)

14.8 (-44.6, 74.3)

-89.9 (-176.7, -3.1)

-60.3 (-144.5, 23.8)

Month 3

53/53 (100.0%)

306.4 (251.3, 361.5)

-11.2 (-86.1, 63.6)

53/53 (100.0%)

302.6 (252.6, 352.5)

-21.2 (-92.9, 50.5)

56/56 (100.0%)

306.1 (258.9, 353.4)

42.5 (-24.1, 109.1)

-53.7 (-152.8, 45.4)

-63.7 (-160.4, 33.1)

Month 6

51/51 (100.0%)

281.3 (237.5, 325.0)

-28.7 (-93.6, 36.2)

47/47 (100.0%)

278.9 (229.3, 328.4)

-56.3 (-128.6, 16.0)

51/51 (100.0%)

293.7 (243.4, 344.1)

22.9 (-51.2, 96.9)

-51.6 (-148.9, 45.7)

-79.2 (-181.3, 23.0)

Month 9

41/41 (100.0%)

283.6 (230.9, 336.2)

-24.8 (-103.7, 54.1)

42/42 (100.0%)

301.3 (245.6, 357.1)

-26.2 (-98.9, 46.5)

51/51 (100.0%)

331.6 (281.3, 381.9)

60.7 (-20.7, 142.2)

-85.5 (-197.4, 26.3)

-86.9 (-194.6, 20.8)

Month 12

37/37 (100.0%)

312.9 (258.6, 367.1)

-2.1 (-64.5, 60.3)

35/35 (100.0%)

315.5 (253.9, 377.2)

-2.3 (-92.0, 87.4)

48/48 (100.0%)

313.2 (262.7, 363.6)

39.7 (-23.9, 103.4)

-41.9 (-129.7, 45.9)

-42.0 (-150.5, 66.4)

Month 15

27/27 (100.0%)

295.3 (230.3, 360.4)

-4.3 (-95.7, 87.2)

29/29 (100.0%)

286.8 (228.8, 344.8)

-14.2 (-110.3, 81.9)

47/47 (100.0%)

278.2 (231.6, 324.8)

2.4 (-74.7, 79.4)

-6.6 (-124.1, 110.8)

-16.6 (-137.6, 104.5)

Month 18

23/23 (100.0%)

308.3 (219.3, 397.3)

26.8 (-90.6, 144.2)

20/20 (100.0%)

294.5 (201.3, 387.7)

-29.4 (-157.4, 98.5)

45/45 (100.0%)

278.2 (232.8, 323.7)

-1.7 (-66.2, 62.9)

28.4 (-103.4, 160.3)

-27.8 (-168.7, 113.2)

Month 24

22/22 (100.0%)

283.6 (204.6, 362.7)

-3.7 (-118.7, 111.3)

16/16 (100.0%)

344.3 (250.0, 438.6)

25.9 (-129.3, 181.2)

41/41 (100.0%)

311.8 (256.6, 367.0)

33.1 (-41.6, 107.9)

-36.8 (-171.3, 97.6)

-7.2 (-176.1, 161.7)

PR Interval, Aggregate (msec)

Baseline

53/53 (100.0%)

304.2 (255.2, 353.2)

73/73 (100.0%)

346.5 (306.4, 386.6)

59/59 (100.0%)

306.1 (259.9, 352.2)

Month 1

53/53 (100.0%)

308.9 (264.2, 353.6)

4.7 (-67.2, 76.6)

71/71 (100.0%)

288.0 (247.1, 329.0)

-60.8 (-122.9, 1.2)

58/58 (100.0%)

269.3 (225.8, 312.9)

-32.0 (-93.4, 29.3)

36.7 (-56.7, 130.2)

-28.8 (-115.2, 57.6)

Month 3

53/53 (100.0%)

304.4 (255.7, 353.0)

0.2 (-63.7, 64.0)

53/53 (100.0%)

294.1 (248.1, 340.2)

-57.2 (-128.7, 14.3)

56/56 (100.0%)

249.4 (205.9, 292.9)

-52.7 (-116.0, 10.6)

52.8 (-36.1, 141.7)

-4.5 (-98.9, 89.9)

Month 6

51/51 (100.0%)

302.7 (254.5, 350.9)

-3.0 (-72.8, 66.8)

47/47 (100.0%)

301.0 (243.1, 358.8)

-46.2 (-116.2, 23.9)

51/51 (100.0%)

271.3 (225.4, 317.3)

-24.7 (-89.9, 40.4)

21.7 (-72.5, 116.0)

-21.4 (-115.9, 73.0)

Month 9

41/41 (100.0%)

273.0 (216.0, 330.0)

-35.4 (-115.2, 44.4)

42/42 (100.0%)

317.3 (262.8, 371.8)

-29.7 (-109.4, 50.0)

51/51 (100.0%)

279.4 (234.9, 324.0)

-16.6 (-83.4, 50.1)

-18.7 (-121.4, 83.9)

-13.0 (-115.6, 89.5)

Month 12

37/37 (100.0%)

249.3 (195.1, 303.6)

-60.2 (-139.3, 18.8)

35/35 (100.0%)

286.8 (232.0, 341.7)

-58.9 (-145.1, 27.4)

48/48 (100.0%)

271.8 (220.7, 322.9)

-26.0 (-107.7, 55.7)

-34.2 (-146.2, 77.8)

-32.8 (-149.8, 84.1)

Month 15

27/27 (100.0%)

292.3 (219.1, 365.6)

-32.1 (-132.1, 67.8)

29/29 (100.0%)

231.7 (166.3, 297.1)

-106.4 (-193.9, -18.9)

47/47 (100.0%)

311.6 (255.0, 368.1)

13.6 (-55.9, 83.1)

-45.7 (-165.4, 74.0)

-120.0 (-229.8, -10.1)

Month 18

23/23 (100.0%)

302.9 (214.7, 391.2)

-34.2 (-154.6, 86.2)

20/20 (100.0%)

331.0 (263.3, 398.6)

21.4 (-96.7, 139.5)

45/45 (100.0%)

312.1 (261.2, 363.0)

22.4 (-49.8, 94.5)

-56.6 (-194.5, 81.3)

-1.0 (-136.6, 134.7)

Month 24

22/22 (100.0%)

304.6 (223.8, 385.5)

-41.8 (-166.3, 82.6)

16/16 (100.0%)

274.6 (172.6, 376.7)

-36.5 (-197.5, 124.5)

41/41 (100.0%)

260.3 (205.8, 314.9)

-18.2 (-107.3, 70.8)

-23.6 (-173.5, 126.3)

-18.3 (-198.1, 161.5)

QRS Duration, Aggregate
 (msec)

Baseline

53/53 (100.0%)

303.0 (257.4, 348.6)

73/73 (100.0%)

305.2 (262.6, 347.8)

59/59 (100.0%)

299.3 (254.7, 343.9)

Month 1

53/53 (100.0%)

307.3 (261.6, 353.1)

4.3 (-61.1, 69.7)

71/71 (100.0%)

273.4 (233.3, 313.4)

-31.9 (-100.7, 36.9)

58/58 (100.0%)

299.1 (253.4, 344.8)

4.2 (-56.3, 64.8)

0.1 (-88.0, 88.2)

-36.1 (-126.9, 54.6)

Month 3

53/53 (100.0%)

314.8 (268.1, 361.5)

11.8 (-51.4, 75.0)

53/53 (100.0%)

321.8 (272.3, 371.2)

14.4 (-48.2, 77.0)

56/56 (100.0%)

247.0 (197.2, 296.8)

-46.4 (-117.4, 24.6)

58.1 (-35.8, 152.1)

60.8 (-32.8, 154.4)

Month 6

51/51 (100.0%)

272.4 (219.7, 325.2)

-25.2 (-90.3, 39.9)

47/47 (100.0%)

287.2 (234.1, 340.3)

-14.4 (-81.7, 53.0)

51/51 (100.0%)

275.9 (226.7, 325.2)

-13.8 (-82.0, 54.4)

-11.4 (-104.6, 81.8)

-0.6 (-95.2, 94.0)

Month 9

41/41 (100.0%)

310.9 (259.3, 362.5)

-20.5 (-89.5, 48.4)

42/42 (100.0%)

328.8 (283.2, 374.5)

32.4 (-39.5, 104.4)

51/51 (100.0%)

293.6 (249.7, 337.6)

3.9 (-62.9, 70.8)

-24.5 (-119.2, 70.3)

28.5 (-68.4, 125.4)

Month 12

37/37 (100.0%)

241.8 (181.4, 302.3)

-75.2 (-153.0, 2.7)

35/35 (100.0%)

295.5 (234.7, 356.4)

-5.2 (-89.9, 79.4)

48/48 (100.0%)

293.6 (242.5, 344.6)

6.2 (-67.3, 79.7)

-81.4 (-186.8, 24.1)

-11.4 (-121.8, 99.0)

Month 15

27/27 (100.0%)

284.3 (208.5, 360.0)

-36.8 (-117.6, 44.1)

29/29 (100.0%)

268.5 (216.8, 320.1)

-8.2 (-88.1, 71.7)

47/47 (100.0%)

290.3 (240.6, 339.9)

2.7 (-71.4, 76.8)

-39.5 (-147.1, 68.2)

-10.9 (-118.0, 96.1)

Month 18

23/23 (100.0%)

277.1 (211.7, 342.6)

-51.3 (-127.4, 24.8)

20/20 (100.0%)

259.6 (169.2, 349.9)

-18.7 (-147.3, 109.9)

45/45 (100.0%)

332.1 (284.5, 379.7)

48.0 (-20.7, 116.8)

-99.3 (-199.7, 1.1)

-66.7 (-210.0, 76.6)

Month 24

22/22 (100.0%)

274.2 (200.2, 348.2)

-58.6 (-177.2, 60.0)

16/16 (100.0%)

276.4 (173.8, 378.9)

-17.2 (-142.3, 107.8)

41/41 (100.0%)

302.9 (247.7, 358.0)

29.2 (-52.6, 111.0)

-87.8 (-228.9, 53.3)

-46.4 (-192.0, 99.1)

QT Interval, Corrected (msec)

Baseline

53/53 (100.0%)

361.3 (335.6, 386.9)

73/73 (100.0%)

356.8 (334.4, 379.3)

59/59 (100.0%)

362.7 (337.2, 388.3)

Month 1

53/53 (100.0%)

361.6 (338.2, 385.0)

0.4 (-30.8, 31.5)

71/71 (100.0%)

397.2 (376.7, 417.8)

39.7 (6.0, 73.5)

58/58 (100.0%)

368.3 (344.6, 392.0)

6.8 (-22.5, 36.2)

-6.5 (-48.8, 35.8)

32.9 (-11.4, 77.2)

Month 3

53/53 (100.0%)

364.2 (336.5, 391.9)

2.9 (-33.8, 39.7)

53/53 (100.0%)

372.4 (345.9, 398.9)

11.4 (-28.6, 51.4)

56/56 (100.0%)

355.2 (332.0, 378.5)

-6.4 (-43.3, 30.6)

9.3 (-42.2, 60.8)

17.8 (-36.1, 71.6)

Month 6

51/51 (100.0%)

359.1 (330.0, 388.3)

-0.9 (-36.6, 34.7)

47/47 (100.0%)

356.2 (325.4, 387.1)

-10.8 (-50.8, 29.2)

51/51 (100.0%)

333.6 (306.3, 361.0)

-23.2 (-63.8, 17.5)

22.2 (-31.2, 75.6)

12.4 (-43.9, 68.7)

Month 9

41/41 (100.0%)

367.9 (339.8, 396.0)

11.1 (-28.7, 51.0)

42/42 (100.0%)

356.4 (325.3, 387.5)

-4.9 (-47.2, 37.5)

51/51 (100.0%)

365.0 (340.2, 389.7)

8.2 (-27.8, 44.2)

2.9 (-50.0, 55.9)

-13.0 (-67.9, 41.8)

Month 12

37/37 (100.0%)

381.6 (346.3, 416.9)

26.5 (-21.1, 74.1)

35/35 (100.0%)

354.4 (317.3, 391.6)

-14.1 (-61.6, 33.5)

48/48 (100.0%)

377.1 (350.4, 403.9)

22.6 (-14.7, 59.9)

4.0 (-55.6, 63.6)

-36.6 (-96.1, 22.9)

Month 15

27/27 (100.0%)

403.8 (372.4, 435.2)

38.6 (-9.5, 86.7)

29/29 (100.0%)

365.9 (334.9, 396.9)

6.3 (-44.5, 57.1)

47/47 (100.0%)

401.4 (375.9, 427.0)

49.2 (13.6, 84.8)

-10.6 (-69.4, 48.2)

-42.9 (-103.9, 18.2)

Month 18

23/23 (100.0%)

375.0 (327.4, 422.6)

19.6 (-36.9, 76.0)

20/20 (100.0%)

363.0 (315.3, 410.8)

16.6 (-52.8, 86.0)

45/45 (100.0%)

371.8 (342.6, 400.9)

23.4 (-14.0, 60.7)

-3.8 (-70.2, 62.7)

-6.8 (-84.2, 70.7)

Month 24

22/22 (100.0%)

364.6 (328.6, 400.7)

9.8 (-60.1, 79.6)

16/16 (100.0%)

384.5 (337.7, 431.3)

32.6 (-48.4, 113.5)

41/41 (100.0%)

351.2 (320.6, 381.9)

3.5 (-34.4, 41.4)

6.3 (-71.9, 84.4)

29.1 (-58.6, 116.7)

QTcB Interval, Aggregate (msec)

Baseline

53/53 (100.0%)

359.8 (330.1, 389.5)

73/73 (100.0%)

348.7 (326.5, 370.9)

59/59 (100.0%)

368.6 (343.9, 393.3)

Month 1

53/53 (100.0%)

367.9 (340.5, 395.3)

8.1 (-34.6, 50.8)

71/71 (100.0%)

349.3 (327.7, 370.8)

-1.0 (-31.5, 29.5)

58/58 (100.0%)

368.1 (342.7, 393.5)

1.9 (-34.6, 38.3)

6.3 (-49.3, 61.8)

-2.8 (-49.9, 44.3)

Month 3

53/53 (100.0%)

361.7 (335.0, 388.3)

1.9 (-30.6, 34.4)

53/53 (100.0%)

364.5 (337.3, 391.7)

14.0 (-21.5, 49.6)

56/56 (100.0%)

361.4 (337.5, 385.3)

-8.4 (-43.0, 26.1)

10.3 (-36.5, 57.2)

22.5 (-26.5, 71.4)

Month 6

51/51 (100.0%)

355.1 (326.3, 383.9)

-4.6 (-49.4, 40.1)

47/47 (100.0%)

347.7 (320.6, 374.7)

-4.6 (-45.5, 36.2)

51/51 (100.0%)

352.5 (326.3, 378.6)

-22.8 (-59.4, 13.9)

18.2 (-39.0, 75.3)

18.2 (-36.0, 72.4)

Month 9

41/41 (100.0%)

353.8 (324.4, 383.2)

0.4 (-43.5, 44.4)

42/42 (100.0%)

352.1 (321.6, 382.6)

-2.4 (-44.0, 39.3)

51/51 (100.0%)

370.1 (345.1, 395.0)

-5.2 (-35.7, 25.3)

5.6 (-47.3, 58.4)

2.8 (-48.1, 53.8)

Month 12

37/37 (100.0%)

359.6 (329.8, 389.4)

15.9 (-33.3, 65.2)

35/35 (100.0%)

351.0 (319.0, 383.0)

-1.7 (-43.5, 40.0)

48/48 (100.0%)

364.6 (338.0, 391.3)

-10.3 (-48.7, 28.2)

26.2 (-35.3, 87.8)

8.6 (-47.3, 64.4)

Month 15

27/27 (100.0%)

374.8 (337.9, 411.7)

48.4 (-4.3, 101.1)

29/29 (100.0%)

380.2 (347.4, 412.9)

21.1 (-32.0, 74.1)

47/47 (100.0%)

383.9 (356.7, 411.0)

10.4 (-28.7, 49.5)

38.0 (-26.5, 102.5)

10.7 (-54.2, 75.5)

Month 18

23/23 (100.0%)

367.6 (329.7, 405.5)

30.8 (-16.0, 77.6)

20/20 (100.0%)

395.6 (348.4, 442.7)

35.0 (-32.1, 102.0)

45/45 (100.0%)

375.3 (343.6, 406.9)

3.9 (-41.2, 49.0)

26.9 (-36.7, 90.5)

31.1 (-48.0, 110.1)

Month 24

22/22 (100.0%)

358.0 (319.1, 396.8)

19.2 (-50.6, 89.0)

16/16 (100.0%)

406.6 (360.0, 453.3)

44.8 (-30.2, 119.9)

41/41 (100.0%)

362.6 (332.9, 392.2)

-17.8 (-55.9, 20.3)

37.0 (-41.2, 115.2)

62.6 (-19.8, 145.0)

QTcF Interval, Aggregate (msec)

Baseline

53/53 (100.0%)

351.6 (324.9, 378.3)

73/73 (100.0%)

347.4 (324.0, 370.8)

59/59 (100.0%)

367.4 (342.5, 392.4)

Month 1

53/53 (100.0%)

345.1 (318.0, 372.1)

-6.5 (-39.6, 26.6)

71/71 (100.0%)

348.6 (326.9, 370.3)

0.3 (-31.4, 31.9)

58/58 (100.0%)

361.9 (337.2, 386.7)

-8.2 (-41.2, 24.8)

1.7 (-44.5, 47.9)

8.5 (-36.8, 53.7)

Month 3

53/53 (100.0%)

354.6 (330.0, 379.3)

3.0 (-34.6, 40.7)

53/53 (100.0%)

372.4 (345.1, 399.7)

37.6 (1.6, 73.7)

56/56 (100.0%)

374.9 (350.7, 399.1)

5.5 (-30.8, 41.9)

-2.5 (-54.2, 49.2)

32.1 (-18.5, 82.7)

Month 6

51/51 (100.0%)

339.7 (310.6, 368.8)

-12.6 (-51.2, 26.0)

47/47 (100.0%)

354.6 (324.9, 384.3)

12.5 (-29.5, 54.5)

51/51 (100.0%)

357.2 (328.1, 386.3)

-5.9 (-42.7, 31.0)

-6.8 (-59.5, 46.0)

18.4 (-36.8, 73.6)

Month 9

41/41 (100.0%)

366.8 (334.7, 398.9)

18.5 (-33.0, 69.9)

42/42 (100.0%)

366.9 (338.4, 395.4)

30.3 (-9.0, 69.6)

51/51 (100.0%)

364.4 (336.0, 392.7)

1.3 (-38.4, 41.1)

17.1 (-47.1, 81.3)

29.0 (-26.2, 84.1)

Month 12

37/37 (100.0%)

365.1 (335.2, 394.9)

11.4 (-34.6, 57.4)

35/35 (100.0%)

377.8 (346.5, 409.1)

39.4 (-12.5, 91.4)

48/48 (100.0%)

351.7 (324.8, 378.6)

-10.5 (-48.6, 27.6)

21.9 (-37.0, 80.8)

49.9 (-13.6, 113.4)

Month 15

27/27 (100.0%)

383.8 (341.2, 426.4)

24.4 (-36.1, 84.9)

29/29 (100.0%)

326.1 (286.2, 366.1)

-18.6 (-74.0, 36.9)

47/47 (100.0%)

340.2 (310.0, 370.4)

-18.7 (-60.9, 23.4)

43.2 (-29.4, 115.7)

0.2 (-68.3, 68.7)

Month 18

23/23 (100.0%)

333.4 (294.1, 372.8)

-36.9 (-92.3, 18.5)

20/20 (100.0%)

375.0 (328.6, 421.3)

6.7 (-63.2, 76.5)

45/45 (100.0%)

367.6 (337.4, 397.7)

6.6 (-27.4, 40.6)

-43.5 (-107.3, 20.4)

0.1 (-76.4, 76.5)

Month 24

22/22 (100.0%)

379.0 (334.0, 424.0)

13.8 (-41.1, 68.7)

16/16 (100.0%)

380.6 (330.8, 430.5)

-3.4 (-56.9, 50.1)

41/41 (100.0%)

359.7 (328.7, 390.7)

2.3 (-35.4, 40.1)

11.5 (-53.8, 76.8)

-5.7 (-69.4, 58.0)

RR Interval, Aggregate (msec)

Baseline

53/53 (100.0%)

313.7 (269.4, 357.9)

73/73 (100.0%)

281.0 (241.4, 320.6)

59/59 (100.0%)

310.4 (268.7, 352.2)

Month 1

53/53 (100.0%)

250.6 (206.9, 294.4)

-63.0 (-122.1, -4.0)

71/71 (100.0%)

320.7 (280.1, 361.3)

35.5 (-21.8, 92.8)

58/58 (100.0%)

288.3 (245.3, 331.3)

-17.7 (-76.3, 40.9)

-45.3 (-127.6, 36.9)

53.2 (-28.0, 134.3)

Month 3

53/53 (100.0%)

311.0 (266.0, 356.1)

-2.6 (-67.2, 62.0)

53/53 (100.0%)

310.6 (258.3, 362.8)

19.2 (-47.0, 85.5)

56/56 (100.0%)

290.0 (248.1, 332.0)

-18.8 (-69.4, 31.9)

16.1 (-65.1, 97.3)

38.0 (-44.5, 120.5)

Month 6

51/51 (100.0%)

262.0 (218.0, 306.1)

-46.5 (-117.2, 24.2)

47/47 (100.0%)

307.1 (256.2, 358.1)

11.6 (-61.6, 84.8)

51/51 (100.0%)

331.8 (283.1, 380.6)

26.7 (-49.1, 102.6)

-73.3 (-175.7, 29.2)

-15.1 (-119.2, 88.9)

Month 9

41/41 (100.0%)

374.7 (325.8, 423.6)

61.7 (-15.3, 138.6)

42/42 (100.0%)

319.8 (270.3, 369.3)

26.1 (-43.9, 96.1)

51/51 (100.0%)

300.7 (252.1, 349.4)

-4.3 (-70.9, 62.3)

66.0 (-34.4, 166.4)

30.5 (-64.8, 125.7)

Month 12

37/37 (100.0%)

214.6 (166.2, 263.0)

-98.3 (-174.0, -22.5)

35/35 (100.0%)

293.0 (232.3, 353.7)

7.7 (-62.5, 77.9)

48/48 (100.0%)

346.4 (298.9, 393.8)

41.7 (-15.5, 99.0)

-140.0 (-233.6, -46.4)

-34.0 (-123.2, 55.2)

Month 15

27/27 (100.0%)

297.4 (225.4, 369.4)

-8.4 (-85.9, 69.0)

29/29 (100.0%)

329.7 (265.8, 393.6)

37.1 (-57.4, 131.6)

47/47 (100.0%)

337.6 (289.9, 385.3)

32.9 (-30.6, 96.5)

-41.4 (-139.7, 57.0)

4.2 (-108.0, 116.3)

Month 18

23/23 (100.0%)

289.6 (212.9, 366.3)

-32.9 (-138.6, 72.9)

20/20 (100.0%)

270.6 (203.8, 337.5)

-20.5 (-101.8, 60.8)

45/45 (100.0%)

310.0 (255.1, 364.8)

9.3 (-62.7, 81.3)

-42.2 (-167.7, 83.4)

-29.8 (-135.8, 76.2)

Month 24

22/22 (100.0%)

319.0 (234.7, 403.4)

4.3 (-85.6, 94.2)

16/16 (100.0%)

314.3 (236.3, 392.3)

14.9 (-106.5, 136.3)

41/41 (100.0%)

328.9 (280.2, 377.6)

27.4 (-42.3, 97.2)

-23.2 (-134.5, 88.1)

-12.6 (-149.3, 124.1)

Download RTF file

TSIDS02A
TSFECG01A
Source Code
---
title: TSFECG01
subtitle: Mean Change From Baseline for ECG Data Over Time
---

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

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

```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
options(docx.add_datetime = FALSE, tidytlg.add_datetime = FALSE)
envsetup_config_name <- "default"

# Path to the combined config file
envsetup_file_path <- file.path("../..", "envsetup.yml")

Sys.setenv(ENVSETUP_ENVIRON = '')
library(envsetup)
loaded_config <- config::get(config = envsetup_config_name, file = envsetup_file_path)
envsetup::rprofile(loaded_config)


dpscomp <- compound
dpspdr <- paste(protocol,dbrelease,rpteff,sep="__")

aptcomp <- compound
aptpdr <- paste(protocol,dbrelease,rpteff,sep="__")

###### Study specific updates (formerly in envre)

dpscomp <- "standards"
dpspdr <- "jjcs__NULL__jjcs - core"

apt <- FALSE
library(junco)
default_str_map <- rbind(default_str_map, c("&ctcae", "5.0"))

```

## Output

:::: panel-tabset
## {{< fa regular file-lines sm fw >}} Preview

```{r variant1, results='hide', warning = FALSE, message = FALSE}

# Program Name:              tsfecg01

# Prep Environment

library(envsetup)
library(tern)
library(dplyr)
library(rtables)
library(junco)

# Define script level parameters:

tblid <- "TSFECG01"
fileid <- tblid
titles <- get_titles_from_file(input_path = '../../_data/', tblid)
string_map <- default_str_map

popfl <- "SAFFL"
trtvar <- "TRT01A"
ctrl_grp <- "Placebo"

# Note on ancova parameter
# when ancova = TRUE
# ancova model will be used to calculate all mean/mean change columns
# not just those from the Difference column
# model specification
summ_vars <- list(arm = trtvar, covariates = NULL)

# when ancova = FALSE, all mean/mean change columns will be from descriptive stats
# for the difference column descriptive stats will be based upon two-sample t-test
ancova <- FALSE

comp_btw_group <- TRUE

selparamcd <- c("EGHRMN", "PRAG", "QRSAG", "QTC", "QTCBAG", "QTCFAG", "RRAG")
# see further, an alternative method to identify all non-unscheduled visits based upon data
selvisit <- c(
  "Baseline",
  "Month 1",
  "Month 3",
  "Month 6",
  "Month 9",
  "Month 12",
  "Month 15",
  "Month 18",
  "Month 24"
)

# Process Data:

adsl <- pharmaverseadamjnj::adsl %>%
  filter(.data[[popfl]] == "Y") %>%
  select(
    STUDYID,
    USUBJID,
    all_of(c(popfl, trtvar)),
    SEX,
    AGEGR1,
    RACE,
    ETHNIC,
    AGE
  )

adsl$colspan_trt <- factor(
  ifelse(adsl[[trtvar]] == ctrl_grp, " ", "Active Study Agent"),
  levels = c("Active Study Agent", " ")
)

adsl$rrisk_header <- "Difference in Mean Change (95% CI)"
adsl$rrisk_label <- paste(adsl[[trtvar]], paste("vs", ctrl_grp))


adeg00 <- pharmaverseadamjnj::adeg %>%
  select(
    USUBJID,
    AVISITN,
    AVISIT,
    PARAMCD,
    PARAM,
    AVAL,
    BASE,
    CHG,
    starts_with("ANL"),
    ABLFL,
    APOBLFL
    # ,EGSTAT
  ) %>%
  inner_join(adsl)

# selection of all non-unscheduled visits from data
visits <- adeg00 %>%
  select(AVISIT) %>%
  filter(!grepl("UNSCHEDULED", toupper(AVISIT)))

visits$AVISIT <- droplevels(visits$AVISIT)
selvisit_data <- levels(visits$AVISIT)

### if preferred to get it from data, rather than hardcoded list of visits
# selvisit <- selvisit_data

## retrieve the precision of AVAL on the input dataset
## review outcome and make updates manually if needed
## the precision variable will be used for the parameter-based formats in layout

## decimal = 4 is a cap in this derivation: if decimal precision of variable > decimal, the result will end up as decimal
## eg if AVAL has precision of 6 for parameter x, and decimal = 4, the resulting decimal value for parameter x is 4

## note that precision is on the raw values, as we are presenting mean/ci, and extra digit will be added
## eg precision = 2 will result in mean/ci format xx.xxx (xx.xxx, xx.xxx)

eg_precision <- tidytlg:::make_precision_data(
  df = adeg00,
  decimal = 4,
  precisionby = "PARAMCD",
  precisionon = "AVAL"
)


### data preparation

filtered_adeg <- adeg00 %>%
  filter(PARAMCD %in% selparamcd) %>%
  filter(AVISIT %in% selvisit) %>%
  ### unique record per timepoint:
  filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y"))

## issue with sysntethic data for Xanomeline Low Dose : 600 records rather than 300
check1 <- filtered_adeg %>%
  group_by(TRT01A, PARAM, AVISIT) %>%
  summarize(n_rec = n(), n_sub = n_distinct(USUBJID))


#### perform check on unique record per subject/param/timepoint
check_unique <- filtered_adeg %>%
  group_by(USUBJID, PARAMCD, AVISIT) %>%
  mutate(n_recsub = n()) %>%
  filter(n_recsub > 1)

if (nrow(check_unique) > 0) {
  stop(
    "Your input dataset needs extra attention, as some subjects have more than one record per parameter/visit"
  )
  ### you will run into issues with fraction portion in count_denom_fraction, as count > denom, and fraction > 1 if you don't adjust your input dataset

  # Possible extra derivation - just to ensure program can run without issues
  ### Study team is responsible for adding this derivation onto ADaM dataset and ensure proper derivation rule for ANL02FL is implemented !!!!!!!!!!
  filtered_adegx <- adeg00 %>%
    filter(PARAMCD %in% selparamcd) %>%
    filter(AVISIT %in% selvisit) %>%
    ### unique record per timepoint:
    filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y")) %>%
    group_by(USUBJID, PARAM, AVISIT) %>%
    mutate(n_sub = n()) %>%
    arrange(USUBJID, PARAM, AVISIT, ADT) %>%
    mutate(i = vctrs::vec_group_id(ADT)) %>%
    mutate(
      ANL02FL = case_when(
        n_sub == 1 ~ "Y",
        i == 1 ~ "Y"
      )
    ) %>%
    select(-c(i, n_sub)) %>%
    ungroup()

  filtered_adeg <- filtered_adegx %>%
    filter(PARAMCD %in% selparamcd) %>%
    filter(AVISIT %in% selvisit) %>%
    ### unique record per timepoint:
    filter(ANL02FL == "Y" & (ABLFL == "Y" | APOBLFL == "Y"))

  ## now your data should contain 1 record per subject per parameter
}


### for denominator per timepoint: all records from adeg on this timepoint: ignoring anl01fl/anl02fl/param
filtered_adeg_timepoints <- unique(
  adeg00 %>%
    filter(AVISIT %in% selvisit) %>%
    select(USUBJID, AVISITN, AVISIT)
) %>%
  inner_join(adsl)

params <- unique(filtered_adeg %>% select(PARAMCD, PARAM))

filtered_adeg_timepoints <- filtered_adeg_timepoints %>%
  mutate(dummy_join = 1) %>%
  full_join(
    params %>% mutate(dummy_join = 1),
    relationship = "many-to-many"
  ) %>%
  select(-dummy_join)

### identify subjects in filtered_advs_timepoints and not in filtered_advs

extra_sub <- anti_join(filtered_adeg_timepoints, filtered_adeg)

### only add these extra_sub to
### this will ensure we still meet the one record per subject per timepoint
### this will ensure length(x) can be used for the denominator derivation inside summarize_aval_chg_diff function

filtered_adeg <- bind_rows(filtered_adeg, extra_sub) %>%
  arrange(USUBJID, PARAM, AVISITN)

filtered_adeg <- filtered_adeg %>%
  inner_join(eg_precision, by = "PARAMCD")

### important: previous actions lost the label of variables
### in order to be able to use obj_label(filtered_advs$PARAM) in layout, need to redefine the label
filtered_adeg <- var_relabel_list(filtered_adeg, var_labels(adeg00, fill = T))

check1 <- filtered_adeg %>%
  group_by(TRT01A, PARAM, AVISIT) %>%
  summarize(n_rec = n(), n_sub = n_distinct(USUBJID))

colspan_trt_map <- create_colspan_map(
  adsl,
  non_active_grp = ctrl_grp,
  non_active_grp_span_lbl = " ",
  active_grp_span_lbl = "Active Study Agent",
  colspan_var = "colspan_trt",
  trt_var = trtvar
)

# Define layout and build table:

summ_vars <- list(arm = trtvar, covariates = NULL)
ref_path <- c("colspan_trt", " ", trtvar, ctrl_grp)
multivars <- c("AVAL", "AVAL", "CHG")

extra_args_3col <- list(
  format_na_str = rep("NA", 3),
  d = "decimal",
  variables = summ_vars,
  ref_path = ref_path,
  ancova = ancova,
  comp_btw_group = comp_btw_group,
  multivars = multivars
)


lyt <- basic_table(show_colcounts = FALSE, colcount_format = "N=xx") %>%
  ### first columns
  split_cols_by(
    "colspan_trt",
    split_fun = trim_levels_to_map(map = colspan_trt_map)
  ) %>%
  split_cols_by(trtvar, show_colcounts = TRUE, colcount_format = "N=xx") %>%
  split_rows_by(
    "PARAM",
    label_pos = "topleft",
    split_label = obj_label(filtered_adeg$PARAM),
    section_div = " ",
    split_fun = drop_split_levels
  ) %>%
  ## note the child_labels = hidden for AVISIT, these labels will be taken care off by
  ## applying function summarize_aval_chg_diff further in the layout
  split_rows_by(
    "AVISIT",
    label_pos = "topleft",
    split_label = "Study Visit",
    split_fun = drop_split_levels,
    child_labels = "hidden"
  ) %>%
  ## set up a 3 column split
  split_cols_by_multivar(
    multivars,
    varlabels = c(
      "n/N (%)",
      "Mean (95% CI)",
      "Mean Change From Baseline (95% CI)"
    )
  ) %>%
  ### restart for the rrisk_header columns - note the nested = FALSE option
  ### also note the child_labels = "hidden" in both PARAM and AVISIT
  split_cols_by("rrisk_header", nested = FALSE) %>%
  split_cols_by(
    trtvar,
    split_fun = remove_split_levels(ctrl_grp),
    labels_var = "rrisk_label",
    show_colcounts = TRUE,
    colcount_format = "N=xx"
  ) %>%
  ### difference columns : just 1 column & analysis needs to be done on change
  split_cols_by_multivar(multivars[3], varlabels = c(" ")) %>%
  ### the variable passed here in analyze is not used (STUDYID), it is a dummy var passing,
  ### the function summarize_aval_chg_diff grabs the required vars from cols_by_multivar calls
  analyze(
    "STUDYID",
    afun = a_summarize_aval_chg_diff_j,
    extra_args = extra_args_3col
  )

result <- build_table(lyt, filtered_adeg, alt_counts_df = adsl)

# Post-Processing:

remove_col_count2 <- function(result, string = paste("vs", ctrl_grp)) {
  mcdf <- make_col_df(result, visible_only = FALSE)
  mcdfsel <- mcdf %>%
    filter(stringr::str_detect(toupper(label), toupper(string))) %>%
    pull(path)

  for (i in seq_along(mcdfsel)) {
    facet_colcount(result, mcdfsel[[i]]) <- NA
  }

  return(result)
}

result <- remove_col_count2(result)

# Add titles and footnotes:

result <- set_titles(result, titles)

# Convert to tbl file and output table

tt_to_tlgrtf(string_map = string_map, tt = 
  result,
  file = fileid,
  nosplitin = list(cols = c(trtvar, "rrisk_header")),
  orientation = "landscape"
)
```
```{r result1, echo=FALSE, message=FALSE, warning=FALSE, test = list(result_v1 = "result")}
tt_to_flextable_j(result, tblid, string_map = string_map) 
```

[Download RTF file](`r paste0(tolower(tblid), '.rtf')`)
::::

Made with ❤️ by the J&J Team

  • Edit this page
  • Report an issue
Cookie Preferences