insightsengineering / teal.modules.clinical

Provides teal modules for the standard clinical trials outputs
https://insightsengineering.github.io/teal.modules.clinical/
Other
32 stars 17 forks source link

[Bug]: Encountering an error when a factor is passed as an argument to the x parameter in the tm_g_lineplot function - not dropping empty levels #1197

Closed PritDash closed 4 months ago

PritDash commented 5 months ago

What happened?

In the lineplot module, when the user assigns the factor variable to the x argument, the module incorrectly applies right-hand filtering.

I am aware character instead of factor solves this issue partly but then we are losing on the proper ordering.

This results in the corresponding table being not filtered based on the selected AVISIT value.

image

Please let me know if you want me to work on this issue?

This is the reproducible example:

library(shiny)
library(teal.code)
library(teal.data)
library(teal.slice)
library(teal)
library(teal.transform)
library(formatters)
library(magrittr)
library(rtables)
library(tern)
library(teal.modules.clinical)
library(admiral)
library(forcats)
library(dplyr)
warning('Code was not verified for reproducibility.')
ADSL <- admiral_adsl %>% mutate(ARM = factor(ARM))
ADLB <- admiral_adlb %>% mutate(AVALU = LBORRESU, AVISIT = fct_reorder(AVISIT, AVISITN, min))
stopifnot(rlang::hash(ADSL) == "cf6527e5bb3e68e5e830f768f1721246")
stopifnot(rlang::hash(ADLB) == "421b9e0909372dabe6ff9217fe642828")
ADLB <- dplyr::filter(ADLB, AVISIT %in% c("Baseline", "Week 2", "Week 4", "Week 20", "POST-BASELINE LAST"))
ADLB <- dplyr::inner_join(x = ADLB, y = ADSL[, c("STUDYID", "USUBJID"), drop = FALSE], by = c("STUDYID", "USUBJID"))
ANL_1 <- ADLB %>% dplyr::select(STUDYID, USUBJID, PARAMCD, AVISIT, AVAL, AVALU)
ANL_2 <- ADSL %>% dplyr::select(STUDYID, USUBJID, ARM)
ANL_3 <- ADLB %>% dplyr::filter(PARAMCD == "ALB") %>% dplyr::select(STUDYID, USUBJID, PARAMCD, AVISIT)
ANL <- ANL_1
ANL <- dplyr::inner_join(ANL, ANL_2, by = c("STUDYID", "USUBJID"))
ANL <- dplyr::inner_join(ANL, ANL_3, by = c("STUDYID", "USUBJID", "PARAMCD", "AVISIT"))
anl <- ANL %>% dplyr::mutate(ARM = droplevels(ARM))
variables <- control_lineplot_vars(x = "AVISIT", y = "AVAL", strata = "ARM", paramcd = "PARAMCD", y_unit = "AVALU")
grid::grid.newpage()
plot <- g_lineplot(df = anl, variables = variables, interval = "mean_ci", mid = "mean", whiskers = c("mean_ci_lwr", "mean_ci_upr"), table = c("n", "mean_sd", "median", "range"), mid_type = "pl", mid_point_size = 2, table_font_size = 4, newpage = FALSE, title = "Plot of Mean and 95% Mean Confidence Interval of AVAL by Visit", subtitle = "", caption = NULL, y_lab = "AVAL Mean Values for", legend_title = NULL, ggtheme = ggplot2::theme_minimal(), control = control_summarize_vars(conf_level = 0.95), subtitle_add_paramcd = FALSE,
subtitle_add_unit = FALSE)
plot

sessionInfo()

R version 4.2.2 (2022-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 22.04.4 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C               LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8     LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] dplyr_1.1.4                 forcats_1.0.0               admiral_1.1.0               teal.modules.clinical_0.9.0 tern_0.9.3                 
 [6] rtables_0.6.6               magrittr_2.0.3              formatters_0.5.5            teal.transform_0.5.0        teal_0.15.2                
[11] teal.slice_0.5.0            teal.data_0.5.0             teal.code_0.5.0             shiny_1.8.0                

loaded via a namespace (and not attached):
 [1] tidyr_1.3.1         splines_4.2.2       Rdpack_2.6          BiocManager_1.30.22 renv_1.0.4          tern.gee_0.1.3      pillar_1.9.0        backports_1.4.1    
 [9] lattice_0.20-45     glue_1.7.0          digest_0.6.34       promises_1.2.1      rbibutils_2.2.16    checkmate_2.3.1     colorspace_2.1-0    sandwich_3.1-0     
[17] htmltools_0.5.7     httpuv_1.6.14       Matrix_1.6-5        pkgconfig_2.0.3     broom_1.0.5         logger_0.2.2        purrr_1.0.2         xtable_1.8-4       
[25] mvtnorm_1.2-4       scales_1.3.0        later_1.3.2         timechange_0.3.0    emmeans_1.10.0      tibble_3.2.1        generics_0.1.3      ggplot2_3.5.0      
[33] ellipsis_0.3.2      TH.data_1.1-2       geepack_1.3.10      cli_3.6.2           survival_3.4-0      mime_0.12           estimability_1.4.1  fansi_1.0.6        
[41] nlme_3.1-160        MASS_7.3-58.1       tools_4.2.2         hms_1.1.3           lifecycle_1.0.4     multcomp_1.4-25     stringr_1.5.1       munsell_0.5.0      
[49] compiler_4.2.2      rlang_1.1.3         grid_4.2.2          rstudioapi_0.15.0   gtable_0.3.4        codetools_0.2-18    teal.logger_0.1.3   R6_2.5.1           
[57] zoo_1.8-12          lubridate_1.9.3     admiraldev_1.1.0    fastmap_1.1.1       utf8_1.2.4          stringi_1.8.3       Rcpp_1.0.12         vctrs_0.6.5        
[65] tidyselect_1.2.0

Relevant log output

No response

Code of Conduct

Contribution Guidelines

Security Policy

Melkiades commented 5 months ago

This is an issue in {tern}. NAs are dropped in the top plot but not in the bottom table/plot.

Melkiades commented 5 months ago

You can solve your issue instantly by doing anl <- anl %>% dplyr::mutate(AVISIT = droplevels(AVISIT)) but I will add this to {tern} for the future too.

PritDash commented 5 months ago

@Melkiades : Thanks for the suggestion. But since the issue comes from the APP (tm_g_lineplot module) and I am not writting any custom modules; I think it will not be feasible to add the above snippet code into the APP.

Melkiades commented 5 months ago

@Melkiades : Thanks for the suggestion. But since the issue comes from the APP (tm_g_lineplot module) and I am not writting any custom modules; I think it will not be feasible to add the above snippet code into the APP.

You do not need to have this in the APP. It is enough that you do it in preprocessing. Anytime before the APP. Otherwise, you should wait for the fix in {tern} that I linked above here.