knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4, message = FALSE, warning = FALSE )
The dumbbell package creates dumbbell plots in ggplot2. A dumbbell plot compares two numeric values for the same item and connects them with a line segment. This is useful when you want to show before/after values, treatment/control values, male/female values, or any paired comparison.
The main function is dumbbell(). It expects a data frame with at least four columns:
The function returns a ggplot object, so you can add standard ggplot2 layers such as facet_wrap(), labs(), theme(), or coord_cartesian().
Install the package from CRAN with:
install.packages("dumbbell")
Or install a development version from a local source directory:
devtools::install("path/to/dumbbell")
suppressPackageStartupMessages({ library(dumbbell) library(dplyr) library(ggplot2) })
The example below creates paired measurements for two groups. Each subject has a value for group A and group B. The data are then reshaped into the format expected by dumbbell().
set.seed(123) raw_data <- data.frame( Group = rep(c("A", "B"), each = 10), Subject = rep(paste0("sub_", 1:10), times = 2), result = sample(1:100000, 20, replace = TRUE), analysis = rep(rep(c("a", "b"), each = 5), times = 2) ) group_a <- raw_data %>% filter(Group == "A") group_b <- raw_data %>% filter(Group == "B") plot_data <- merge( group_a, group_b, by = c("Subject", "analysis") ) plot_data <- plot_data %>% mutate(diff = result.x - result.y) %>% arrange(diff) plot_data$Subject <- factor(plot_data$Subject, levels = plot_data$Subject) head(plot_data)
Use id for the labels on the y-axis, key for the grouping variable, and column1/column2 for the paired numeric values.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B" )
Set delt = 1 to add the difference between the two values at the right side of the plot.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B", delt = 1, expandx = 0.1 )
Set pt_val = 1 to print the numeric values next to the points. Use col_lab1 and col_lab2 to control the label colors.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B", pt_val = 1, expandx = 0.05, col_lab1 = "blue", col_lab2 = "red" )
Set arrow = 1 to draw arrows along the connecting segments. Use arrow_size, segsize, pointsize, pt_alpha, col_seg1, and col_seg2 to customize the display.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B", arrow = 1, arrow_size = 0.2, segsize = 0.7, pointsize = 1.5, pt_alpha = 0.6, col_seg1 = "#A9A9A9", col_seg2 = "#A9A9A9" )
Because dumbbell() returns a ggplot object, you can add facet_wrap() directly.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B" ) + facet_wrap(~ analysis, ncol = 1, scales = "free_y")
The pval argument adds a paired test result to the facet label:
pval = 1 uses a paired Wilcoxon test.pval = 2 uses a paired t-test.The current implementation uses base R functions from the stats package, so the package does not need to depend on rstatix for these tests.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B", pval = 1 ) + facet_wrap(~ analysis, ncol = 1, scales = "free_y")
This example combines facets, arrows, highlighted segment colors, point transparency, and delta labels.
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B", delt = 1, col_seg2 = "red", col_seg1 = "blue", arrow = 1, pt_alpha = 0.6, pointsize = 2, expandx = 0.2, segsize = 0.5, textsize = 2, pval = 1 ) + facet_wrap(~ analysis, ncol = 1, scales = "free_y")
Because dumbbell() already adds an x-axis scale, xlim() will replace that scale and may remove data outside the requested range. To zoom without dropping observations, use coord_cartesian():
dumbbell( xdf = plot_data, id = "Subject", key = "analysis", column1 = "result.x", column2 = "result.y", lab1 = "Group A", lab2 = "Group B" ) + coord_cartesian(xlim = c(0, 100000))
| Argument | Description |
|---|---|
| xdf | Input data frame. |
| id | Column used for the y-axis labels. |
| key | Grouping variable, commonly used with facet_wrap(). |
| column1, column2 | Paired numeric columns to compare. |
| lab1, lab2 | Labels for the two compared values. |
| delt | Set to 1 to display the difference between the two values. |
| pt_val | Set to 1 to display point value labels. |
| pval | Set to 1 for paired Wilcoxon test or 2 for paired t-test. |
| arrow | Set to 1 to add arrows to the connecting segments. |
| pointsize, textsize, segsize | Control point, label, and segment sizes. |
| p_col1, p_col2 | Colors for the two point groups. |
| col_seg1, col_seg2 | Segment colors by direction. |
| expandx, expandy | Expansion around the x- and y-axes. |
stats::wilcox.test() and stats::t.test() to avoid an unnecessary dependency on rstatix.devtools::document() to regenerate NAMESPACE and help files.docs/ website is used, regenerate it from the source vignette/R Markdown rather than editing generated HTML by hand.Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.