Sorting a frequency distribution table with tbl_summary()

Describe your issue

Hello everyone! I’m trying to create a frequency distribution table for the symptoms experienced by cases diagnosed with acute gastroenteritis. Symptoms are recorded as either present (1) or absent (0), with one column per symptom. I was able to create a table, however I could not get it to sort from the most common symptom (Watery Diarrhea, 100%) to the least common symptom (Bloody Diarrhea, 0%).

Also, is there anything wrong with how I generated the reprex? There seems to be some additional material between the rscript and the table output.

Looking forward to any assistance from the team.

Regards,
Ian

Provide an example of your R code

# reprex

pacman::p_load(tidyverse, gtsummary)

sx_table <- data.frame(
   symptoms_ap = c(0, 0, 0, 1, 1, 0, 0, 1, 1, 0),
   symptoms_na = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  symptoms_vom = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1),
  symptoms_awd = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
  symptoms_abd = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  symptoms_fev = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
)


sx_summary <- sx_table %>% 
  tbl_summary(
    sort = list(everything() ~ "frequency"),
    label = list(
      symptoms_ap~"Abdominal Pain",
      symptoms_na~"Nausea",
      symptoms_vom~"Vomiting",
      symptoms_awd~"Watery Diarrhea",
      symptoms_abd~"Bloody Diarrhea",
      symptoms_fev~"Fever"),
    missing = "no")

sx_summary
html { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif; }

#dtxudauofh .gt_table {
display: table;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
color: #333333;
font-size: 16px;
font-weight: normal;
font-style: normal;
background-color: #FFFFFF;
width: auto;
border-top-style: solid;
border-top-width: 2px;
border-top-color: #A8A8A8;
border-right-style: none;
border-right-width: 2px;
border-right-color: #D3D3D3;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #A8A8A8;
border-left-style: none;
border-left-width: 2px;
border-left-color: #D3D3D3;
}

#dtxudauofh .gt_heading {
background-color: #FFFFFF;
text-align: center;
border-bottom-color: #FFFFFF;
border-left-style: none;
border-left-width: 1px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 1px;
border-right-color: #D3D3D3;
}

#dtxudauofh .gt_caption {
padding-top: 4px;
padding-bottom: 4px;
}

#dtxudauofh .gt_title {
color: #333333;
font-size: 125%;
font-weight: initial;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 5px;
padding-right: 5px;
border-bottom-color: #FFFFFF;
border-bottom-width: 0;
}

#dtxudauofh .gt_subtitle {
color: #333333;
font-size: 85%;
font-weight: initial;
padding-top: 0;
padding-bottom: 6px;
padding-left: 5px;
padding-right: 5px;
border-top-color: #FFFFFF;
border-top-width: 0;
}

#dtxudauofh .gt_bottom_border {
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
}

#dtxudauofh .gt_col_headings {
border-top-style: solid;
border-top-width: 2px;
border-top-color: #D3D3D3;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
border-left-style: none;
border-left-width: 1px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 1px;
border-right-color: #D3D3D3;
}

#dtxudauofh .gt_col_heading {
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: normal;
text-transform: inherit;
border-left-style: none;
border-left-width: 1px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 1px;
border-right-color: #D3D3D3;
vertical-align: bottom;
padding-top: 5px;
padding-bottom: 6px;
padding-left: 5px;
padding-right: 5px;
overflow-x: hidden;
}

#dtxudauofh .gt_column_spanner_outer {
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: normal;
text-transform: inherit;
padding-top: 0;
padding-bottom: 0;
padding-left: 4px;
padding-right: 4px;
}

#dtxudauofh .gt_column_spanner_outer:first-child {
padding-left: 0;
}

#dtxudauofh .gt_column_spanner_outer:last-child {
padding-right: 0;
}

#dtxudauofh .gt_column_spanner {
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
vertical-align: bottom;
padding-top: 5px;
padding-bottom: 5px;
overflow-x: hidden;
display: inline-block;
width: 100%;
}

#dtxudauofh .gt_group_heading {
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: initial;
text-transform: inherit;
border-top-style: solid;
border-top-width: 2px;
border-top-color: #D3D3D3;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
border-left-style: none;
border-left-width: 1px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 1px;
border-right-color: #D3D3D3;
vertical-align: middle;
text-align: left;
}

#dtxudauofh .gt_empty_group_heading {
padding: 0.5px;
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: initial;
border-top-style: solid;
border-top-width: 2px;
border-top-color: #D3D3D3;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
vertical-align: middle;
}

#dtxudauofh .gt_from_md > :first-child {
margin-top: 0;
}

#dtxudauofh .gt_from_md > :last-child {
margin-bottom: 0;
}

#dtxudauofh .gt_row {
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
margin: 10px;
border-top-style: solid;
border-top-width: 1px;
border-top-color: #D3D3D3;
border-left-style: none;
border-left-width: 1px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 1px;
border-right-color: #D3D3D3;
vertical-align: middle;
overflow-x: hidden;
}

#dtxudauofh .gt_stub {
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: initial;
text-transform: inherit;
border-right-style: solid;
border-right-width: 2px;
border-right-color: #D3D3D3;
padding-left: 5px;
padding-right: 5px;
}

