Skip to content

Fix duplicated x scale and expose cap width in PK line plots - #323

Merged
wzfrank merged 18 commits into
mainfrom
322_pkc_lineplot_x_scale_and_caps@main
Oct 14, 2026
Merged

wzfrank merged 18 commits into
mainfrom
322_pkc_lineplot_x_scale_and_caps@main

Conversation

@Melkiades

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

All three are backwards compatible: every default reproduces the current output.

Detail

The x scale bug was visible in our own test suite. Before this change, Scale for x is already present. Adding another scale for x, which will replace the existing scale. appeared on essentially every gg_pkc_lineplot() test; after it, the full suite reports it zero times. Because ggplot2 kept the second scale, the expand = expansion(mult = 0.05) on the first one had never had any effect.

The two new arguments come from template work on PKCG03, where the lack of them was the stated reason for dropping gg_pkc_lineplot() and hand-writing the plot in raw ggplot2. That trade loses the input validation, the invalid stat/variability guard, the factor/numeric time_var handling and the LLOQ line. Both gaps are small enough to close directly.

x_breaks accepts a vector or a break function, so a 0 to 600 hour profile can use seq(0, 600, by = 100) or scales::breaks_pretty() instead of a tick per timepoint.

The three man/*.Rd files were updated by hand: the local roxygen2 is 7.3.3 while DESCRIPTION pins 8.1.0, and running the older version rewrote unrelated files. If CI regenerates docs with 8.1.0 and shows a diff in those three files, that diff is formatting only.

Reference GitHub issue associated with pull request. closes #322


Pre-review Checklist (if item does not apply, mark is as complete)

  • All GitHub Action workflows pass with a ✅
  • PR branch has pulled the most recent updates from master branch: usethis::pr_merge_main()
  • If a bug was fixed, a unit test was added.
  • Code coverage is suitable for any new functions/features (generally, 100% coverage for new code): devtools::test_coverage()
  • Request a reviewer

gg_pkc_lineplot() added two scale_x_continuous() layers, so ggplot2 dropped
the first and reported "Scale for x is already present" on every call with a
numeric time_var. The expand setting carried by the discarded scale never
applied. A single scale is now added, keeping that expand.

Adds x_breaks to gg_pkc_lineplot() for time ranges too wide to label every
timepoint, and a width argument to gg_add_stats() exposed as errorbar_width
on gg_pkc_lineplot() and gg_lineplot(). All defaults preserve current output.
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Unit Tests Summary

  1 files  338 suites   1m 50s ⏱️
338 tests 338 ✅ 0 💤 0 ❌
987 runs  987 ✅ 0 💤 0 ❌

Results for commit 2067888.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Unit Test Performance Difference

Test Suite $Status$ Time on main $±Time$ $±Tests$ $±Skipped$ $±Failures$ $±Errors$
gg_pkc_boxplot 👶 $+0.00$ $+2$ $0$ $0$ $0$
modify_header_rm_md 💔 $0.10$ $+1.10$ $0$ $0$ $0$ $0$
Additional test case details
Test Suite $Status$ Time on main $±Time$ Test Case
add_forest 💚 $4.55$ $-1.15$ add_forest_table_engine_flextable_works
add_grade_column 💚 $7.95$ $-1.09$ add_grade_column_works_on_a_standalone_tbl_hierarchical_rate_by_grade
annotate_gg 💚 $3.61$ $-3.22$ annotate_lineplot_df_warns_if_plot_is_not_generated_by_gg_lineplot
annotate_gg_km 💔 $0.01$ $+3.17$ annotate_riskdf_handles_all_branches_and_inputs
gg_lineplot 👶 $+0.00$ gg_lineplot_errorbar_width_sets_the_error_bar_cap_width
gg_lineplot 💚 $1.26$ $-1.10$ gg_lineplot_input_validation_catches_invalid_statistical_combinations
gg_pkc_boxplot 👶 $+1.68$ gg_pkc_boxplot_catches_invalid_arguments_and_missing_inputs
gg_pkc_boxplot 👶 $+0.01$ gg_pkc_boxplot_computes_tukey_whiskers_and_flags_outliers
gg_pkc_boxplot 👶 $+0.00$ gg_pkc_boxplot_converts_time_var_to_a_discrete_factor_regardless_of_input_type
gg_pkc_boxplot 👶 $+0.00$ gg_pkc_boxplot_dodges_boxes_whiskers_outliers_and_the_mean_marker_together
gg_pkc_boxplot 👶 $+0.02$ gg_pkc_boxplot_drops_non_positive_values_before_log_transforming
gg_pkc_boxplot 👶 $+0.00$ gg_pkc_boxplot_passes_quantile_type_through_to_stats_quantile
gg_pkc_boxplot 👶 $+0.01$ gg_pkc_boxplot_percentile_and_minmax_whiskers_do_not_flag_the_same_outlier
gg_pkc_boxplot 👶 $+0.00$ gg_pkc_boxplot_toggles_the_mean_marker_layer_with_show_mean
gg_pkc_lineplot 👶 $+0.00$ gg_pkc_lineplot_adds_a_single_x_scale_and_honours_x_breaks
gg_pkc_lineplot 👶 $+0.00$ gg_pkc_lineplot_dodges_error_bars_to_match_the_line_point_layers
gg_pkc_lineplot 👶 $+0.00$ gg_pkc_lineplot_passes_errorbar_width_to_the_error_bar_caps
gg_utils 💚 $1.23$ $-1.09$ df2gg_aligned_input_validation_and_error_handling_works
modify_header_rm_md 💔 $0.10$ $+1.10$ strip_md_bold_works_with_gtsummary_table
tbl_baseline_chg 💚 $13.37$ $-2.60$ tbl_baseline_chg_works
tbl_hierarchical_rate_and_count 💚 $10.45$ $-1.65$ tbl_hierarchical_rate_and_count_works
tbl_hierarchical_rate_by_grade 💚 $12.87$ $-3.78$ tbl_hierarchical_rate_by_grade_works
tbl_mmrm 💔 $0.41$ $+1.85$ se_calculates_standard_error_correctly
tbl_proportion 💚 $5.70$ $-2.94$ tbl_proportion_binary_summary_works
tbl_rmpt 💔 $3.36$ $+1.64$ tbl_rmpt_works_with_default_parameters_Example_1_
tbl_roche_subgroups 💚 $10.08$ $-3.45$ tbl_roche_subgroups_time_to_event_NULL_works
tbl_shift 💔 $0.15$ $+1.73$ tbl_shift_strata_location_
tbl_survfit_times 💚 $2.28$ $-2.09$ tbl_survfit_times_works

Results for commit a9eacd7

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

badge

Code Coverage Summary

Filename                                 Stmts    Miss  Cover    Missing
-------------------------------------  -------  ------  -------  ------------------------------------------------------------------------------------------------
R/add_blank_rows.R                          63       0  100.00%
R/add_difference_row.R                     101       0  100.00%
R/add_forest_utils.R                        97      10  89.69%   76-79, 94-100
R/add_forest.R                             139       0  100.00%
R/add_hierarchical_count_row.R              33       0  100.00%
R/add_label_column.R                        26       0  100.00%
R/add_proportion_difference.R              150       1  99.33%   245
R/add_proportion_odds_ratio.R               57       0  100.00%
R/adjust_stat_columns_wrap.R                29       1  96.55%   59
R/annotate_gg_km.R                         141       0  100.00%
R/annotate_gg_pkc.R                        100       0  100.00%
R/annotate_gg.R                             94       0  100.00%
R/ard_tabulate_abnormal_by_baseline.R       65       0  100.00%
R/crane-package.R                            2       2  0.00%    26-27
R/deprecated.R                              21      21  0.00%    18-54
R/df_add_poolings.R                         41       0  100.00%
R/get_cox_pairwise_df.R                    163       0  100.00%
R/gg_km_utils.R                             39      14  64.10%   20-37
R/gg_km.R                                  143      37  74.13%   55-58, 75, 102, 176-181, 184-187, 197-199, 204-205, 239-241, 248-251, 255, 266-270, 283, 285-287
R/gg_lineplot.R                            113       0  100.00%
R/gg_mmrm_lineplot.R                       102       1  99.02%   106
R/gg_pkc_boxplot.R                         195       5  97.44%   108, 136-139
R/gg_pkc_lineplot.R                        118       0  100.00%
R/gg_utils.R                               222       0  100.00%
R/label_roche.R                             72       0  100.00%
R/modify_header_rm_md.R                     18       2  88.89%   35-36
R/modify_split_caption.R                    37       0  100.00%
R/modify_zero_recode.R                      20       1  95.00%   64
R/pk_helper.R                              499       0  100.00%
R/reverse_difference_ci.R                   33       0  100.00%
R/tbl_baseline_chg.R                       188       0  100.00%
R/tbl_coxph.R                               90       1  98.89%   229
R/tbl_hierarchical_incidence_rate.R        291       4  98.63%   430-433
R/tbl_hierarchical_rate_and_count.R        339      13  96.17%   343, 425, 446-456
R/tbl_hierarchical_rate_by_grade.R         317       3  99.05%   169-171
R/tbl_listing.R                             36       0  100.00%
R/tbl_mmrm.R                               344       6  98.26%   452-456, 548
R/tbl_null_report.R                         10       0  100.00%
R/tbl_proportion.R                         141      13  90.78%   100-103, 107-111, 114-117
R/tbl_rmpt.R                               157      12  92.36%   299-304, 316-321
R/tbl_roche_subgroups.R                    157       0  100.00%
R/tbl_roche_summary.R                       64       0  100.00%
R/tbl_shift.R                              111       0  100.00%
R/tbl_survfit_quantiles.R                  154       0  100.00%
R/tbl_survfit_times.R                       92       0  100.00%
R/tbl_with_pools.R                          79       1  98.73%   317
R/theme_gtsummary_roche.R                   87       1  98.85%   61
R/utils.R                                   42       0  100.00%
TOTAL                                     5632     149  97.35%

Diff against main

Filename               Stmts    Miss  Cover
-------------------  -------  ------  --------
R/gg_lineplot.R           -8       0  +100.00%
R/gg_pkc_boxplot.R      +195      +5  +97.44%
R/gg_pkc_lineplot.R      +20       0  +100.00%
TOTAL                   +207      +5  +0.01%

Results for commit: 2067888

Minimum allowed coverage is 80%

♻️ This comment has been updated with latest results

@Melkiades
Melkiades requested a review from wzfrank September 30, 2026 08:48
@qiliu1013

qiliu1013 commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Hi @Melkiades,

errorbar_idx <- which(vapply(plt_pkcg03$layers, function(l) inherits(l$geom, "GeomErrorbar"), logical(1))) plt_pkcg03$layers[[errorbar_idx]]$position <- ggplot2::position_dodge(width = 0.2)

  • Additionally, I got following message, which is a bit confused, we want the time_var to be numeric and we won't show the summary table under the table. Can you please remove this message from the function?

"We encourage to supply time_var as a factor, since it supports correct decimals formatting in the summary table."

  • The y scale will be reassigned when apply log scale based on the actual range of log y, could you please remove the message below.

Scale for y is already present. Adding another scale for y, which will replace the existing scale.

Thanks,
Qi

wzfrank and others added 3 commits October 5, 2026 19:28
Error bars in gg_pkc_lineplot() were not dodged like the line/point
layers, causing overlap across groups. Also removes a cli_inform()
message that incorrectly nudged users to supply time_var/x as a
factor, which contradicts the intended numeric usage.

Co-authored-by: Claude <noreply@anthropic.com>
Adds a new PK box plot function with selectable whisker method
(percentile, tukey, minmax), outlier detection, and an optional mean
marker, documented and tested to match gg_pkc_lineplot()'s conventions.
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ All contributors have signed the CLA
Posted by the CLA Assistant Lite bot.

@wzfrank

wzfrank commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

I have read the CLA Document and I hereby sign the CLA

Reword "5th/95th" to "5th and 95th" to avoid a spelling false-positive,
and qualify the bare .time symbol with .data$ in group_by() to resolve
the "no visible binding for global variable" NOTE.
Spellcheck also flagged "th" in "5th and 95th"; use "5% and 95%" instead.
Escape % in gg_pkc_boxplot.Rd (unescaped % starts a comment in Rd
syntax) and fix the scale_x_continuous() link topic in
gg_pkc_lineplot.Rd, per the CI "manuals not up-to-date" diff.
pkgdown::build_site() errors when an exported topic is missing from
_pkgdown.yml's reference index.
Comment thread R/gg_pkc_boxplot.R Outdated
Comment thread R/gg_pkc_boxplot.R
Comment thread R/gg_pkc_boxplot.R
Comment thread R/gg_pkc_boxplot.R
@Melkiades

Copy link
Copy Markdown
Contributor Author

It looks super good to me!! Thanks Zhen

…oxplot()

- Add `percentiles` parameter (default c(0.05, 0.95)) to customize
  whisker percentiles when whisker = "percentile"
- Validate percentiles: must be two-element numeric, ordered, in [0,1]
- Warn when non-positive values are removed for log_y = TRUE
- Change dodge width from 0.8 to 1 so boxes touch
- Add example showing custom 10%/90% percentiles
gg_pkc_lineplot():
- Add dodge_width parameter (default 0.2) to control horizontal
  separation between groups, replacing the hardcoded 0.2 value
- Prevents overlap when errorbar_width > dodge_width

gg_pkc_boxplot():
- Warn when non-positive values are removed for log_y = TRUE
- Change dodge width from 0.8 to 1 so boxes touch
- Change errorbar cap width from 0.8 to 1 to match

@wzfrank wzfrank left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All functions are good and well tested.

Comment thread R/gg_pkc_boxplot.R Outdated
…bility

- ARD now uses switch(whisker) to produce self-describing stat names:
  percentile → p05/p25/p50/p75/p95
  minmax     → min/p25/p50/p75/max
  tukey      → p25/p50/p75/iqr/lower_whisker/upper_whisker
- Add optional id_var parameter; when supplied, outlier ARD rows carry
  the subject ID as stat_label (matching the template USUBJID convention)
Replace generic ymin/ymax with descriptive bound names matching the
template: mean_plus_sd/mean_minus_sd (sd), mean_plus_se/mean_minus_se
(se), upper_ci/lower_ci (ci), q75/q25 (iqr). Align N capitalisation
with the template. Minor comment cleanup in gg_pkc_boxplot.
@wzfrank
wzfrank merged commit a70c651 into main Oct 14, 2026
34 checks passed
@wzfrank
wzfrank deleted the 322_pkc_lineplot_x_scale_and_caps@main branch October 14, 2026 16:59
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gg_pkc_lineplot() adds two x scales and hardcodes the error bar cap width

3 participants