Streamlining R Deliverables at J&J

The Junco TLG Catalog and Production-Ready Exporters

David Munoz Tord - Senior R Developer

Cytel FSP - Johnson & Johnson Innovative Medicine

April 28, 2026

Standardized Clinical Catalog

The Challenge: Streamlining Clinical Trial Deliverables


Key Challenges in Pharma R Deliverables

  • Volume and complexity of clinical data analysis
  • Regulatory requirements for consistent formatting
  • Time pressure for rapid delivery across studies
  • Quality assurance and validation needs

Solution: The Junco TLG Catalog

What is the Junco TLG Catalog?


The Junco TLG Catalog provides a standardized library for clinical reporting with R:

  • Pre-built templates for common clinical tables (demographics, vital signs, adverse events, etc.)
  • Consistent formatting across all outputs
  • Statistical calculations aligned with J&J standards
  • Modular components for customization

Benefits: Faster development, reduced errors, regulatory compliance

The Actual Catalog

Exporters


Key Challenges in Pharma R Outputs


  • Regulatory compliance: Meeting specific formatting and submission requirements
  • Complex layouts: Handling multi-level headers, spanning cells, and pagination
  • Output formats: Need for DOCX, RTF, and other formats
  • Integration: Seamless workflow from data analysis to final deliverable


Solution: Junco’s exporters for regulatory formats

Production-Ready Exporters


Export Functions for Regulatory Submissions

Junco’s exporters include:

  • DOCX generation: For Word-compatible documents (export_TLG_as_docx)
  • RTF export: For legacy Word formats (tt_to_tlgrtf)
  • Quality assurance: Validated formatting and layout

Key Features

  • True-type font support
  • Automatic pagination
  • Regulatory-compliant styling
  • Custom page orientation, font sizes, spanning headers

Code Examples


library(junco)
library(rtables)
library(dplyr)

# Create sample table layout
colspan_trt_map <- create_colspan_map(adsl,
  non_active_grp = "Placebo",
  non_active_grp_span_lbl = " ",
  active_grp_span_lbl = "Active Study Agent",
  colspan_var = "colspan_trt",
  trt_var = "TRT01A")


lyt <- basic_table(show_colcounts = TRUE, colcount_format = "N=xx") |>
  split_cols_by("colspan_trt", split_fun = trim_levels_to_map(map = colspan_trt_map)) |>
  split_cols_by("TRT01A", show_colcounts = FALSE) |>
  split_rows_by("SEX", section_div = " ", split_fun = drop_split_levels) |>
  summarize_row_groups("SEX", cfun = a_freq_j, extra_args = list(denom = "n_df", denom_by = "SEX", riskdiff = FALSE, extrablankline = TRUE, .stats = c("count_unique"))) |>
  analyze("RESPONSE", afun = a_freq_j, extra_args = list(denom = "n_df", denom_by = "SEX", riskdiff = FALSE, .stats = c("count_unique_fraction")))

result <- build_table(lyt, adsl)

export_TLG_as_docx(result, tblid = "example_table")

Exporting to DOCX and RTF

Example DOCX Export :

# Export table to DOCX with landscape orientation
export_TLG_as_docx(result,
                 tblid = "example_table",
                 output_dir = "output")

Example RTF Export with Landscape:

tt_to_tlgrtf(result,
                tblid = "example_table",
                output_dir = "output")


Example Output:


example_table:Example Clinical Table

Active Study Agent

Example Drug 5 mg

Example Drug 10 mg

Example Drug 20 mg

Placebo

N=2

N=2

N=2

N=2

Male

1

1

1

1

Yes

1 (100.0%)

0

1 (100.0%)

0

No

0

1 (100.0%)

0

1 (100.0%)

Female

1

1

1

1

Yes

1 (100.0%)

0

1 (100.0%)

1 (100.0%)

No

0

1 (100.0%)

0

0


[example_table.docx][C:\Users\david.tord\quarto\share\rmd\rmd.R] 28APR2026, 14:18

Markup Customization

Customization of the markup for a .docx file is as follows:

custom_markup <- junco:::dps_markup_df_docx %>%
  dplyr::add_row(keyword = "custom_symbol",
            replace_by = "flextable::as_strike")
            
adsl_superscript <- data.frame(TRT01A = c("Example Drug~[super a] 5 mg",
                              "Example Drug~[super b] 10 mg",
                              "Example Drug~[custom_symbol X] 20 mg",
                              "Placebo"),
                              SUBJECT = c("1","2","3","4"),
                              HEIGHT = c(70, 74, 60, 64)
)


lyt <- basic_table(
  show_colcounts = FALSE,
  colcount_format = "N=xx"
) |>
  split_cols_by("TRT01A",show_colcounts = FALSE
  ) |>
  analyze("HEIGHT", afun = list_wrap_x(summary), format = "xx.xx")

result <- build_table(lyt, adsl_superscript)

export_TLG_as_docx(result,
             file = "superscript_table",
             orientation = "landscape",
             markup_df_docx = custom_markup)


Output Customization with Markup


custom_markup
# A tibble: 3 × 2
  keyword       replace_by          
  <chr>         <chr>               
1 super         flextable::as_sup   
2 sub           flextable::as_sub   
3 custom_symbol flextable::as_strike


Example Druga 5 mg

Example Drugb 10 mg

Example DrugX 20 mg

Placebo

Min.

70.00

74.00

60.00

64.00

1st Qu.

70.00

74.00

60.00

64.00

Median

70.00

74.00

60.00

64.00

Mean

70.00

74.00

60.00

64.00

3rd Qu.

70.00

74.00

60.00

64.00

Max.

70.00

74.00

60.00

64.00

[superscript_table.docx][C:\Users\david.tord\quarto\share\rmd\rmd.R] 28APR2026, 14:18

