Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,685 changes: 2,685 additions & 0 deletions _quarto_internal_scss_error.scss

Large diffs are not rendered by default.

Binary file modified inst/slides/img/final_table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inst/slides/img/table-with-goodies-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
825 changes: 381 additions & 444 deletions inst/slides/index.qmd

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions inst/slides/slides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ $font-family-sans-serif: "Google Sans", sans-serif;
text-decoration: underline;
}

.smaller {
font-size: 1.5rem;
}

.smallest {
font-size: 1rem;
}
Expand Down Expand Up @@ -103,3 +107,19 @@ code {
border: 1px solid #808080;
border-radius: 6px !important;
}

.smallest code {
padding: 1px !important;
}

.coloring {
color: black !important;
background-color: lightgray;
}

.reveal .col-45-55 div.column:first-child {
width: 45%;
}
.reveal .col-45-55 div.column:not(:first-child) {
width: 55%;
}
288 changes: 288 additions & 0 deletions inst/transcript.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@

## Title
 Good afternoon, RMed. My name is Kyle Grealis, and today I will show
how easy it is to use the sumExtras package for streamlining table
workflows in clinical research

## Intro
sumExtras is a R CRAN package created to enhance my workflows with gtsummary.
Now, I *love* gtsummary and it has been my go-to table-making package for a while now.
The output tables are elegant, clean and readable.
But oftentimes i would rewrite the same bits of code over and over.
And when you do that, we're advised it's best to write a function -- don't repeat yourself, right?
So I wrote a few wrapper functions. And then I was writing the same wrapper functions in multiple projects.
Ah yes, it was time to convert these repeatable lines of code to a package!
Simply put: sumExtras is a group of extra functions for using gtsummary tables.

## The plan [incremental]
Today we will learn:
* how to apply a JAMA-ready table style theme
* customize missing values using the clean table function
* learn the power of the extras function
* quickly apply automatic variable labeling
* group like-variables and [CLICK] apply font styling & background colors to those group headers
* We will do this while progressively building our code pipeline.

## What we'll build
The final table we build today will look like this, and I will demonstrate how to
reduce our lines of code while adding custom table styling bits throughout.
Let's offer bespoke tables to our colleagues and fellow stakeholders!

## Creating a summary table
The gtsummary package provides the trial dataset, complete with synthetic information
of 200 patients who received one of two treatment drugs. Notice the data is...
not what we normally receive!
Here we have complete records, but let's make this more real-world in order to
visualize other features available with sumExtras.

##
We'll begin by mutating our data, replacing the values for marker and grade [CLICK]
with zeroes and NA values when the treatment drug is B.
We'll save this as a new dataset, "dat". [CLICK]
Notice on line 17 the 0 and NA values for marker & grade, respectively.

## Initial gtsummary table
Our initial gtsummary table is packed with great output.
It's beautiful and has a clean font making it easily readable.
The statistics are nicely grouped and this immediately is a tremendous improvement
over shipping generic console output to your PIs.
We can begin to improve this table by

## Setting a theme
...setting a theme. I've often reached for the JAMA theme because it takes the
initial table and makes it nice and compact.
sumExtras provides the use_jama_theme function you can set once at the top of your
code to use for every table.
[CLICK]
You can see that this is nothing more than reducing how much code I needed to
remember... it's a wrapper around an existing gtsummary function.


## Cleaning the table
So we made a nicely-themed, more compact table.
However, we have zeros and missing values clogging up real estate.
[CLICK]
Let's set a goal to replace the all-zero and all-NA filled cells.
Perhaps we can remove some noise and direct the attention to the non-missingness
of our data.

## Cleaning the table
When we pipe our table code to clean_table, we replace the cells that have
mean & standard deviation values of all-zero or counts cells of zero with NA percentage
with a cleaner emdash.
This is a default replacement placeholder that you can adjust... you can even use an emoji if you'd like.
If you compare the left & right output for Drug B, I find that my attention is now drawn to what truly matters.
This effect is more noticeable with more amount of missingness.

## Adding labels...
This output is closer to our final table and more of what I want.
[CLICK]
The header "Characteristic" has been removed
[CLICK]
I've added a p-value column on the right of the table
[CLICK]
The variable labels and significant p-values are now bolded
[CLICK]
An Overall column has been added to the first output column position
[CLICK]
And lastly the clean table function has replace the noise of missingness
as we've just seen with clean table.

[quick pause]
[CLICK]
The same table was created with these code cells
all while replacing the bottom six lines of code on the left
[CLICK]
with one pipe to extras on the right!
Another feature of sumExtras is how we can reduce redundancies with labeling.

## Labeling hierarchy
Using gtsummary and sumExtras requires a small bit of understanding labeling hierarchy
[CLICK]
First, using gtsummary's label parameter ALWAYS wins
[CLICK]
Next, if our data contains variable label attributes, those are second in order
[CLICK]
Finally, sumExtras auto labeling is last.

## Default table without labels
Now, the trial dataset contains variable attributes.
However, let's explicitly add the word "ATTRIBUTE" to the age variable.
This will become more apparent as we continue.
Now, notice in the output on the right, the age has that big attribute.
[CLICK]
The variables marker and grade do not have any nice styled labels,
and that's because when we initially mutated our data on slide 6, label attributes
were stripped from marker and grade.

## The gtsummary::tbl_* labeling method
Labels set using the label parameter will always override attributes as
they are natively greater in the labeling hierarchy.
This action is native to gtsummary.
[CLICK]
Let's now also set the attribute for marker
[CLICK]
and also add the label parameter label for marker.
This will highlight the labeling hierarchy concept because notice
the output table. The variable label for marker is "marker label".
[CLICK]
Also, notice the variable grade still has no label since it does not have
a label attribute from the previous mutate nor was any label assigned in the
tbl_summary function.

