Gmisc collects utilities for the graphics and tables that recur in
medical research papers — built so they compose with the native R pipe
(|>):
- Descriptive “Table 1” —
getDescriptionStatsBy()+htmlTable()for publication-ready, copy-paste descriptive tables. - Grid-based flowcharts — a
flowchart() |> spread() |> move() |> connect()pipeline for CONSORT-style diagrams, includingphaseLabel()headings. - Transition plots — the
Transitionclass for visualising how observations move between categories over time. - SVD variable selection —
getSvdMostInfluential()for picking influential variables. - Bézier arrows — smooth arrows complementing the
gridpackage.
# From CRAN
install.packages("Gmisc")
# Development version from GitHub# install.packages("remotes")remotes::install_github("gforge/Gmisc")Build a flowchart as a named list of boxes, position the columns with
spread()/move(), then add the connectors. Parallel arms are just
lists, and phaseLabel() drops a CONSORT phase heading (“Allocation”,
“Follow-up”, …) between the arms — centred, slightly overlapping, and
drawn on top.
library(Gmisc)
library(grid)
main_gp<- gpar(fill="white", col="black", lwd=1)
head_gp<- gpar(fill="#c8daf7", col="#2f5f9f", lwd=1)
con_gp<- gpar(col="#4f86c6", fill="#4f86c6", lwd=1.8)
sw<- unit(70, "mm")
flowchart(
rando= boxGrob("Randomised\nN = 100", box_gp=main_gp),
groups=list(
boxGrob("Allocated to intervention\nn = 50", width=sw, box_gp=main_gp),
boxGrob("Allocated to control\nn = 50", width=sw, box_gp=main_gp)
),
followup=list(
boxGrob("Lost to follow-up\nn = 1", width=sw, box_gp=main_gp),
boxGrob("Lost to follow-up\nn = 2", width=sw, box_gp=main_gp)
),
analysis=list(
boxGrob("Analysed\nn = 49", width=sw, box_gp=main_gp),
boxGrob("Analysed\nn = 48", width=sw, box_gp=main_gp)
)
) |>
spread(axis="y", margin= unit(0.04, "npc")) |>
move(subelement=list(c("groups", 1), c("followup", 1), c("analysis", 1)), x=0.27) |>
move(subelement=list(c("groups", 2), c("followup", 2), c("analysis", 2)), x=0.73) |>
phaseLabel("groups", "Allocation", box_gp=head_gp) |>
phaseLabel("followup", "Follow-up", box_gp=head_gp) |>
phaseLabel("analysis", "Analysis", box_gp=head_gp) |>
connect("rando", "groups", type="N", lty_gp=con_gp, arrow_size=3, smooth=TRUE) |>
connect("groups", "followup", type="v", lty_gp=con_gp, arrow_size=3) |>
connect("followup", "analysis", type="v", lty_gp=con_gp, arrow_size=3)See vignette("Grid-based_flowcharts", package = "Gmisc") for the full
API.
getDescriptionStatsBy() summarises variables split by a grouping
column. It is often used with mergeDesc() to group related variables
into sections, and pipes straight into htmlTable() for a
publication-ready table.
library(dplyr)
library(Gmisc)
# A custom wrapper to keep statistics and formatting consistent# (e.g., same digits, p-values, and header count)get_stats<-function(data, ...) {
res<-data|>
getDescriptionStatsBy(...,
by=am,
statistics=TRUE,
digits=1,
header_count=TRUE)
if (is.list(res)) {
return(do.call(rbind, res))
}
return(res)
}
mtcars_prep<-mtcars|>
mutate(am=factor(am, labels= c("Automatic", "Manual")),
gear=factor(gear),
cyl=factor(cyl)) |>
set_column_labels(mpg="Gas",
wt="Weight",
hp="Horsepower",
cyl="Cylinders",
gear="Gears") |>
set_column_units(mpg="Miles/gallon",
wt="10<sup>3</sup> lbs",
hp="hp")
# Group variables and merge them into a single table
mergeDesc(
"Main"=mtcars_prep|> get_stats(mpg, wt),
"Engine"=mtcars_prep|> get_stats(hp, cyl),
"Transmission"=mtcars_prep|> get_stats(gear)
) |>
htmlTable(caption="Baseline characteristics by transmission",
tfoot="† Statistics: Mean (SD) for continuous; n (%) for categorical")See vignette("Descriptives", package = "Gmisc") for the many
formatting options.
The Transition class shows how observations move between classes over
time; a third dimension can be encoded as a colour split within each
box.
set.seed(1)
n<-100sex<- sample(c("Male", "Female"), n, replace=TRUE)
before<- sample(1:3, n, replace=TRUE)
# Most cases improve one class, some stay, a few worsenafter<- pmin(pmax(before- sample(c(-1, 0, 1), n, replace=TRUE, prob= c(.15, .35, .5)), 1), 3)
lbl<- c("A", "B", "C")
tbl<- table(factor(before, 1:3, lbl), factor(after, 1:3, lbl), sex)
transitions<- getRefClass("Transition")$new(tbl, label= c("Before surgery", "1 year after"))
transitions$title<-"Charnley class before vs. after surgery"transitions$clr_bar<-"bottom"transitions$render()See vignette("Transition-class", package = "Gmisc") for customisation.
- Project page: https://gforge.se
- Vignettes:
browseVignettes("Gmisc") - Bugs & feature requests: https://github.com/gforge/Gmisc/issues