#dtxudauofh .gt_stub_row_group {
color: #333333;
background-color: #FFFFFF;
font-size: 100%;
font-weight: initial;
text-transform: inherit;
border-right-style: solid;
border-right-width: 2px;
border-right-color: #D3D3D3;
padding-left: 5px;
padding-right: 5px;
vertical-align: top;
}

#dtxudauofh .gt_row_group_first td {
border-top-width: 2px;
}

#dtxudauofh .gt_summary_row {
color: #333333;
background-color: #FFFFFF;
text-transform: inherit;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
}

#dtxudauofh .gt_first_summary_row {
border-top-style: solid;
border-top-color: #D3D3D3;
}

#dtxudauofh .gt_first_summary_row.thick {
border-top-width: 2px;
}

#dtxudauofh .gt_last_summary_row {
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
}

#dtxudauofh .gt_grand_summary_row {
color: #333333;
background-color: #FFFFFF;
text-transform: inherit;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
}

#dtxudauofh .gt_first_grand_summary_row {
padding-top: 8px;
padding-bottom: 8px;
padding-left: 5px;
padding-right: 5px;
border-top-style: double;
border-top-width: 6px;
border-top-color: #D3D3D3;
}

#dtxudauofh .gt_striped {
background-color: rgba(128, 128, 128, 0.05);
}

#dtxudauofh .gt_table_body {
border-top-style: solid;
border-top-width: 2px;
border-top-color: #D3D3D3;
border-bottom-style: solid;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
}

#dtxudauofh .gt_footnotes {
color: #333333;
background-color: #FFFFFF;
border-bottom-style: none;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
border-left-style: none;
border-left-width: 2px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 2px;
border-right-color: #D3D3D3;
}

#dtxudauofh .gt_footnote {
margin: 0px;
font-size: 90%;
padding-left: 4px;
padding-right: 4px;
padding-left: 5px;
padding-right: 5px;
}

#dtxudauofh .gt_sourcenotes {
color: #333333;
background-color: #FFFFFF;
border-bottom-style: none;
border-bottom-width: 2px;
border-bottom-color: #D3D3D3;
border-left-style: none;
border-left-width: 2px;
border-left-color: #D3D3D3;
border-right-style: none;
border-right-width: 2px;
border-right-color: #D3D3D3;
}

#dtxudauofh .gt_sourcenote {
font-size: 90%;
padding-top: 4px;
padding-bottom: 4px;
padding-left: 5px;
padding-right: 5px;
}

#dtxudauofh .gt_left {
text-align: left;
}

#dtxudauofh .gt_center {
text-align: center;
}

#dtxudauofh .gt_right {
text-align: right;
font-variant-numeric: tabular-nums;
}

#dtxudauofh .gt_font_normal {
font-weight: normal;
}

#dtxudauofh .gt_font_bold {
font-weight: bold;
}

#dtxudauofh .gt_font_italic {
font-style: italic;
}

#dtxudauofh .gt_super {
font-size: 65%;
}

#dtxudauofh .gt_footnote_marks {
font-style: italic;
font-weight: normal;
font-size: 75%;
vertical-align: 0.4em;
}

#dtxudauofh .gt_asterisk {
font-size: 100%;
vertical-align: 0;
}

#dtxudauofh .gt_indent_1 {
text-indent: 5px;
}

#dtxudauofh .gt_indent_2 {
text-indent: 10px;
}

#dtxudauofh .gt_indent_3 {
text-indent: 15px;
}

#dtxudauofh .gt_indent_4 {
text-indent: 20px;
}

#dtxudauofh .gt_indent_5 {
text-indent: 25px;
}

Characteristic N = 101
Abdominal Pain 4 (40%)
Nausea 0 (0%)
Vomiting 9 (90%)
Watery Diarrhea 10 (100%)
Bloody Diarrhea 0 (0%)
Fever 1 (10%)
1 n (%)

Created on 2023-03-04 with reprex v2.0.2

Session info
sessionInfo()
#> R version 4.2.2 (2022-10-31 ucrt)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 22621)
#> 
#> Matrix products: default
#> 
#> locale:
#> [1] LC_COLLATE=English_Philippines.utf8  LC_CTYPE=English_Philippines.utf8   
#> [3] LC_MONETARY=English_Philippines.utf8 LC_NUMERIC=C                        
#> [5] LC_TIME=English_Philippines.utf8    
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] gtsummary_1.7.0 forcats_1.0.0   stringr_1.5.0   dplyr_1.0.10   
#>  [5] purrr_1.0.1     readr_2.1.3     tidyr_1.2.1     tibble_3.1.8   
#>  [9] ggplot2_3.4.0   tidyverse_1.3.2
#> 
#> loaded via a namespace (and not attached):
#>  [1] lubridate_1.9.0      assertthat_0.2.1     digest_0.6.31       
#>  [4] utf8_1.2.2           R6_2.5.1             cellranger_1.1.0    
#>  [7] backports_1.4.1      reprex_2.0.2         evaluate_0.19       
#> [10] httr_1.4.4           highr_0.10           pillar_1.8.1        
#> [13] rlang_1.0.6          googlesheets4_1.0.1  readxl_1.4.1        
#> [16] rstudioapi_0.14      rmarkdown_2.19       googledrive_2.0.0   
#> [19] munsell_0.5.0        broom_1.0.2          compiler_4.2.2      
#> [22] modelr_0.1.10        xfun_0.36            pkgconfig_2.0.3     
#> [25] htmltools_0.5.4      tidyselect_1.2.0     fansi_1.0.3         
#> [28] crayon_1.5.2         tzdb_0.3.0           dbplyr_2.3.0        
#> [31] withr_2.5.0          commonmark_1.8.1     grid_4.2.2          
#> [34] jsonlite_1.8.4       gtable_0.3.1         lifecycle_1.0.3     
#> [37] DBI_1.1.3            pacman_0.5.1         magrittr_2.0.3      
#> [40] scales_1.2.1         cli_3.6.0            stringi_1.7.12      
#> [43] broom.helpers_1.12.0 fs_1.5.2             xml2_1.3.3          
#> [46] ellipsis_0.3.2       generics_0.1.3       vctrs_0.5.1         
#> [49] tools_4.2.2          glue_1.6.2           hms_1.1.2           
#> [52] fastmap_1.1.0        yaml_2.3.6           timechange_0.2.0    
#> [55] colorspace_2.0-3     gargle_1.2.1         gt_0.8.0            
#> [58] rvest_1.0.3          knitr_1.41           haven_2.5.1         
#> [61] sass_0.4.4
1 Like