## Creating a variable dictionary
We have one final labeling method at our disposal.
Let's create a dictionary object and add a very-visual "DICT" to our variable labels.
[CLICK]
The dictionary requires the variable and description columns.
[CLICK]
The dictionary object can exist with any case-insensitive version of the words
variable and description: lowercase, title case, or uppercase.
This can also be an object you import from Excel.

## Use the dictionary with add_auto_labels
We will continue with our explicit examples and add parameter labels within
the tbl_summary function.
I've added "label" here to all the variable labels to stress the understanding
of the labeling hierarchy.
[CLICK]
We then pipe this to add_auto_labels, but nothing changed in our table output.
There aren't any labels with the explicit DICT from the dictionary.
Why? Again, the labels set in the label parameter always take priority.

## Use the dictionary with add_auto_labels part 2
But we actually want the auto-labeling!
[CLICK]
We'll begin by commenting out many of the label parameter arguments
so add auto labels can work as intended.
Notice the output table now has "age from label" and
the DICT for grade originating from the dictionary object.
[pause]
If we look closely, marker has the attribute label that was set on slides 20.
T stage and the last 3 variables retained the label attributes from the
trial dataset that our dat dataset originated from.
We now have all three methods shown on one table: explicit labeling,
attributes, then sumExtras dictionary objects.

## Use the dictionary with add_auto_labels part 3
sumExtras offers some session options you can set at the beginning of your
table script or choose to include these in your Rprofile.
This will reset the hierarchy.
[CLICK]
The dictionary now takes precedence as the preferred or primary labeling method.
[CLICK]
And you no longer need to call the add auto labels function ONLY IF
[CLICK]
you use the extras function in the pipe. extras will find the dictionary
in your session environment and apply the labels automatically.

## Applying the dictionary
Kinda like magic, right? :)
First we set the options before we create the tables
Then just pipe to extras!
You'll now notice that the output on the right has the new labeling hierarchy
with DICT being displayed and nothing specifying attribute for age or marker.
I promise this will be clearer to you as you use it.
Or reach out and I will gladly give a hand.

## Grouping variables & adding color
Let's add grouping for like variables.
The trial data has demographic and clinical measures

## Group variables
We will use the gtsummary add variable group header and then pipe that to
[CLICK]
add group styling.
And what you get right outta the box with this is
[CLICK]
bold and italicized grouping labels and it restores left justified variable indentation.
What does that mean?!
Well, using add_variable group header without sumExtras' add group styling,
variable labels are indented 2 places and are vertically aligned with
the factor levels.
Add group styling removes that indent and restores left-justification.
A minor tweak but, to me, adds value...

## Add grouping colors
Especially when we add group colors.
[CLICK]
Since we have 2 variable groupings, we can set a color for each group header.
I chose to use each of the colors for the sumExtras logo.
The default color is a submission-worthy light gray, if you chose to omit the
color parameter & argument.
[CLICK]
Just note that add group colors will convert the table to a gt table.
So use this function as the last in your pipe, especially if you plan to add
more gtsummary functions in the pipe.

## Reduced code
OK, while building our table, we've greatly reduced the code.
[CLICK]
We've removed the need to write labels inside of the table summary function and
we've removed these extra gtsummary functions as well.
And this was all done by just applying this one simple extras function.
I hope you can see why I lead-in that this one line can be really powerful.
Our code was cut in half and that was just only for one table!

## And this is what we built
It's the same output that we were going for.
Less code, same result!

## extras parameters
Let's discuss the default parameters for extras.
gtsummary defaults are used where applicable while adding in some sumExtras
defaults as well.
You can decide if you want to show the p-value, remove the header label,
use the emdash for clean table or pass lists for your own extras overrides
or p-value styling
[CLICK]
gtsummary defaults the overall column position in the first column.
[CLICK]
sumExtras retains all default parameter arguments for add_overall & add_p functions

## .arg parameter
Here's how you can create reusable parameter overrides, if you wish.
[CLICK]
You can optionally create a list of default overrides for extras
[CLICK]
Let's set the p-value to false and last position to false
[CLICK]
And now set the .args parameter to use the extra args you've created.
Notice the table now does not have the p-value column and the overall column
is now in the far right location.

## .add_p_args
We can do a similar modification to our p-values
[CLICK]
Create a p args list where
the continuous variables age and marker use the t test
and the p value output is styled to 2 digits
[CLICK]
Add that argument to the .add p args parameter within extras

## Match gtsummary tables to gt tables
If you use both gtsummary and gt in the same report, sumExtras
has the
[CLICK]
theme_gt_compact function for gt tables.
This allows you to achieve the same compact output from the use jama theme
but for your gt tables!

## sumExtras supports..
Most of the gtsummary tables that you may use have either partial or Full feature
support from sumExtras.
Please check the documentation for both packages for more specifics,
or feel free to reach out to me if your tables require further customizations.

## Thank you

Thank you so much for choosing to spend your time with me today.
I really appreciate it.
You can find sumExtras on CRAN or from my GitHub repo.
The slides are live on my website: slides.kylegrealis.com/sumExtras
Do you love it, do you hate it, is the documentation wonky?
You can email me at kyle@kyleGrealis.com and I look forward to any feedback
you can provide!

And thank you for spending your time with me today and
enjoy the remainder of RMed 2026!
Loading