Title: | Easy Visualization of Conditional Effects from Regression Models |
Version: | 1.0.0 |
Description: | Offers a flexible and user-friendly interface for visualizing conditional effects from a broad range of regression models, including mixed-effects and generalized additive (mixed) models. Compatible model types include lm(), rlm(), glm(), glm.nb(), and gam() (from 'mgcv'); nonlinear models via nls(); and generalized least squares via gls(). Mixed-effects models with random intercepts and/or slopes can be fitted using lmer(), glmer(), glmer.nb(), glmmTMB(), or gam() (from 'mgcv', via smooth terms). Plots are rendered using base R graphics with extensive customization options. Robust standard errors for rlm() are computed using the sandwich estimator (Zeileis 2004) <doi:10.18637/jss.v011.i10>. For mixed models using 'glmmTMB', see Brooks et al. (2017) <doi:10.32614/RJ-2017-066>. For linear mixed-effects models with 'lme4', see Bates et al. (2015) <doi:10.18637/jss.v067.i01>. Methods for generalized additive models follow Wood (2017) <doi:10.1201/9781315370279>. |
Maintainer: | Luca Corlatti <lucac1980@yahoo.it> |
Imports: | stats, utils, graphics, grDevices |
Suggests: | nlme, lme4, MASS, glmmTMB, mgcv, numDeriv, sandwich |
License: | GPL-3 |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2 |
NeedsCompilation: | no |
Packaged: | 2025-07-19 14:45:17 UTC; lucacorlatti |
Author: | Luca Corlatti [aut, cre] |
Repository: | CRAN |
Date/Publication: | 2025-07-22 10:10:06 UTC |
Easy Visualization of Conditional Effects from Regression Models
Description
easyViz
offers a flexible and user-friendly interface for visualizing conditional effects
from a broad range of regression and mixed-effects models using base R graphics.
Usage
easyViz(
model,
data,
predictor,
by = NULL,
pred_type = "response",
pred_range_limit = TRUE,
pred_on_top = FALSE,
num_conditioning = "median",
cat_conditioning = "mode",
fix_values = NULL,
backtransform_response = NULL,
re.form = NULL,
xlim = NULL,
ylim = NULL,
xlab = NULL,
ylab = NULL,
font_family = "",
las = 1,
bty = "o",
plot_args = list(),
show_data_points = TRUE,
binary_data_type = "plain",
bins = 10,
jitter_data_points = FALSE,
point_col = rgb(0, 0, 0, alpha = 0.4),
point_pch = 16,
point_cex = 0.75,
pred_line_col = "black",
pred_line_lty = c(1, 2, 3, 4),
pred_line_lwd = 2,
ci_type = "polygon",
ci_polygon_col = c("gray", "black", "lightgray", "darkgray"),
ci_line_col = "black",
ci_line_lty = c(1, 2, 3, 4),
ci_line_lwd = 1,
pred_point_col = c("black", "gray", "darkgray", "lightgray"),
pred_point_pch = 16,
pred_point_cex = 1,
ci_bar_col = "black",
ci_bar_lty = 1,
ci_bar_lwd = 1,
ci_bar_caps = 0.1,
cat_labels = NULL,
add_legend = FALSE,
legend_position = "top",
legend_text_size = 0.9,
legend_labels = NULL
)
Arguments
model |
[required] A fitted model object (e.g., |
data |
[required] The data frame used to fit the model (e.g., |
predictor |
[required] The name of the target explanatory variable to be plotted (e.g., |
by |
The name of an interaction or additional variable for conditioning (e.g., |
pred_type |
Character string indicating the type of predictions to plot.
Either |
pred_range_limit |
Logical. Applies only when the predictor is numeric and a categorical |
pred_on_top |
Logical. If |
num_conditioning |
How to condition non-target numeric predictors. Either |
cat_conditioning |
How to condition non-target categorical predictors.
Either |
fix_values |
A named vector or named list specifying fixed values for one or more variables during prediction.
Supports both numeric and categorical variables.
For numeric variables, specify a fixed value (e.g., |
backtransform_response |
A custom function to back-transform predictions for transformed response variables
(e.g., |
re.form |
A formula specifying which random effects to include when generating predictions.
This argument is relevant for mixed-effects models only (e.g., from |
xlim |
x-axis limits for the plot (e.g., |
ylim |
y axis limits for the plot (e.g., |
xlab |
x axis labels (e.g., |
ylab |
y axis labels (e.g., |
font_family |
Font family for the plot. E.g., |
las |
Text orientation for axis labels (default: |
bty |
Box type around the plot. E.g., |
plot_args |
A named list of additional graphical parameters passed to base R's
This is a flexible alternative to manually setting individual plot parameters in the function signature.
For a full list of supported parameters, see |
show_data_points |
Logical. Whether to display raw data points (default: |
binary_data_type |
For binary responses, how to display raw data points in the plot.
Either |
bins |
Number of bins for displaying binary response raw data (default: |
jitter_data_points |
Logical. If |
point_col |
Point color for raw data (default: |
point_pch |
Point shape for raw data (default: |
point_cex |
Point size for raw data (default: |
pred_line_col |
Color of the predicted line for numerical predictors (default: |
pred_line_lty |
Type of the predicted line for numerical predictors (default: |
pred_line_lwd |
Width of the predicted line for numerical predictors (default: |
ci_type |
Type of 95 percent confidence intervals for numerical predictors. |
ci_polygon_col |
Color for 95 percent confidence interval polygon (default: |
ci_line_col |
Color for 95 percent confidence interval lines (default: |
ci_line_lty |
Type for 95 percent confidence interval lines (default: |
ci_line_lwd |
Width for 95 percent confidence interval lines (default: |
pred_point_col |
Color for predicted point values of categorical predictors (default: |
pred_point_pch |
Shape for predicted point values of categorical predictors (default: |
pred_point_cex |
Size for predicted point values of categorical predictors (default: |
ci_bar_col |
Color for 95 percent confidence interval bars (default: |
ci_bar_lty |
Type for 95 percent confidence interval bars (default: |
ci_bar_lwd |
Width for 95 percent confidence interval bars (default: |
ci_bar_caps |
Size of the caps on 95 percent confidence interval bars (default: |
cat_labels |
Custom labels for levels of a categorical predictor (e.g., |
add_legend |
Logical. Whether to add a legend for |
legend_position |
Legend position. Either a named position string ( |
legend_text_size |
Legend text size (default: |
legend_labels |
Custom labels for the legend (e.g., |
Details
This function provides an easy-to-use yet highly flexible tool for visualizing conditional effects
from a wide range of regression models, including mixed-effects and generalized additive (mixed) models.
Compatible model types include lm
, rlm
, glm
, glm.nb
, and mgcv::gam
;
nonlinear models via nls
; and generalized least squares via gls
.
Mixed-effects models with random intercepts and/or slopes can be fitted using lmer
, glmer
, glmer.nb
,
glmmTMB
, or mgcv::gam
(via smooth terms).
The function handles nonlinear relationships (e.g., splines, polynomials), two-way interactions,
and supports visualization of three-way interactions via conditional plots.
Plots are rendered using base R graphics with extensive customization options available through the plot_args
argument.
Users can pass any valid graphical parameters accepted by plot
or par
,
enabling full control over axis labels, font styles, colors, margins, tick orientation, and more.
The arguments model
, data
, and predictor
are required.
The function will return an error if any of them is missing or invalid.
Value
A base R plot visualizing the conditional effect of a predictor on the response variable.
Additionally, a data frame is invisibly returned containing the predictor values, conditioning variables,
predicted values (fit
), and their 95 percent confidence intervals (lower
, upper
).
To extract prediction data for further use (e.g., custom plotting or tabulation), assign the output to an object:
pred_df <- easyViz(...)
. You can then inspect it using head(pred_df)
or save it with write.csv(pred_df, ...)
.
Examples
#------------------------------------------
# Load required packages
#------------------------------------------
library(nlme)
library(MASS)
library(lme4)
library(glmmTMB)
library(mgcv)
#------------------------------------------
# Simulate dataset
#------------------------------------------
set.seed(123)
n <- 100
x1 <- rnorm(n)
x2 <- rnorm(n)
x3 <- runif(n, 0, 5)
x4 <- factor(sample(letters[1:3], n, replace = TRUE))
group_levels <- paste0("G", 1:10)
group <- factor(sample(group_levels, n, replace = TRUE))
# Generate random intercepts for each group
group_effects <- rnorm(length(group_levels), mean = 0, sd = 2) # non-zero variance
names(group_effects) <- group_levels
group_intercept <- group_effects[as.character(group)]
# Non-linear continuous response
true_y <- 5 * sin(x3) + 3 * x1 + group_intercept + model.matrix(~x4)[, -1] %*% c(2, -2)
noise <- rnorm(n, sd = 3)
y <- as.vector(true_y + noise)
# Binary response with group effect added to logit
logit_p <- 2 * x1 - 1 + group_intercept
p <- 1 / (1 + exp(-logit_p))
binary_y <- rbinom(n, size = 1, prob = p)
# Binomial response: number of successes and failures
y3 <- sample(10:30, n, replace = TRUE)
logit_p_prop <- -1.5 * scale(x1)
p_prop <- 1 / (1 + exp(-logit_p_prop))
y1 <- rbinom(n, size = y3, prob = p_prop) # successes
y2 <- y3 - y1 # failures
# Count response with group effect in log(mu)
mu_count <- exp(1 + 0.8 * x2 - 0.5 * (x4 == "b") + group_intercept)
size <- 1.2
count_y <- rnbinom(n, size = size, mu = mu_count)
# Offset variable
offset_var <- log(runif(n, 1, 10))
# Assemble dataset
sim_data <- data.frame(x1, x2, x3, x4, group, y, binary_y, y1, y2, y3, count_y, offset_var)
#------------------------------------------
# 1. Linear model (lm)
#------------------------------------------
mod_lm <- lm(y ~ x1 + x4,
data = sim_data)
easyViz(model = mod_lm, data = sim_data, predictor = "x1",
by = "x4",
pred_range_limit = FALSE,
pred_on_top = TRUE,
bty = "n",
xlab = "Predictor x1",
ylab = "Response y",
point_col = ifelse(sim_data$x4=="a", "red",
ifelse(sim_data$x4=="b", "orange",
"yellow")),
point_cex = 0.5,
pred_line_col = c("red", "orange", "yellow"),
pred_line_lty = 1,
ci_polygon_col = c(rgb(1,0,0,0.5),
rgb(1,0.5,0,0.5),
rgb(1,1,0,0.5)),
add_legend = TRUE,
legend_position = "topleft",
legend_labels = c("a", "b", "c"))
# Extract prediction data
pred_df <- easyViz(model = mod_lm, data = sim_data, predictor = "x1", by = "x4")
head(pred_df)
mod_lm2 <- lm(sqrt(x3) ~ x1 * x4,
data = sim_data)
easyViz(model = mod_lm2, data = sim_data, predictor = "x1",
by="x4",
backtransform_response = function(x) x^2,
ylim = c(0,8),
show_data_points = FALSE,
add_legend = TRUE)
mod_lm3 <- lm(y ~ poly(x3, 3),
data = sim_data)
easyViz(model = mod_lm3, data = sim_data, predictor = "x3",
pred_on_top = TRUE,
font_family = "mono",
point_col = rgb(1,0,0,0.3),
point_pch = "+",
ci_type = "lines",
ci_line_lty = 2)
#------------------------------------------
# 2. Robust linear model (rlm)
#------------------------------------------
mod_rlm <- rlm(y ~ x1 + x4,
data = sim_data)
easyViz(model = mod_rlm, data = sim_data, predictor = "x1",
by = "x4",
pred_on_top = TRUE,
bty = "n",
xlab = "Predictor x1",
ylab = "Response y",
point_col = ifelse(sim_data$x4=="a", "red",
ifelse(sim_data$x4=="b", "orange",
"yellow")),
point_cex = 0.5,
pred_line_col = c("red", "orange", "yellow"),
pred_line_lty = 1,
ci_polygon_col = c(rgb(1,0,0,0.5),
rgb(1,0.5,0,0.5),
rgb(1,1,0,0.5)),
add_legend = TRUE,
legend_position = c(1.25,-1),
legend_labels = c("a", "b", "c"))
#------------------------------------------
# 3. Generalized least squares (gls)
#------------------------------------------
mod_gls <- gls(y ~ x1 + x2 + x4,
correlation = corAR1(form = ~1|group),
data = sim_data)
easyViz(model = mod_gls, data = sim_data, predictor = "x4",
jitter_data_points = TRUE,
bty = "n",
xlab = "Predictor x4",
ylab = "Response y",
point_col = rgb(0,0,1,0.2),
pred_point_col = "blue",
cat_labels = c("group A", "group B", "group C"))
sim_data$x5 <- sample(c(rep("CatA", 50), rep("CatB", 50)))
mod_gls2 <- gls(y ~ x1 + x2 + x4 * x5,
correlation = corAR1(form = ~1|group),
data = sim_data)
easyViz(model = mod_gls2, data = sim_data, predictor = "x4",
by = "x5",
jitter_data_points = TRUE,
bty = "n",
ylim = c(-15,20),
xlab = "Predictor x4",
ylab = "Response y",
point_col = c(rgb(0,0,1,0.2), rgb(1,0,0,0.2)),
pred_point_col = c("blue", "red"),
ci_bar_caps = 0,
cat_labels = c("group A", "group B", "group C"),
add_legend = TRUE,
legend_position = "topright",
legend_labels = c("Category A", "Category B"))
#------------------------------------------
# 4. Nonlinear least squares (nls)
#------------------------------------------
mod_nls <- nls(y ~ a * sin(b * x3) + c,
data = sim_data,
start = list(a = 5, b = 1, c = 0))
summary(mod_nls)
easyViz(model = mod_nls, data = sim_data, predictor = "x3",
pred_on_top = TRUE,
font_family = "serif",
bty = "n",
xlab = "Predictor x3",
ylab = "Response y",
point_col = rgb(0,1,0,0.7),
point_pch = 1,
ci_type = "lines",
ci_line_col = "black",
ci_line_lty = 2)
text(x = 2.5, y = 11,
labels = expression(Y %~% 5.31584 %*% sin(1.08158 %*% X[3]) + 0.51338),
cex = 0.7)
#------------------------------------------
# 5. Generalized linear model (glm)
#------------------------------------------
mod_glm <- glm(binary_y ~ x1 + x4 + offset(log(offset_var)),
family = binomial(link="cloglog"),
data = sim_data)
easyViz(model = mod_glm, data = sim_data, predictor = "x1",
fix_values = list(x4="b", offset_var=1),
xlab = "Predictor x1",
ylab = "Response y",
binary_data_type = "binned",
point_col = "black",
ci_polygon_col = "red")
easyViz(model = mod_glm, data = sim_data, predictor = "x4",
bty = "n",
xlab = "Predictor x4",
ylab = "Response y",
binary_data_type = "plain",
jitter_data_points = TRUE,
point_col = "black",
point_pch = "|",
point_cex = 0.5)
mod_glm2 <- glm(y1/y3 ~ x1 + x4, weights = y3,
family = binomial(link="logit"),
data = sim_data)
easyViz(model = mod_glm2, data = sim_data, predictor = "x1",
pred_on_top = TRUE,
xlab = "Predictor x1",
ylab = "Response y",
point_col = "black",
ci_polygon_col = "red")
#------------------------------------------
# 6. Negative binomial GLM (glm.nb)
#------------------------------------------
mod_glm_nb <- glm.nb(count_y ~ x2,
data = sim_data)
easyViz(model = mod_glm_nb, data = sim_data, predictor = "x2",
font_family = "mono",
bty = "L",
plot_args = list(main = "NB model"),
xlab = "Predictor x2",
ylab = "Response y",
ci_polygon_col = "blue")
#------------------------------------------
# 7. Linear mixed-effects model (lmer)
#------------------------------------------
mod_lmer <- lmer(y ~ x1 + x4 + (1 | group),
data = sim_data)
easyViz(model = mod_lmer, data = sim_data, predictor = "x1",
by="group",
re.form = NULL,
bty = "n",
plot_args = list(xaxp = c(round(min(sim_data$x1),1),
round(max(sim_data$x1),1), 5)),
ylim = c(-15, 15),
xlab = "Predictor x1",
ylab = "Response y",
pred_line_col = "green",
pred_line_lty = 1,
pred_line_lwd = 1)
oldpar <- par(new = TRUE)
easyViz(model = mod_lmer, data = sim_data, predictor = "x1",
re.form = NA,
bty = "n",
plot_args = list(xaxp = c(round(min(sim_data$x1),1),
round(max(sim_data$x1),1), 5)),
show_data_points = FALSE,
xlab = "Predictor x1",
ylab = "Response y",
ylim = c(-15, 15),
pred_line_col = "red",
pred_line_lty = 1,
pred_line_lwd = 2,
ci_polygon = rgb(0,0,0,0))
par(oldpar)
#------------------------------------------
# 8. Generalized linear mixed model (glmer)
#------------------------------------------
mod_glmer <- glmer(binary_y ~ x1 + x4 + (1 | group),
family = binomial,
data = sim_data)
easyViz(model = mod_glmer, data = sim_data, predictor = "x1",
by = "group",
re.form = NULL,
cat_conditioning = "reference",
font_family = "serif",
xlab = "Predictor x1",
ylab = "Response y",
binary_data_type = "binned",
pred_range_limit = FALSE,
pred_line_col = "blue",
pred_line_lty = 1,
pred_line_lwd = 1)
#------------------------------------------
# 9. GLMM with negative binomial (glmer.nb)
#------------------------------------------
mod_glmer_nb <- glmer.nb(count_y ~ x2 + x4 + (1 | group),
data = sim_data)
easyViz(model = mod_glmer_nb, data = sim_data, predictor = "x2",
re.form = NA,
bty = "n",
xlab = "Predictor x2",
ylab = "Response y",
ylim = c(0, 120),
point_pch = 1)
#------------------------------------------
# 10. GLMM using glmmTMB
#------------------------------------------
mod_glmmTMB <- glmmTMB(count_y ~ x2 + x4 + (1 | group),
ziformula = ~ x2,
family = nbinom2,
data = sim_data)
easyViz(model = mod_glmmTMB, data = sim_data, predictor = "x2",
re.form = NA,
bty = "n",
xlab = "Predictor x2",
ylab = "Response y",
ylim = c(0, 120),
point_pch = 1)
#------------------------------------------
# 11. GAM with random smooth for group
#------------------------------------------
mod_gam <- gam(y ~ s(x3) + s(group, bs = "re"),
data = sim_data)
easyViz(model = mod_gam, data = sim_data, predictor = "x3",
re.form = NA,
las = 0,
bty = "n",
xlab = "Predictor x3",
ylab = "Response y",
point_col = "black",
point_pch = 1,
ci_polygon_col = rgb(1,0,0,0.5))