Hi Ian,

I can’t find any built in functionality for gtsummary to achieve this, however, I have come up with a bit of a workaround where I calculated the proportion by symptom, ordered them in a descending order, and then selected the variables with respect to that order.

library(tidyverse)

sx_table <- tibble(
    symptoms_ap = c(0, 0, 0, 1, 1, 0, 0, 1, 1, 0),
    symptoms_na = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_vom = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1),
    symptoms_awd = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    symptoms_abd = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_fev = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
)

variable_order <-
    sx_table |>
summarize(across(everything(), mean)) |>
    pivot_longer(col = everything(),
                             names_to  = "symptom",
                             values_to = "present") |>
arrange(-present) |>
pull(symptom)

sx_table |>
    select(all_of(variable_order)) |>
    gtsummary::tbl_summary(
        label = list(
            symptoms_ap ~ "Abdominal Pain",
            symptoms_na ~ "Nausea",
            symptoms_vom ~ "Vomiting",
            symptoms_awd ~ "Watery Diarrhea",
            symptoms_abd ~ "Bloody Diarrhea",
            symptoms_fev ~ "Fever"
        ),
        missing = "no"
    )
Characteristic N = 101
Watery Diarrhea 10 (100%)
Vomiting 9 (90%)
Abdominal Pain 4 (40%)
Fever 1 (10%)
Nausea 0 (0%)
Bloody Diarrhea 0 (0%)
1 n (%)

Created on 2023-03-04 with reprex v2.0.2

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.2 (2022-10-31)
#>  os       macOS Big Sur ... 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       America/Toronto
#>  date     2023-03-04
#>  pandoc   2.19.2 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package       * version date (UTC) lib source
#>  broom.helpers   1.12.0  2023-02-09 [1] CRAN (R 4.2.2)
#>  cli             3.6.0   2023-01-09 [1] CRAN (R 4.2.2)
#>  colorspace      2.1-0   2023-01-23 [1] CRAN (R 4.2.0)
#>  commonmark      1.8.1   2022-10-14 [1] CRAN (R 4.2.0)
#>  digest          0.6.31  2022-12-11 [1] CRAN (R 4.2.0)
#>  dplyr         * 1.1.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  ellipsis        0.3.2   2021-04-29 [1] CRAN (R 4.2.0)
#>  evaluate        0.20    2023-01-17 [1] CRAN (R 4.2.0)
#>  fansi           1.0.4   2023-01-22 [1] CRAN (R 4.2.0)
#>  fastmap         1.1.0   2021-01-25 [1] CRAN (R 4.2.0)
#>  forcats       * 1.0.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  fs              1.6.1   2023-02-06 [1] CRAN (R 4.2.0)
#>  generics        0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
#>  ggplot2       * 3.4.1   2023-02-10 [1] CRAN (R 4.2.2)
#>  glue            1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
#>  gt              0.8.0   2022-11-16 [1] CRAN (R 4.2.0)
#>  gtable          0.3.1   2022-09-01 [1] RSPM (R 4.2.1)
#>  gtsummary       1.7.0   2023-01-13 [1] CRAN (R 4.2.0)
#>  hms             1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  htmltools       0.5.4   2022-12-07 [1] CRAN (R 4.2.0)
#>  knitr           1.42    2023-01-25 [1] CRAN (R 4.2.0)
#>  lifecycle       1.0.3   2022-10-07 [1] CRAN (R 4.2.1)
#>  lubridate     * 1.9.2   2023-02-10 [1] CRAN (R 4.2.2)
#>  magrittr        2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
#>  munsell         0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
#>  pillar          1.8.1   2022-08-19 [1] RSPM (R 4.2.1)
#>  pkgconfig       2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
#>  purrr         * 1.0.1   2023-01-10 [1] CRAN (R 4.2.2)
#>  R.cache         0.16.0  2022-07-21 [1] CRAN (R 4.2.0)
#>  R.methodsS3     1.8.2   2022-06-13 [1] CRAN (R 4.2.0)
#>  R.oo            1.25.0  2022-06-12 [1] CRAN (R 4.2.0)
#>  R.utils         2.12.2  2022-11-11 [1] CRAN (R 4.2.0)
#>  R6              2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
#>  readr         * 2.1.4   2023-02-10 [1] CRAN (R 4.2.2)
#>  reprex          2.0.2   2022-08-17 [1] RSPM (R 4.2.1)
#>  rlang           1.0.6   2022-09-24 [1] CRAN (R 4.2.0)
#>  rmarkdown       2.20    2023-01-19 [1] CRAN (R 4.2.0)
#>  rstudioapi      0.14    2022-08-22 [1] RSPM (R 4.2.1)
#>  sass            0.4.5   2023-01-24 [1] CRAN (R 4.2.0)
#>  scales          1.2.1   2022-08-20 [1] RSPM (R 4.2.1)
#>  sessioninfo     1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
#>  stringi         1.7.12  2023-01-11 [1] CRAN (R 4.2.2)
#>  stringr       * 1.5.0   2022-12-02 [1] CRAN (R 4.2.0)
#>  styler          1.9.0   2023-01-15 [1] CRAN (R 4.2.0)
#>  tibble        * 3.1.8   2022-07-22 [1] CRAN (R 4.2.1)
#>  tidyr         * 1.3.0   2023-01-24 [1] CRAN (R 4.2.0)
#>  tidyselect      1.2.0   2022-10-10 [1] CRAN (R 4.2.0)
#>  tidyverse     * 2.0.0   2023-02-22 [1] CRAN (R 4.2.2)
#>  timechange      0.2.0   2023-01-11 [1] CRAN (R 4.2.2)
#>  tzdb            0.3.0   2022-03-28 [1] CRAN (R 4.2.0)
#>  utf8            1.2.3   2023-01-31 [1] CRAN (R 4.2.2)
#>  vctrs           0.5.2   2023-01-23 [1] CRAN (R 4.2.0)
#>  withr           2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
#>  xfun            0.37    2023-01-31 [1] CRAN (R 4.2.0)
#>  yaml            2.3.7   2023-01-23 [1] CRAN (R 4.2.0)
#> 
#>  [1] /Users/timothychisamore/Library/R/x86_64/4.2/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────

