insightsengineering / formatters

A framework for creating listings of raw data that include specialized formatting, headers, footers, referential footnotes, and pagination.
https://insightsengineering.github.io/formatters/
Other
15 stars 6 forks source link

format_value cannot always correctly handle custom strings that are displayed when the value of x is missing #308

Closed kaipingyang closed 1 month ago

kaipingyang commented 1 month ago

Summary

For formatters v0.5.8: format_value cannot always correctly handle custom strings that are displayed when the value of x is missing For examples, when I set format = "xx.x (xx.x - xx.x)" and na_str = "NE", abc doesn't always get "NE".

> format_value(c(1,1,NA), format = "xx.x (xx.x - xx.x)", na_str = "NE")
[1] "1.0 (1.0 - NA)"
> format_value(c(1,NA,NA), format = "xx.x (xx.x - xx.x)", na_str = "NE")
[1] "1.0 (NE - NA)"
> format_value(c(NA,NA,1), format = "xx.x (xx.x - xx.x)", na_str = "NE")
[1] "NE (NE - 1.0)"
> format_value(c(NA,1,NA), format = "xx.x (xx.x - xx.x)", na_str = "NE")
[1] "NE (1.0 - NA)"
> format_value(c(NA,1,1), format = "xx.x (xx.x - xx.x)", na_str = "NE")
[1] "NE (1.0 - 1.0)"

R session info


R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
Running under: Red Hat Enterprise Linux

Matrix products: default
BLAS/LAPACK: /usr/lib64/libopenblasp-r0.3.3.so;  LAPACK version 3.8.0

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

time zone: America/Los_Angeles
tzcode source: system (glibc)

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

other attached packages:
 [1] bslib_0.7.0                 DT_0.33                     shinyjs_2.1.0              
 [4] reactable_0.4.4             shinylogs_0.2.1             nestcolor_0.1.2            
 [7] sparkline_2.0               scda.2022_0.1.5             scda_0.1.6                 
[10] teal.reporter_0.3.1         teal.widgets_0.4.2          teal.logger_0.2.0          
[13] teal.osprey_0.1.16          osprey_0.1.16               teal.modules.clinical_0.9.1
[16] teal.modules.general_0.3.0  teal.transform_0.5.0        ggmosaic_0.3.3             
[19] teal_0.15.2                 teal.slice_0.5.1            teal.data_0.6.0            
[22] teal.code_0.5.0             tern_0.9.5                  RSQLite_2.3.7              
[25] DBI_1.2.3                   dbplyr_2.5.0                qs_0.26.3                  
[28] glue_1.7.0                  readxl_1.4.3                haven_2.5.4                
[31] lubridate_1.9.3             forcats_1.0.0               stringr_1.5.1              
[34] purrr_1.0.2                 readr_2.1.5                 tidyr_1.3.1                
[37] tibble_3.2.1                ggplot2_3.5.1               tidyverse_2.0.0            
[40] admiral_1.1.1               dplyr_1.1.4                 rtables_0.6.9              
[43] magrittr_2.0.3              formatters_0.5.8            shiny_1.8.1.1              
[46] officer_0.6.6              

loaded via a namespace (and not attached):
  [1] rstudioapi_0.16.0        jsonlite_1.8.8           estimability_1.5.1       rmarkdown_2.27          
  [5] geepack_1.3.11           ragg_1.3.2               vctrs_0.6.5              memoise_2.0.1           
  [9] shinydashboardPlus_2.0.4 askpass_1.2.0            htmltools_0.5.8.1        broom_1.0.6             
 [13] cellranger_1.1.0         sass_0.4.9               fontawesome_0.5.2        htmlwidgets_1.6.4       
 [17] zoo_1.8-12               emmeans_1.10.3           plotly_4.10.4            cachem_1.1.0            
 [21] uuid_1.2-0               mime_0.12                lifecycle_1.0.4          pkgconfig_2.0.3         
 [25] Matrix_1.7-0             R6_2.5.1                 fastmap_1.2.0            rbibutils_2.2.16        
 [29] digest_0.6.36            colorspace_2.1-0         shinycssloaders_1.0.0    crosstalk_1.2.1         
 [33] textshaping_0.4.0        reactR_0.6.0             labeling_0.4.3           fansi_1.0.6             
 [37] timechange_0.3.0         httr_1.4.7               compiler_4.4.0           bit64_4.0.5             
 [41] withr_3.0.0              backports_1.5.0          logger_0.3.0             MASS_7.3-60.2           
 [45] openssl_2.2.0            tools_4.4.0              admiraldev_1.1.0         zip_2.3.1               
 [49] httpuv_1.6.15            shinyvalidate_0.1.3      nlme_3.1-164             promises_1.3.0          
 [53] rsconnect_1.3.1          grid_4.4.0               checkmate_2.3.1          generics_0.1.3          
 [57] gtable_0.3.5             tzdb_0.4.0               data.table_1.15.4        RApiSerialize_0.1.3     
 [61] hms_1.1.3                xml2_1.3.6               stringfish_0.16.0        utf8_1.2.4              
 [65] ggrepel_0.9.5            pillar_1.9.0             later_1.3.2              splines_4.4.0           
 [69] tern.gee_0.1.4           lattice_0.22-6           renv_1.0.7               survival_3.5-8          
 [73] bit_4.0.5                tidyselect_1.2.1         knitr_1.48               gridExtra_2.3           
 [77] RcppCCTZ_0.2.12          shinydashboard_0.7.2     xfun_0.46                stringi_1.8.4           
 [81] shinybrowser_1.0.0       lazyeval_0.2.2           yaml_2.3.9               shinyWidgets_0.8.6      
 [85] evaluate_0.24.0          cli_3.6.3                RcppParallel_5.1.8       xtable_1.8-4            
 [89] systemfonts_1.1.0        Rdpack_2.6               munsell_0.5.1            jquerylib_0.1.4         
 [93] Rcpp_1.0.13              anytime_0.3.9            assertthat_0.2.1         blob_1.2.4              
 [97] viridisLite_0.4.2        mvtnorm_1.2-5            scales_1.3.0             crayon_1.5.3            
[101] rlang_1.1.4              rvest_1.0.4              nanotime_0.3.9 

OS

Melkiades commented 1 month ago

Thanks @kaipingyang for this. In principles, you should be able to achieve that and you should also be able to modify multiple values. Here the fixed behavior in a {rtables} example:

library(rtables)
#> Loading required package: formatters
#> 
#> Attaching package: 'formatters'
#> The following object is masked from 'package:base':
#> 
#>     %||%
#> Loading required package: magrittr
#> 
#> Attaching package: 'rtables'
#> The following object is masked from 'package:utils':
#> 
#>     str
my_fun <- function(x, ...) {
  rcell(c(1, NA, NA), format = "xx.x (xx.x - xx.x)", format_na_str = c("NE", "NU"))
}
basic_table() |> 
  analyze("A", afun = my_fun, format = "xx - xx") |> 
  build_table(tibble::tibble("A" = NA))
#>             all obs   
#> ——————————————————————
#> my_fun   1.0 (NE - NU)

Created on 2024-08-07 with reprex v2.1.1