Statistical Tools Designed for End Users.
statuser
Stat Tools for End Users
Basic and custom statistical tools designed with end users in mind. Functions have optimized defaults, produce decluttered and informative output that is self-explanatory, and generate publication-ready results in one line of code.
Installation
# CRAN (when available)
install.packages("statuser")
# Or pin a version with groundhog
groundhog::groundhog.library("statuser", date)
Overview
Same organization as help(statuser):
Basic Stats (improved)
lm2()— likelm(), with robust SE and much more informative outputt.test2()— liket.test(), decluttered, and more informative outputtable2()— liketable(), showing variable names, and with proportions & chi2 built indesc_var()— descriptive statistics for variables (optional, by group(s))
Custom tools from papers by Uri Simonsohn
twolines()— two-lines test for U-shapes (Simonsohn 2018)interprobe()— probe and visualize nonlinear interactions (Simonsohn 2024; Montealegre & Simonsohn 2026)stimulus.plot()— stimulus plots for matched/treated-stimulus designs (Simonsohn, Montealegre, & Evangelidis 2025)stimulus.beeswarm()— beeswarm plots for compared-stimulus designs (Simonsohn, Montealegre, & Evangelidis 2025)
Graphing
scatter.gam()— scatter plot for x & y, with fitted GAM line y = f(x)plot_cdf()— empirical cumulative distribution functions (optional, by group)plot_density()— density functions (optional, by group)plot_freq()— frequency of observed values (optional, by group)plot_means()— barplot of means with confidence intervals and (optionally) tests; see alsostimulus.plot()for per-stimulus plotsplot_gam()— fitted GAM values for a focal predictortext2()— liketext()with horizontal alignment and background color
Formatting
format_pvalue()— format p-values for displayvar_labels()— get/set variable labels (as base-R"label"attributes)message2()— print colored messages to consoleresize_images()— resize images (SVG, PDF, EPS, JPG, PNG, etc.) to PNG with specified width
Miscellaneous
clear()— clear environment, console, and all graphics deviceslist2()— likelist(), but unnamed objects are automatically namedconvert_to_sql()— convert CSV files to SQL INSERT statements
Examples
Basic Stats (improved)
lm2(): like lm(), with robust SE and much more informative output
Uses estimatr for robust and clustered errors. Notes via lm2_notes() after printing.
lm2(mpg ~ wt + hp, data = mtcars)
lm2(mpg ~ wt + hp, data = mtcars, se_type = "HC2")
lm2_notes()
t.test2(): like t.test(), decluttered, and more informative output
men <- rnorm(100, mean = 5, sd = 1)
women <- rnorm(100, mean = 4.8, sd = 1)
t.test2(men, women)
data <- data.frame(y = rnorm(100), group = rep(c("A", "B"), 50))
t.test2(y ~ group, data = data)
table2(): like table(), showing variable names, with proportions & chi2 built in
df <- data.frame(
group = c("A", "A", "B", "B", "A"),
status = c("X", "Y", "X", "Y", "X")
)
table2(df$group, df$status)
table2(df$group, df$status, prop = "row", chi = TRUE)
desc_var(): descriptive statistics for variables (optional, by group(s))
df <- data.frame(score = rnorm(100), condition = rep(c("Control", "Treatment"), 50))
desc_var(score ~ condition, data = df)
Custom tools from papers by Uri Simonsohn
twolines(): two-lines test for U-shapes (Simonsohn 2018)
Implements the two-lines test (Simonsohn, 2018).
Reference: Simonsohn, U. (2018). Two lines: A valid alternative to the invalid testing of U-shaped relationships with quadratic regressions. Advances in Methods and Practices in Psychological Science, 1(4), 538–555. https://doi.org/10.1177/2515245918805755
set.seed(123)
x <- rnorm(100)
y <- -x^2 + rnorm(100)
data <- data.frame(x = x, y = y)
twolines(y ~ x, data = data)
# With covariates, suppress Robin Hood details, or save PNG
twolines(y ~ x + z, data = data, quiet = TRUE)
twolines(y ~ x, data = data, pngfile = "twolines_plot.png")
interprobe(): probe and visualize nonlinear interactions
Estimates or accepts a model, then plots simple slopes and Johnson–Neyman curves. Default engine is GAM; also supports linear models, supplied fits, and lm2().
References: Simonsohn, U. (2024). AMPPS. https://doi.org/10.1177/25152459231207787
interprobe(x = "predictor", z = "moderator", y = "outcome", data = df)
interprobe(x = "predictor", z = "moderator", y = "outcome", data = df, model = "linear")
stimulus.plot(): stimulus plots for matched/treated-stimulus designs
Reference: Simonsohn, U., Montealegre, A., & Evangelidis, I. (2025). JPSP, 129(1), 71–90. https://doi.org/10.1037/pspa0000449
stimulus.plot(
data = df, dv = "score", stimulus = "item", condition = "cond",
plot.type = "means", watermark = FALSE
)
stimulus.plot(
data = df, dv = "score", stimulus = "item", condition = "cond",
plot.type = "effects", participant = "id", simtot = 500, seed = 2024
)
clear_stimulus_cache()
stimulus.beeswarm(): beeswarm plots for compared-stimulus designs
stimulus.beeswarm(
data = df, dv = "score", stimulus = "stim_id", condition = "cond",
simtot = 500, watermark = FALSE
)
Graphing
scatter.gam(): scatter plot for x & y, with fitted GAM line
x <- rnorm(100)
y <- 2 * x + rnorm(100)
scatter.gam(x, y)
scatter.gam(y ~ x, data = data.frame(x, y), data.dots = TRUE)
plot_cdf(): ECDFs by group
y <- rnorm(100)
x <- rep(c("A", "B"), 50)
plot_cdf(y ~ x)
plot_cdf(y ~ x, col = c("red", "blue"), order = c("B", "A"))
plot_density(): Densities by group
plot_density(y ~ x)
plot_density(y ~ x, col = c("red", "blue"), show.means = FALSE, order = -1)
plot_freq(): Frequency plot without binning
plot_freq(c(1, 1, 2, 2, 2, 5, 5))
df <- data.frame(
value = c(1, 1, 2, 2, 2, 5, 5),
group = c("A", "A", "A", "B", "B", "A", "B")
)
plot_freq(value ~ group, data = df, order = c("B", "A"))
plot_freq(value ~ group, data = df, freq = FALSE, legend.title = "Treatment")
plot_means(): barplot of means with CIs and (optionally) tests
Up to three grouping factors; optional clustered SEs and custom comparisons. See stimulus.plot() for per-stimulus plots.
df <- data.frame(y = rnorm(100), group = rep(c("A", "B"), 50))
plot_means(y ~ group, data = df, quiet = TRUE)
df2 <- data.frame(
y = rnorm(200),
x1 = rep(c("A", "B"), 100),
x2 = rep(c("X", "Y"), each = 100)
)
plot_means(y ~ x1 + x2, data = df2)
plot_gam(): GAM partial effect with optional distribution panel
library(mgcv)
model <- gam(mpg ~ s(hp) + s(wt) + factor(cyl), data = mtcars)
plot_gam(model, "hp", plot2 = "auto")
plot_gam(model, "hp", plot2 = "freq", quantile.others = 25)
text2(): like text() with horizontal alignment and background color
plot(1:10, 1:10, type = "n")
text2(2, 8, "Left", align = "left", bg = "lightblue")
text2(5, 8, "Center", align = "center", bg = "lightgreen")
text2(8, 8, "Right", align = "right", bg = "lightyellow")
text2(5, 5, "Red text", col = "red", bg = "white")
Formatting
format_pvalue(): format p-values for display
format_pvalue(0.05)
format_pvalue(0.0001, include_p = TRUE)
var_labels(): get/set variable labels
df <- data.frame(x = 1:3, y = 4:6)
var_labels(df) <- c("Variable X", "Variable Y")
var_labels(df)
message2(): print colored messages to console
message2("Note", col = "cyan", font = 2)
resize_images(): resize images to PNG at a set width
resize_images("path/to/image.svg", width = 800)
resize_images("path/to/images", width = c(800, 1200, 600))
Miscellaneous
clear(): clear environment, console, and graphics devices
clear() # first run may prompt for one-time permission
list2(): like list(), auto-named objects
list2(x, y, z)
convert_to_sql(): CSV to SQL INSERT statements
convert_to_sql("data.csv", "data.sql")
Dependencies
Imports:mgcv, marginaleffects, rsvg, magick, sandwich, lmtest, lmerTest, digest, beeswarm, utils
Suggested (optional features):estimatr (lm2()), testthat, crayon, quantreg, broom, modelsummary
Author
Uri Simonsohn — [email protected] — https://github.com/urisohn/statuser
License
GPL-3
Version
CRAN release: 0.3.0 (stimulus plots, lm2_notes(), Cohen's d in t.test2(), and related fixes). Development version may be ahead of CRAN.