All the best,

Tim

This works great! Thank you for the quick response, Tim!

All the best,
Ian

1 Like

Hi again! It seems that gtsummary tables are not very customizable for presentation. Is there an alternative approach, perhaps using flextable, to have the same output but have the ability to modify table headers?

1 Like

Hi Ian,

I’m not as familiar with the flextable or reactable packages but I know people do often use them. I will take a look later today when I can to see if there is anything there.

Alternatively, have you considered using the gt package? I’ve found there is a lot of room for customization and I believe there is a relationship between the gt and gtsummary packages.

All the best,

Tim

Hi Tim, I have not tried the gt package but I will look into it and post here if I find a solution. Thank you!

Best,
Ian

1 Like

Hi Ian,

You could do something like this with gt:

library(tidyverse)
library(gt)

sx_table <- tibble(
    symptoms_ap = c(0, 0, 0, 1, 1, 0, 0, 1, 1, 0),
    symptoms_na = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_vom = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1),
    symptoms_awd = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    symptoms_abd = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_fev = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
)

long_props_data <- sx_table |>
    summarize(across(.cols = everything(), .fns = mean)) |>
    pivot_longer(col = everything(),
                             names_to  = "symptom",
                             values_to = "present") |>
    arrange(desc(present))

gt(data = long_props_data) |>
    cols_label(symptom = "Symptom",
                         present = "Percentage (%)") |>
    fmt(columns = symptom,
            fns = \(x) {
                case_match(
                    x,
                    "symptoms_ap" ~ "Abdominal Pain",
                    "symptoms_na" ~ "Nausea",
                    "symptoms_vom" ~ "Vomiting",
                    "symptoms_awd" ~ "Watery Diarrhea",
                    "symptoms_abd" ~ "Bloody Diarrhea",
                    "symptoms_fev" ~ "Fever"
                )
            }) |>
    fmt_percent(columns = present, decimals = 0)

Symptom Percentage (%)
Watery Diarrhea 100%
Vomiting 90%
Abdominal Pain 40%
Fever 10%
Nausea 0%
Bloody Diarrhea 0%