SAS-like Rounding


export_TLG_as_docx(result,
             file = "round_sas",
             orientation = "landscape",
             round_type = "sas")


Example Druga 5 mg

Example Drugb 10 mg

Example DrugX 20 mg

Placebo

Min.

70.00

74.00

60.00

64.00

1st Qu.

70.00

74.00

60.00

64.00

Median

70.00

74.00

60.00

64.00

Mean

70.00

74.00

60.00

64.00

3rd Qu.

70.00

74.00

60.00

64.00

Max.

70.00

74.00

60.00

64.00

[round_sas.docx][C:\Users\david.tord\quarto\share\rmd\rmd.R] 28APR2026, 14:18

No Split (Treatment Variable)


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

Active Study Agent

Xanomeline High Dose

System Organ Class

Race

Preferred Term, n (%)

Total

White

Black

Asian

Other

Analysis set: Safety

47

8

3

10

26

Subjects with ≥1 AE

32 (68.1%)

7 (87.5%)

1 (33.3%)

8 (80.0%)

16 (61.5%)

Skin and subcutaneous tissue disorders

32 (68.1%)

7 (87.5%)

1 (33.3%)

8 (80.0%)

16 (61.5%)

ACTINIC KERATOSIS

1 (2.1%)

0

0

0

1 (3.8%)

ALOPECIA

0

0

0

0

0

BLISTER

1 (2.1%)

0

0

0

1 (3.8%)

DRUG ERUPTION

0

0

0

0

0

ERYTHEMA

10 (21.3%)

3 (37.5%)

1 (33.3%)

0

6 (23.1%)

HYPERHIDROSIS

7 (14.9%)

2 (25.0%)

0

3 (30.0%)

2 (7.7%)

PRURITUS

18 (38.3%)

3 (37.5%)

1 (33.3%)

4 (40.0%)

10 (38.5%)

PRURITUS GENERALISED

1 (2.1%)

0

0

1 (10.0%)

0

RASH

5 (10.6%)

0

0

2 (20.0%)

3 (11.5%)

RASH ERYTHEMATOUS

0

0

0

0

0

RASH MACULO-PAPULAR

1 (2.1%)

0

0

0

1 (3.8%)

RASH PRURITIC

2 (4.3%)

1 (12.5%)

0

0

1 (3.8%)

SKIN IRRITATION

4 (8.5%)

1 (12.5%)

0

2 (20.0%)

1 (3.8%)

SKIN ODOUR ABNORMAL

1 (2.1%)

1 (12.5%)

0

0

0

SKIN ULCER

0

0

0

0

0

URTICARIA

1 (2.1%)

0

0

0

1 (3.8%)

[aetablemultipledocs2part1of3.docx][C:\Users\david.tord\quarto\share\rmd\rmd.R] 28APR2026, 14:18



Continued Treatment Variable (Low Dose)


Active Study Agent

Xanomeline Low Dose

System Organ Class

Race

Preferred Term, n (%)

Total

White

Black

Asian

Other

Analysis set: Safety

68

8

11

9

40

Subjects with ≥1 AE

26 (38.2%)

4 (50.0%)

4 (36.4%)

4 (44.4%)

14 (35.0%)

Skin and subcutaneous tissue disorders

26 (38.2%)

4 (50.0%)

4 (36.4%)

4 (44.4%)

14 (35.0%)

ACTINIC KERATOSIS

0

0

0

0

0

ALOPECIA

0

0

0

0

0

BLISTER

2 (2.9%)

0

0

0

2 (5.0%)

DRUG ERUPTION

0

0

0

0

0

ERYTHEMA

8 (11.8%)

1 (12.5%)

1 (9.1%)

0

6 (15.0%)

HYPERHIDROSIS

3 (4.4%)

0

0

2 (22.2%)

1 (2.5%)

PRURITUS

14 (20.6%)

3 (37.5%)

1 (9.1%)

2 (22.2%)

8 (20.0%)

PRURITUS GENERALISED

0

0

0

0

0

RASH

8 (11.8%)

3 (37.5%)

2 (18.2%)

1 (11.1%)

2 (5.0%)

RASH ERYTHEMATOUS

1 (1.5%)

0

0

0

1 (2.5%)

RASH MACULO-PAPULAR

0

0

0

0

0

RASH PRURITIC

1 (1.5%)

0

1 (9.1%)

0

0

SKIN IRRITATION

4 (5.9%)

0

0

1 (11.1%)

3 (7.5%)

SKIN ODOUR ABNORMAL

0

0

0

0

0

SKIN ULCER

0

0

0

0

0

URTICARIA

1 (1.5%)

1 (12.5%)

0

0

0

[aetablemultipledocs2part2of3.docx][C:\Users\david.tord\quarto\share\rmd\rmd.R] 28APR2026, 14:18



Some other Advanced Capabilitiesties


  • Risk difference calculations with confidence intervals

  • Higher-order column spanning for complex headers (create_colspan_map)

  • Combined treatment columns for aggregated data (add_combo_facet)

  • Pathability in row and column spaces

  • Integration with pharmaverse ecosystem

Summary


Benefits

  • Standardized across multiple therapeutic areas
  • Reduced development time
  • Improved consistency in regulatory submissions
  • Faster time-to-delivery
  • Reduced manual errors
  • Streamlined validation processes
  • Community-driven open-source development

Future: Expanding catalog, enhancing exporters, community feedback

Resources


Junco Logo

Q&A


Thank You for Your Attention!


junco Team Acknowledgements:

  • Sairam Gorthi
  • Nick Masel
  • Ilse Augustyns
  • Ezequiel Anokian
  • Joseph Kovach
  • Gabriel Becker

Contact Information