1

I want to produce a table of summary stats with summary_table. This needs to have subheadings.

I have been following this example: https://cran.r-project.org/web/packages/qwraps2/vignettes/summary-statistics.html

stats_summary1 <-
  list("Sex (female)" =
         list("number (%)" = ~ qwraps2::n_perc(.data$sex=="F", digits = 1)),
       "Age" =
         list("min" = ~ min(.data$age_d, digits = 1),
              "max" = ~ max(.data$age_d, digits = 1),
              "median (IQR)" = ~ qwraps2::median_iqr(.data$age_d, digits = 1)),
       "Disease" =
         list("A" = ~ qwraps2::n_perc(.data$d==1, digits = 1),
              "B" = ~ qwraps2::n_perc(.data$d==2, digits = 1),
              "C" = ~ qwraps2::n_perc(.data$d==3, digits = 1),
              "D" = ~ qwraps2::n_perc(.data$d==4, digits = 1),
              "E" = ~ qwraps2::n_perc(.data$d==5, digits = 1)),
       "Disease duration" =
         list("min" = ~ min(.data$dis_dur, digits = 1),
              "max" = ~ max(.data$dis_dur, digits = 1),
              "median (IQR)" = ~ qwraps2::median_iqr(.data$dis_dur, digits = 1)) 
    )
whole <- summary_table(df, stats_summary1)

The table output does not include the subheadings eg "Disease". It also produces the percentage with a forward slash as eg. 65\%

sar
  • 182
  • 6
  • 26

2 Answers2

1

First, I will create an example dataset to match the provided summary

set.seed(42)
df <- data.frame(sex     = sample(c("M", "F"), size = 100, replace = TRUE),
                 age_d   = runif(100, 18, 80),
                 d       = sample(1:5, size = 100, replace = TRUE),
                 dis_dur = runif(100, 20, 43),
                 stringsAsFactors = FALSE)
str(df)
#> 'data.frame':    100 obs. of  4 variables:
#>  $ sex    : chr  "M" "M" "M" "M" ...
#>  $ age_d  : num  56.8 31.5 31.4 42.1 76.4 ...
#>  $ d      : int  2 1 4 3 5 2 4 2 3 2 ...
#>  $ dis_dur: num  33.3 21.7 23.8 37 30.9 ...

load and attach the qwraps2 namespace

library(qwraps2)

by default qwraps2 formats output in LaTeX. To have the default switched to markdown set the following option

options(qwraps2_markup = "markdown")

Update: as of version 0.5.0 of qwraps2, the use of the .data pronoun is no longer needed or recommended.

stats_summary1 <-
  list("Sex (female)" =
         list("number (%)" = ~ qwraps2::n_perc(sex=="F", digits = 1)),
       "Age" =
         list("min" = ~ min(age_d, digits = 1),
              "max" = ~ max(age_d, digits = 1),
              "median (IQR)" = ~ qwraps2::median_iqr(age_d, digits = 1)),
       "Disease" =
         list("A" = ~ qwraps2::n_perc(d==1, digits = 1),
              "B" = ~ qwraps2::n_perc(d==2, digits = 1),
              "C" = ~ qwraps2::n_perc(d==3, digits = 1),
              "D" = ~ qwraps2::n_perc(d==4, digits = 1),
              "E" = ~ qwraps2::n_perc(d==5, digits = 1)),
       "Disease duration" =
         list("min" = ~ min(dis_dur, digits = 1),
              "max" = ~ max(dis_dur, digits = 1),
              "median (IQR)" = ~ qwraps2::median_iqr(dis_dur, digits = 1)) 
    )
whole <- summary_table(df, stats_summary1)
whole
#> 
#> 
#> |                          |df (N = 100)      |
#> |:-------------------------|:-----------------|
#> |**Sex (female)**          |&nbsp;&nbsp;      |
#> |&nbsp;&nbsp; number (%)   |56 (56.0%)        |
#> |**Age**                   |&nbsp;&nbsp;      |
#> |&nbsp;&nbsp; min          |1                 |
#> |&nbsp;&nbsp; max          |77.6816968536004  |
#> |&nbsp;&nbsp; median (IQR) |52.8 (33.7, 64.8) |
#> |**Disease**               |&nbsp;&nbsp;      |
#> |&nbsp;&nbsp; A            |26 (26.0%)        |
#> |&nbsp;&nbsp; B            |20 (20.0%)        |
#> |&nbsp;&nbsp; C            |15 (15.0%)        |
#> |&nbsp;&nbsp; D            |21 (21.0%)        |
#> |&nbsp;&nbsp; E            |18 (18.0%)        |
#> |**Disease duration**      |&nbsp;&nbsp;      |
#> |&nbsp;&nbsp; min          |1                 |
#> |&nbsp;&nbsp; max          |42.5464100171812  |
#> |&nbsp;&nbsp; median (IQR) |31.0 (25.1, 35.8) |

This sould resolve the issue with the forward slash on the percentage sign (needed escape for LaTeX). Make sure you have the results = "asis" chunk option set so the table will render nicely in your final document.