Created on 2023-03-05 with reprex v2.0.2

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.2 (2022-10-31)
#>  os       macOS Big Sur ... 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       America/Toronto
#>  date     2023-03-05
#>  pandoc   2.19.2 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  cli           3.6.0   2023-01-09 [1] CRAN (R 4.2.2)
#>  colorspace    2.1-0   2023-01-23 [1] CRAN (R 4.2.0)
#>  digest        0.6.31  2022-12-11 [1] CRAN (R 4.2.0)
#>  dplyr       * 1.1.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  ellipsis      0.3.2   2021-04-29 [1] CRAN (R 4.2.0)
#>  evaluate      0.20    2023-01-17 [1] CRAN (R 4.2.0)
#>  fansi         1.0.4   2023-01-22 [1] CRAN (R 4.2.0)
#>  fastmap       1.1.0   2021-01-25 [1] CRAN (R 4.2.0)
#>  forcats     * 1.0.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  fs            1.6.1   2023-02-06 [1] CRAN (R 4.2.0)
#>  generics      0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
#>  ggplot2     * 3.4.1   2023-02-10 [1] CRAN (R 4.2.2)
#>  glue          1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
#>  gt          * 0.8.0   2022-11-16 [1] CRAN (R 4.2.0)
#>  gtable        0.3.1   2022-09-01 [1] RSPM (R 4.2.1)
#>  hms           1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  htmltools     0.5.4   2022-12-07 [1] CRAN (R 4.2.0)
#>  knitr         1.42    2023-01-25 [1] CRAN (R 4.2.0)
#>  lifecycle     1.0.3   2022-10-07 [1] CRAN (R 4.2.1)
#>  lubridate   * 1.9.2   2023-02-10 [1] CRAN (R 4.2.2)
#>  magrittr      2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
#>  pillar        1.8.1   2022-08-19 [1] RSPM (R 4.2.1)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
#>  purrr       * 1.0.1   2023-01-10 [1] CRAN (R 4.2.2)
#>  R.cache       0.16.0  2022-07-21 [1] CRAN (R 4.2.0)
#>  R.methodsS3   1.8.2   2022-06-13 [1] CRAN (R 4.2.0)
#>  R.oo          1.25.0  2022-06-12 [1] CRAN (R 4.2.0)
#>  R.utils       2.12.2  2022-11-11 [1] CRAN (R 4.2.0)
#>  R6            2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
#>  readr       * 2.1.4   2023-02-10 [1] CRAN (R 4.2.2)
#>  reprex        2.0.2   2022-08-17 [1] RSPM (R 4.2.1)
#>  rlang         1.0.6   2022-09-24 [1] CRAN (R 4.2.0)
#>  rmarkdown     2.20    2023-01-19 [1] CRAN (R 4.2.0)
#>  rstudioapi    0.14    2022-08-22 [1] RSPM (R 4.2.1)
#>  sass          0.4.5   2023-01-24 [1] CRAN (R 4.2.0)
#>  scales        1.2.1   2022-08-20 [1] RSPM (R 4.2.1)
#>  sessioninfo   1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
#>  stringi       1.7.12  2023-01-11 [1] CRAN (R 4.2.2)
#>  stringr     * 1.5.0   2022-12-02 [1] CRAN (R 4.2.0)
#>  styler        1.9.0   2023-01-15 [1] CRAN (R 4.2.0)
#>  tibble      * 3.1.8   2022-07-22 [1] CRAN (R 4.2.1)
#>  tidyr       * 1.3.0   2023-01-24 [1] CRAN (R 4.2.0)
#>  tidyselect    1.2.0   2022-10-10 [1] CRAN (R 4.2.0)
#>  tidyverse   * 2.0.0   2023-02-22 [1] CRAN (R 4.2.2)
#>  timechange    0.2.0   2023-01-11 [1] CRAN (R 4.2.2)
#>  tzdb          0.3.0   2022-03-28 [1] CRAN (R 4.2.0)
#>  utf8          1.2.3   2023-01-31 [1] CRAN (R 4.2.2)
#>  vctrs         0.5.2   2023-01-23 [1] CRAN (R 4.2.0)
#>  withr         2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
#>  xfun          0.37    2023-01-31 [1] CRAN (R 4.2.0)
#>  yaml          2.3.7   2023-01-23 [1] CRAN (R 4.2.0)
#> 
#>  [1] /Users/timothychisamore/Library/R/x86_64/4.2/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────

All the best,

Tim

Hi Tim! When I run the code, I get the following error: Error in vec_is_vector(x) : object β€˜x’ not found. Is this the x being referred to in fns = (x) and case_match(x ?

1 Like

Hi Ian,

It may be an issue with the version of R you are using, can you check with one you have? Typing R.version into the R console will let you know.

All the best,

Tim

Hi Tim,

I’m not sure what went wrong, but when I restarted R, the command executed properly.

Also, I tried to create a bar plot of the symptoms with the following command. However ggplot seems to count the number of observations rather than just the ones with the symptoms (i.e. only those with a value of 1). How do I get around this? Sorry, I’m not sure if I continue with this thread or start another topic.

sx_table_long <- sx_table %>% 
  pivot_longer(
    cols = starts_with("symptoms_"),
    names_to = "symptoms",
    values_to = "present")

# plot
ggplot(sx_table_long) +
  geom_bar(mapping = aes(y = symptoms))

Regards,
Ian

1 Like

Hi Ian,

In the future it would be best to open a separate thread. However, there is no need to this time, I will answer your question within.

Your code is counting both those records where the symptom is present and absent, i.e., there is a count of 10 for each symptom. I would recommend either filtering your data or filling by presence/absence.

library(tidyverse)
library(patchwork)

sx_table <- tibble(
    symptoms_ap = c(0, 0, 0, 1, 1, 0, 0, 1, 1, 0),
    symptoms_na = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_vom = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1),
    symptoms_awd = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    symptoms_abd = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_fev = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
)

sx_table_long <- sx_table %>%
    pivot_longer(
        cols = starts_with("symptoms_"),
        names_to = "symptoms",
        values_to = "present"
    )

# filtering
filter_method <- sx_table_long |>
    filter(present == 1) |>
    ggplot() +
    geom_bar(mapping = aes(y = symptoms)) +
    scale_x_continuous(
        breaks = scales::extended_breaks(),
        labels = scales::comma_format(accuracy = 1)
    ) +
    scale_y_discrete(
        labels = c(
            "symptoms_ap" = "Abdominal Pain",
            "symptoms_na" = "Nausea",
            "symptoms_vom" = "Vomiting",
            "symptoms_awd" = "Watery Diarrhea",
            "symptoms_abd" = "Bloody Diarrhea",
            "symptoms_fev" = "Fever"
        )
    ) +
    labs(x = "\nFrequency",
             y = "Symptom\n",
             title = "Filter method") +
    theme_minimal()

# filling
fill_method <- sx_table_long |>
    ggplot() +
    geom_bar(mapping = aes(
        y = symptoms,
        group = as.logical(present),
        fill = as.logical(present)
    )) +
    scale_x_continuous(
        breaks = scales::extended_breaks(),
        labels = scales::comma_format(accuracy = 1)
    ) +
    scale_y_discrete(
        labels = c(
            "symptoms_ap" = "Abdominal Pain",
            "symptoms_na" = "Nausea",
            "symptoms_vom" = "Vomiting",
            "symptoms_awd" = "Watery Diarrhea",
            "symptoms_abd" = "Bloody Diarrhea",
            "symptoms_fev" = "Fever"
        )
    ) +
    scale_fill_brewer(
        type = "qual",
        palette = "Set3",
        labels = c("TRUE" = "Yes", "FALSE" = "No")
    ) +
    labs(x = "\nFrequency",
             y = "Symptom\n",
             fill = "Presence",
             title = "Fill method") +
    theme_minimal()

filter_method + fill_method + plot_layout(ncol = 1)

Created on 2023-03-11 with reprex v2.0.2

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.2 (2022-10-31)
#>  os       macOS Big Sur ... 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       America/Toronto
#>  date     2023-03-11
#>  pandoc   2.19.2 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package      * version date (UTC) lib source
#>  cli            3.6.0   2023-01-09 [1] CRAN (R 4.2.2)
#>  colorspace     2.1-0   2023-01-23 [1] CRAN (R 4.2.0)
#>  curl           5.0.0   2023-01-12 [1] CRAN (R 4.2.0)
#>  digest         0.6.31  2022-12-11 [1] CRAN (R 4.2.0)
#>  dplyr        * 1.1.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  ellipsis       0.3.2   2021-04-29 [1] CRAN (R 4.2.0)
#>  evaluate       0.20    2023-01-17 [1] CRAN (R 4.2.0)
#>  fansi          1.0.4   2023-01-22 [1] CRAN (R 4.2.0)
#>  farver         2.1.1   2022-07-06 [1] CRAN (R 4.2.0)
#>  fastmap        1.1.1   2023-02-24 [1] CRAN (R 4.2.0)
#>  forcats      * 1.0.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  fs             1.6.1   2023-02-06 [1] CRAN (R 4.2.0)
#>  generics       0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
#>  ggplot2      * 3.4.1   2023-02-10 [1] CRAN (R 4.2.2)
#>  glue           1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
#>  gtable         0.3.1   2022-09-01 [1] RSPM (R 4.2.1)
#>  highr          0.10    2022-12-22 [1] CRAN (R 4.2.0)
#>  hms            1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  htmltools      0.5.4   2022-12-07 [1] CRAN (R 4.2.0)
#>  httr           1.4.5   2023-02-24 [1] CRAN (R 4.2.0)
#>  knitr          1.42    2023-01-25 [1] CRAN (R 4.2.0)
#>  labeling       0.4.2   2020-10-20 [1] CRAN (R 4.2.0)
#>  lifecycle      1.0.3   2022-10-07 [1] CRAN (R 4.2.1)
#>  lubridate    * 1.9.2   2023-02-10 [1] CRAN (R 4.2.2)
#>  magrittr       2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
#>  mime           0.12    2021-09-28 [1] CRAN (R 4.2.0)
#>  munsell        0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
#>  patchwork    * 1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  pillar         1.8.1   2022-08-19 [1] RSPM (R 4.2.1)
#>  pkgconfig      2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
#>  purrr        * 1.0.1   2023-01-10 [1] CRAN (R 4.2.2)
#>  R.cache        0.16.0  2022-07-21 [1] CRAN (R 4.2.0)
#>  R.methodsS3    1.8.2   2022-06-13 [1] CRAN (R 4.2.0)
#>  R.oo           1.25.0  2022-06-12 [1] CRAN (R 4.2.0)
#>  R.utils        2.12.2  2022-11-11 [1] CRAN (R 4.2.0)
#>  R6             2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
#>  RColorBrewer   1.1-3   2022-04-03 [1] CRAN (R 4.2.0)
#>  readr        * 2.1.4   2023-02-10 [1] CRAN (R 4.2.2)
#>  reprex         2.0.2   2022-08-17 [1] RSPM (R 4.2.1)
#>  rlang          1.0.6   2022-09-24 [1] CRAN (R 4.2.0)
#>  rmarkdown      2.20    2023-01-19 [1] CRAN (R 4.2.0)
#>  rstudioapi     0.14    2022-08-22 [1] RSPM (R 4.2.1)
#>  scales         1.2.1   2022-08-20 [1] RSPM (R 4.2.1)
#>  sessioninfo    1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
#>  stringi        1.7.12  2023-01-11 [1] CRAN (R 4.2.2)
#>  stringr      * 1.5.0   2022-12-02 [1] CRAN (R 4.2.0)
#>  styler         1.9.1   2023-03-04 [1] CRAN (R 4.2.0)
#>  tibble       * 3.1.8   2022-07-22 [1] CRAN (R 4.2.1)
#>  tidyr        * 1.3.0   2023-01-24 [1] CRAN (R 4.2.0)
#>  tidyselect     1.2.0   2022-10-10 [1] CRAN (R 4.2.0)
#>  tidyverse    * 2.0.0   2023-02-22 [1] CRAN (R 4.2.2)
#>  timechange     0.2.0   2023-01-11 [1] CRAN (R 4.2.2)
#>  tzdb           0.3.0   2022-03-28 [1] CRAN (R 4.2.0)
#>  utf8           1.2.3   2023-01-31 [1] CRAN (R 4.2.2)
#>  vctrs          0.5.2   2023-01-23 [1] CRAN (R 4.2.0)
#>  withr          2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
#>  xfun           0.37    2023-01-31 [1] CRAN (R 4.2.0)
#>  xml2           1.3.3   2021-11-30 [1] CRAN (R 4.2.0)
#>  yaml           2.3.7   2023-01-23 [1] CRAN (R 4.2.0)
#> 
#>  [1] /Users/timothychisamore/Library/R/x86_64/4.2/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────