As for the omitted subheadings, the qwraps2_summary_table object is a character matrix with the class attribute set accordingly and has the additional attribute rgroups which is used by the printing methods to format the output correctly.

str(whole)
#>  'qwraps2_summary_table' chr [1:12, 1] "56 (56.0%)" "1" "77.6816968536004" ...
#>  - attr(*, "dimnames")=List of 2
#>   ..$ : chr [1:12] "number (%)" "min" "max" "median (IQR)" ...
#>   ..$ : chr "df (N = 100)"
#>  - attr(*, "rgroups")= Named int [1:4] 1 3 5 3
#>   ..- attr(*, "names")= chr [1:4] "Sex (female)" "Age" "Disease" "Disease duration"
#>  - attr(*, "n")= int 100

Created on 2020-09-14 by the reprex package (v0.3.0)

devtools::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 4.0.2 (2020-06-22)
#>  os       macOS Catalina 10.15.6      
#>  system   x86_64, darwin17.0          
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       America/Denver              
#>  date     2020-09-14                  
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.0.0)
#>  backports     1.1.9   2020-08-24 [1] CRAN (R 4.0.2)
#>  callr         3.4.4   2020-09-07 [1] CRAN (R 4.0.2)
#>  cli           2.0.2   2020-02-28 [1] CRAN (R 4.0.0)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 4.0.0)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 4.0.0)
#>  devtools      2.3.1   2020-07-21 [1] CRAN (R 4.0.2)
#>  digest        0.6.25  2020-02-23 [1] CRAN (R 4.0.0)
#>  ellipsis      0.3.1   2020-05-15 [1] CRAN (R 4.0.0)
#>  evaluate      0.14    2019-05-28 [1] CRAN (R 4.0.0)
#>  fansi         0.4.1   2020-01-08 [1] CRAN (R 4.0.0)
#>  fs            1.5.0   2020-07-31 [1] CRAN (R 4.0.2)
#>  glue          1.4.2   2020-08-27 [1] CRAN (R 4.0.2)
#>  highr         0.8     2019-03-20 [1] CRAN (R 4.0.0)
#>  htmltools     0.5.0   2020-06-16 [1] CRAN (R 4.0.0)
#>  knitr         1.29    2020-06-23 [1] CRAN (R 4.0.0)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 4.0.0)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 4.0.0)
#>  pkgbuild      1.1.0   2020-07-13 [1] CRAN (R 4.0.2)
#>  pkgload       1.1.0   2020-05-29 [1] CRAN (R 4.0.0)
#>  prettyunits   1.1.1   2020-01-24 [1] CRAN (R 4.0.0)
#>  processx      3.4.4   2020-09-03 [1] CRAN (R 4.0.2)
#>  ps            1.3.4   2020-08-11 [1] CRAN (R 4.0.2)
#>  qwraps2     * 0.5.0   2020-08-31 [1] local         
#>  R6            2.4.1   2019-11-12 [1] CRAN (R 4.0.0)
#>  Rcpp          1.0.5   2020-07-06 [1] CRAN (R 4.0.0)
#>  remotes       2.2.0   2020-07-21 [1] CRAN (R 4.0.2)
#>  rlang         0.4.7   2020-07-09 [1] CRAN (R 4.0.2)
#>  rmarkdown     2.3     2020-06-18 [1] CRAN (R 4.0.0)
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 4.0.0)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 4.0.0)
#>  stringi       1.5.3   2020-09-09 [1] CRAN (R 4.0.2)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 4.0.0)
#>  testthat      2.3.2   2020-03-02 [1] CRAN (R 4.0.0)
#>  usethis       1.6.1   2020-04-29 [1] CRAN (R 4.0.0)
#>  withr         2.2.0   2020-04-20 [1] CRAN (R 4.0.0)
#>  xfun          0.17    2020-09-09 [1] CRAN (R 4.0.2)
#>  yaml          2.2.1   2020-02-01 [1] CRAN (R 4.0.0)
#> 
#> [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
Peter
  • 7,460
  • 2
  • 47
  • 68
0

Your example is not really reproducible since you data is is not provided.

What worked for me was the following:

  • Instead of using the summary statistics arguments from qwraps2, I use the ones from the carpenter package. This is because in PDF documents rendered through the bookdown package, qwraps2::mean_sd() renders the "±" sign as &plusmn; in the table. Instead, carpenter::stat_meanSD() avoids the "±" sign and uses brackets for the SD instead. You could do another workaround with paste() though if you prefer the "±" sign.

  • The fact that qwraps2 is ignoring the top-level headings like Sex (female), Age etc. in your example is very annoying. My workaround here is to manually re-introduce these headings through the kableExtra package. In you example this would be something like this:

.

options(qwraps2_markup = "markdown")

summary_table(df, stats_summary1) %>%
kableExtra::pack_rows("Sex (female)", 1, 1) %>%
kableExtra::pack_rows("Age", 2, 4) %>% 
kableExtra::pack_rows("Disease", 5, 9) %>% 
kableExtra::pack_rows("Disease duration", 10, 12)
Frederick
  • 810
  • 8
  • 28