All the best,

Tim

Thank you, Tim!

How would I sort the bar chart from most (at the top) to least (at the bottom) frequent symptoms?

Also, I noticed you used the {patchwork} package. Could you elaborate a little about what functions are used and how does that add to the {ggplot} in this case?

Best,
Ian

1 Like

Hi Ian,

In the future, if you could provide some attempt at a solution it would be beneficial as I could see how you are approaching the problem.

These are the two potential approaches I would use, note that patchwork is just an R package for combining plots into a single plot.

library(tidyverse)
library(patchwork)

sx_table <- tibble(
    symptoms_ap = c(0, 0, 0, 1, 1, 0, 0, 1, 1, 0),
    symptoms_na = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_vom = c(1, 1, 1, 1, 0, 1, 1, 1, 1, 1),
    symptoms_awd = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    symptoms_abd = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    symptoms_fev = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
)

sx_table_long <- sx_table %>%
    pivot_longer(
        cols = starts_with("symptoms_"),
        names_to = "symptoms",
        values_to = "present"
    )

# filtering
filter_method <- sx_table_long |>
    filter(present == 1) |>
    mutate(symptoms = fct_rev(f = fct_infreq(f = symptoms))) |>
    ggplot() +
    geom_bar(mapping = aes(y = symptoms)) +
    scale_x_continuous(
        breaks = scales::extended_breaks(),
        labels = scales::comma_format(accuracy = 1)
    ) +
    scale_y_discrete(
        labels = c(
            "symptoms_ap" = "Abdominal Pain",
            "symptoms_na" = "Nausea",
            "symptoms_vom" = "Vomiting",
            "symptoms_awd" = "Watery Diarrhea",
            "symptoms_abd" = "Bloody Diarrhea",
            "symptoms_fev" = "Fever"
        )
    ) +
    labs(x = "\nFrequency",
             y = "Symptom\n",
             title = "Filter method") +
    theme_minimal()

# filling
fill_method <- sx_table_long |>
    mutate(symptoms = fct_reorder(.f = symptoms, .x = present, .fun = mean)) |>
    ggplot() +
    geom_bar(mapping = aes(
        y = symptoms,
        group = as.logical(present),
        fill = as.logical(present)
    )) +
    scale_x_continuous(
        breaks = scales::extended_breaks(),
        labels = scales::comma_format(accuracy = 1)
    ) +
    scale_y_discrete(
        labels = c(
            "symptoms_ap" = "Abdominal Pain",
            "symptoms_na" = "Nausea",
            "symptoms_vom" = "Vomiting",
            "symptoms_awd" = "Watery Diarrhea",
            "symptoms_abd" = "Bloody Diarrhea",
            "symptoms_fev" = "Fever"
        )
    ) +
    scale_fill_brewer(
        type = "qual",
        palette = "Set3",
        labels = c("TRUE" = "Yes", "FALSE" = "No")
    ) +
    labs(x = "\nFrequency",
             y = "Symptom\n",
             fill = "Presence",
             title = "Fill method") +
    theme_minimal()

# combining plots into a single plot using patchwork
filter_method + fill_method + plot_layout(ncol = 1)

Created on 2023-03-12 with reprex v2.0.2

Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.2 (2022-10-31)
#>  os       macOS Big Sur ... 10.16
#>  system   x86_64, darwin17.0
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       America/Toronto
#>  date     2023-03-12
#>  pandoc   2.19.2 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/ (via rmarkdown)
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package      * version date (UTC) lib source
#>  cli            3.6.0   2023-01-09 [1] CRAN (R 4.2.2)
#>  colorspace     2.1-0   2023-01-23 [1] CRAN (R 4.2.0)
#>  curl           5.0.0   2023-01-12 [1] CRAN (R 4.2.0)
#>  digest         0.6.31  2022-12-11 [1] CRAN (R 4.2.0)
#>  dplyr        * 1.1.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  ellipsis       0.3.2   2021-04-29 [1] CRAN (R 4.2.0)
#>  evaluate       0.20    2023-01-17 [1] CRAN (R 4.2.0)
#>  fansi          1.0.4   2023-01-22 [1] CRAN (R 4.2.0)
#>  farver         2.1.1   2022-07-06 [1] CRAN (R 4.2.0)
#>  fastmap        1.1.1   2023-02-24 [1] CRAN (R 4.2.0)
#>  forcats      * 1.0.0   2023-01-29 [1] CRAN (R 4.2.2)
#>  fs             1.6.1   2023-02-06 [1] CRAN (R 4.2.0)
#>  generics       0.1.3   2022-07-05 [1] CRAN (R 4.2.0)
#>  ggplot2      * 3.4.1   2023-02-10 [1] CRAN (R 4.2.2)
#>  glue           1.6.2   2022-02-24 [1] CRAN (R 4.2.0)
#>  gtable         0.3.1   2022-09-01 [1] RSPM (R 4.2.1)
#>  highr          0.10    2022-12-22 [1] CRAN (R 4.2.0)
#>  hms            1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  htmltools      0.5.4   2022-12-07 [1] CRAN (R 4.2.0)
#>  httr           1.4.5   2023-02-24 [1] CRAN (R 4.2.0)
#>  knitr          1.42    2023-01-25 [1] CRAN (R 4.2.0)
#>  labeling       0.4.2   2020-10-20 [1] CRAN (R 4.2.0)
#>  lifecycle      1.0.3   2022-10-07 [1] CRAN (R 4.2.1)
#>  lubridate    * 1.9.2   2023-02-10 [1] CRAN (R 4.2.2)
#>  magrittr       2.0.3   2022-03-30 [1] CRAN (R 4.2.0)
#>  mime           0.12    2021-09-28 [1] CRAN (R 4.2.0)
#>  munsell        0.5.0   2018-06-12 [1] CRAN (R 4.2.0)
#>  patchwork    * 1.1.2   2022-08-19 [1] RSPM (R 4.2.1)
#>  pillar         1.8.1   2022-08-19 [1] RSPM (R 4.2.1)
#>  pkgconfig      2.0.3   2019-09-22 [1] CRAN (R 4.2.0)
#>  purrr        * 1.0.1   2023-01-10 [1] CRAN (R 4.2.2)
#>  R.cache        0.16.0  2022-07-21 [1] CRAN (R 4.2.0)
#>  R.methodsS3    1.8.2   2022-06-13 [1] CRAN (R 4.2.0)
#>  R.oo           1.25.0  2022-06-12 [1] CRAN (R 4.2.0)
#>  R.utils        2.12.2  2022-11-11 [1] CRAN (R 4.2.0)
#>  R6             2.5.1   2021-08-19 [1] CRAN (R 4.2.0)
#>  RColorBrewer   1.1-3   2022-04-03 [1] CRAN (R 4.2.0)
#>  readr        * 2.1.4   2023-02-10 [1] CRAN (R 4.2.2)
#>  reprex         2.0.2   2022-08-17 [1] RSPM (R 4.2.1)
#>  rlang          1.0.6   2022-09-24 [1] CRAN (R 4.2.0)
#>  rmarkdown      2.20    2023-01-19 [1] CRAN (R 4.2.0)
#>  rstudioapi     0.14    2022-08-22 [1] RSPM (R 4.2.1)
#>  scales         1.2.1   2022-08-20 [1] RSPM (R 4.2.1)
#>  sessioninfo    1.2.2   2021-12-06 [1] CRAN (R 4.2.0)
#>  stringi        1.7.12  2023-01-11 [1] CRAN (R 4.2.2)
#>  stringr      * 1.5.0   2022-12-02 [1] CRAN (R 4.2.0)
#>  styler         1.9.1   2023-03-04 [1] CRAN (R 4.2.0)
#>  tibble       * 3.1.8   2022-07-22 [1] CRAN (R 4.2.1)
#>  tidyr        * 1.3.0   2023-01-24 [1] CRAN (R 4.2.0)
#>  tidyselect     1.2.0   2022-10-10 [1] CRAN (R 4.2.0)
#>  tidyverse    * 2.0.0   2023-02-22 [1] CRAN (R 4.2.2)
#>  timechange     0.2.0   2023-01-11 [1] CRAN (R 4.2.2)
#>  tzdb           0.3.0   2022-03-28 [1] CRAN (R 4.2.0)
#>  utf8           1.2.3   2023-01-31 [1] CRAN (R 4.2.2)
#>  vctrs          0.5.2   2023-01-23 [1] CRAN (R 4.2.0)
#>  withr          2.5.0   2022-03-03 [1] CRAN (R 4.2.0)
#>  xfun           0.37    2023-01-31 [1] CRAN (R 4.2.0)
#>  xml2           1.3.3   2021-11-30 [1] CRAN (R 4.2.0)
#>  yaml           2.3.7   2023-01-23 [1] CRAN (R 4.2.0)
#> 
#>  [1] /Users/timothychisamore/Library/R/x86_64/4.2/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.2/Resources/library
#> 
#> ──────────────────────────────────────────────────────────────────────────────

All the best,

Tim

Thank you, Tim! This worked great! I’ll be sure to post attempted solutions in the future as well.

Regards,
Ian

1 Like