| Title: | Plotting Two- and Three-Way Interactions |
|---|---|
| Description: | Provides two- and three-way Johnson-Neyman-(Krause) plots for easier interpretation of interactions. It extends the classic framework of Johnson and Neyman (1936) and Johnson and Fay (1950) <doi:10.1007/BF02288864> to Bayesian models and three-way interactions. The functions have dedicated routines for classic lm()/glm() models, as well as 'lme4' models and 'RSiena' results. However, the package can also be used model agnostic and thus extends the availability of JN(K)-plots beyond what is currently available. A detailed introduction can be found in Krause (2026) <doi:10.48550/arXiv.2604.22051>. |
| Authors: | Robert W. Krause [aut, cre, cph] |
| Maintainer: | Robert W. Krause <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.0.7 |
| Built: | 2026-06-05 08:56:10 UTC |
| Source: | https://github.com/rwkrause/int3ract |
Accepts either a raw matrix of posterior draws (rows = iterations,
columns = parameters) or a multiSiena object produced by
sienaBayes().
JNK_bayes( x, theta_1, theta_2, theta_3 = NULL, theta_int_12 = NULL, theta_int_13 = NULL, theta_int_23 = NULL, theta_int_123 = NULL, theta_1_vals, theta_2_vals, theta_3_vals = NULL, burn_in = NULL, thin = 1, thresholds = NULL, hyper_only = TRUE, round_res = 3, noTitle = NULL, color_mid = "#EBCC2A", color_low = "#3B9AB2", color_high = "#F21A00", color_values = "grey40", color_grid = "black", grid_density = 0.01, grid_spacing = 0.1, save = FALSE, folder = NULL )JNK_bayes( x, theta_1, theta_2, theta_3 = NULL, theta_int_12 = NULL, theta_int_13 = NULL, theta_int_23 = NULL, theta_int_123 = NULL, theta_1_vals, theta_2_vals, theta_3_vals = NULL, burn_in = NULL, thin = 1, thresholds = NULL, hyper_only = TRUE, round_res = 3, noTitle = NULL, color_mid = "#EBCC2A", color_low = "#3B9AB2", color_high = "#F21A00", color_values = "grey40", color_grid = "black", grid_density = 0.01, grid_spacing = 0.1, save = FALSE, folder = NULL )
x |
matrix or 'multiSiena'; posterior draws or sienaBayes() output. If a matrix, columns should be named or referenced by index. If a 'multiSiena' object, parameters are referenced by their position in the (rate-excluded) effects object. |
theta_1 |
character or numeric; name/index of the first variable
involved in the interaction. (For |
theta_2 |
character or numeric; name/index of the second variable. |
theta_3 |
character or numeric; name/index of the third variable. Default NULL (two-way interaction). |
theta_int_12 |
numeric; index of the interaction between theta_1
and theta_2. Not needed when theta_1 etc. are character names
(matrix input and |
theta_int_13 |
numeric; index of the theta_1:theta_3 interaction. Default NULL. |
theta_int_23 |
numeric; index of the theta_2:theta_3 interaction. Default NULL. |
theta_int_123 |
numeric; index of the three-way interaction. Default NULL. |
theta_1_vals |
numeric; range of the statistic theta_1 is multiplied with. |
theta_2_vals |
numeric; range of the statistic theta_2 is multiplied with. |
theta_3_vals |
numeric; range of the statistic theta_3 is multiplied with. Default NULL. |
burn_in |
numeric; burn-in iterations to remove.
For |
thin |
numeric; thinning interval. Default 1. |
thresholds |
numeric; threshold for significance hashing.
Default |
hyper_only |
logical; ( |
round_res |
numeric; rounding digits. Default 3. |
noTitle |
character; optional plot title. |
color_mid |
character; mid-point colour. Default '#EBCC2A'. |
color_low |
character; low-value colour. Default '#3B9AB2'. |
color_high |
character; high-value colour. Default '#F21A00'. |
color_values |
character; number colour. Default 'grey40'. |
color_grid |
character; grid colour. Default 'black'. |
grid_density |
numeric; hash-grid density. Default 0.01. |
grid_spacing |
numeric; hash-grid spacing. Default 0.1. |
save |
logical; save plots with ggsave()? Default FALSE. |
folder |
character; save folder. Default NULL, which writes into a
session-temporary directory
( |
A list containing tables and plots. For two-way interactions:
param_table and plots. For three-way: thetas,
standard_errors, p_values, significance, and
plots. When hyper_only = FALSE ('multiSiena'), also returns a
list of group-level results under random_groups_effects.
# --- two-way: raw posterior matrix (fast, no extra packages) --- set.seed(1) n_iter <- 500 post2 <- cbind(x = rnorm(n_iter, 0.5, 0.2), z = rnorm(n_iter, -0.3, 0.2), `x:z` = rnorm(n_iter, 0.4, 0.2)) jnk_bayes2 <- JNK_bayes(post2, theta_1 = 'x', theta_2 = 'z', theta_1_vals = seq(-2, 2, 1), theta_2_vals = seq(-2, 2, 1)) # --- three-way: raw posterior matrix --- post3 <- cbind(x = rnorm(n_iter, 0.5, 0.2), z = rnorm(n_iter, -0.3, 0.2), w = rnorm(n_iter, 0.2, 0.2), `x:z` = rnorm(n_iter, 0.4, 0.2), `x:w` = rnorm(n_iter, 0.1, 0.2), `z:w` = rnorm(n_iter, -0.1, 0.2), `x:z:w` = rnorm(n_iter, 0.2, 0.2)) jnk_bayes3 <- JNK_bayes(post3, theta_1 = 'x', theta_2 = 'z', theta_3 = 'w', theta_1_vals = seq(-2, 2, 1), theta_2_vals = seq(-2, 2, 1), theta_3_vals = seq(-2, 2, 1)) # --- two-way: integration with MCMCpack (only if installed) --- if (requireNamespace("MCMCpack", quietly = TRUE)) { set.seed(1402) dat <- data.frame(x = rnorm(100), z = rnorm(100)) dat$y <- dat$x + 0.5 * dat$x * dat$z - 0.5 * dat$z + rnorm(100, sd = 4) mod_bayes2 <- MCMCpack::MCMCregress(y ~ x * z, data = dat, burnin = 1000, mcmc = 10000, thin = 1, verbose = 0) jnk_bayes2_e <- JNK_bayes(mod_bayes2, theta_1 = 'x', theta_2 = 'z', theta_1_vals = seq(-3, 3, 0.5), theta_2_vals = seq(-3, 3, 0.5)) }# --- two-way: raw posterior matrix (fast, no extra packages) --- set.seed(1) n_iter <- 500 post2 <- cbind(x = rnorm(n_iter, 0.5, 0.2), z = rnorm(n_iter, -0.3, 0.2), `x:z` = rnorm(n_iter, 0.4, 0.2)) jnk_bayes2 <- JNK_bayes(post2, theta_1 = 'x', theta_2 = 'z', theta_1_vals = seq(-2, 2, 1), theta_2_vals = seq(-2, 2, 1)) # --- three-way: raw posterior matrix --- post3 <- cbind(x = rnorm(n_iter, 0.5, 0.2), z = rnorm(n_iter, -0.3, 0.2), w = rnorm(n_iter, 0.2, 0.2), `x:z` = rnorm(n_iter, 0.4, 0.2), `x:w` = rnorm(n_iter, 0.1, 0.2), `z:w` = rnorm(n_iter, -0.1, 0.2), `x:z:w` = rnorm(n_iter, 0.2, 0.2)) jnk_bayes3 <- JNK_bayes(post3, theta_1 = 'x', theta_2 = 'z', theta_3 = 'w', theta_1_vals = seq(-2, 2, 1), theta_2_vals = seq(-2, 2, 1), theta_3_vals = seq(-2, 2, 1)) # --- two-way: integration with MCMCpack (only if installed) --- if (requireNamespace("MCMCpack", quietly = TRUE)) { set.seed(1402) dat <- data.frame(x = rnorm(100), z = rnorm(100)) dat$y <- dat$x + 0.5 * dat$x * dat$z - 0.5 * dat$z + rnorm(100, sd = 4) mod_bayes2 <- MCMCpack::MCMCregress(y ~ x * z, data = dat, burnin = 1000, mcmc = 10000, thin = 1, verbose = 0) jnk_bayes2_e <- JNK_bayes(mod_bayes2, theta_1 = 'x', theta_2 = 'z', theta_1_vals = seq(-3, 3, 0.5), theta_2_vals = seq(-3, 3, 0.5)) }
Unified function that accepts lm, glm, sienaFit
('RSiena'), or lmerMod/glmerMod ('lme4') objects, or raw
coefficient vectors and covariance matrices.
JNK_freq( x = NULL, theta_1, theta_2, theta_3 = NULL, theta_int_12 = NULL, theta_int_13 = NULL, theta_int_23 = NULL, theta_int_123 = NULL, theta_1_vals = NULL, theta_2_vals = NULL, theta_3_vals = NULL, covar = NULL, coefs = NULL, name = NULL, group_var = NULL, fixed_only = TRUE, control_fdr = FALSE, alpha = 0.05, round_res = 3, range_size = NULL, sig_color = "seagreen3", non_sig_color = "chocolate", line_color = "black", color_mid = "#EBCC2A", color_low = "#3B9AB2", color_high = "#F21A00", color_values = "grey40", color_grid = "black", grid_density = 0.01, grid_spacing = 0.1, crosshatch_non_sig = TRUE, save = FALSE, folder = NULL )JNK_freq( x = NULL, theta_1, theta_2, theta_3 = NULL, theta_int_12 = NULL, theta_int_13 = NULL, theta_int_23 = NULL, theta_int_123 = NULL, theta_1_vals = NULL, theta_2_vals = NULL, theta_3_vals = NULL, covar = NULL, coefs = NULL, name = NULL, group_var = NULL, fixed_only = TRUE, control_fdr = FALSE, alpha = 0.05, round_res = 3, range_size = NULL, sig_color = "seagreen3", non_sig_color = "chocolate", line_color = "black", color_mid = "#EBCC2A", color_low = "#3B9AB2", color_high = "#F21A00", color_values = "grey40", color_grid = "black", grid_density = 0.01, grid_spacing = 0.1, crosshatch_non_sig = TRUE, save = FALSE, folder = NULL )
x |
model object ( |
theta_1 |
character or numeric; name (lm/glm/lmerMod/glmerMod) or index (sienaFit) of the first variable. |
theta_2 |
character or numeric; second variable. |
theta_3 |
character or numeric; third variable. Default NULL (two-way). |
theta_int_12 |
numeric; index of the theta_1:theta_2 interaction (sienaFit / generic only). For m/glm/lmerMod/glmerMod inputs the interaction name is resolved automatically. |
theta_int_13 |
numeric; index of the theta_1:theta_3 interaction. Default NULL. |
theta_int_23 |
numeric; index of the theta_2:theta_3 interaction. Default NULL. |
theta_int_123 |
numeric; index of the three-way interaction. Default NULL. |
theta_1_vals |
numeric; evaluation range for theta_1. Auto-derived from model data for lm/glm/lmerMod/glmerMod if NULL. |
theta_2_vals |
numeric; evaluation range for theta_2. |
theta_3_vals |
numeric; evaluation range for theta_3. Default NULL. |
covar |
matrix; covariance matrix of the relevant parameters.
Required only when |
coefs |
numeric; coefficient vector.
Required only when |
name |
character; variable names.
Required only when |
group_var |
character; ('lme4' only) grouping variable for random effects. Defaults to the first grouping factor. |
fixed_only |
logical; ('lme4' only) produce only fixed-effects plots? If FALSE, per-group plots are produced for groups with random interaction terms. Default TRUE. |
control_fdr |
logical; apply Bonferroni-Holm correction? Default FALSE. |
alpha |
numeric; significance level. Default 0.05. |
round_res |
integer; rounding precision. Default 3. |
range_size |
integer; number of moderator values. Default 1000 for two-way, 50 for three-way. |
sig_color |
character; significant region colour (2-way). Default 'seagreen3'. |
non_sig_color |
character; non-significant region colour (2-way). Default 'chocolate'. |
line_color |
character; line colour (2-way). Default 'black'. |
color_mid |
character; midpoint colour (3-way heatmap). Default '#EBCC2A'. |
color_low |
character; low-value colour. Default '#3B9AB2'. |
color_high |
character; high-value colour. Default '#F21A00'. |
color_values |
character; value label colour. Default 'grey40'. |
color_grid |
character; crosshatch colour. Default 'black'. |
grid_density |
numeric; crosshatch density. Default 0.01. |
grid_spacing |
numeric; crosshatch spacing. Default 0.1. |
crosshatch_non_sig |
logical; crosshatch non-significant cells? Default TRUE. |
save |
logical; save plots via ggsave()? Default FALSE. |
folder |
character; output folder for saved plots. Default NULL,
which writes into a session-temporary directory
( |
A list containing tables and plots. For two-way interactions:
param_table and plots. For three-way: thetas,
standard_errors, p_values, significance, and
plots. When fixed_only = FALSE ('lme4'), returns a list
with fixed and random_groups elements.
# --- two-way lm --- set.seed(1) dat <- data.frame(y = rnorm(100), x = rnorm(100), z = rnorm(100), w = rnorm(100)) res <- lm(y ~ x * z * w, dat) x2 <- JNK_freq(res, theta_1 = 'x', theta_2 = 'z', range_size = 50) # --- three-way lm (small grid for speed) --- x3 <- JNK_freq(res, theta_1 = 'x', theta_2 = 'z', theta_3 = 'w', range_size = 10) # --- generic (covariance + coefficients) --- x2_gen <- JNK_freq(covar = vcov(res)[c('x','z','x:z'), c('x','z','x:z')], coefs = coef(res)[c('x','z','x:z')], name = c('x', 'z'), theta_1 = 'x', theta_2 = 'z', theta_1_vals = c(-3, 3), theta_2_vals = c(-3, 3), range_size = 50)# --- two-way lm --- set.seed(1) dat <- data.frame(y = rnorm(100), x = rnorm(100), z = rnorm(100), w = rnorm(100)) res <- lm(y ~ x * z * w, dat) x2 <- JNK_freq(res, theta_1 = 'x', theta_2 = 'z', range_size = 50) # --- three-way lm (small grid for speed) --- x3 <- JNK_freq(res, theta_1 = 'x', theta_2 = 'z', theta_3 = 'w', range_size = 10) # --- generic (covariance + coefficients) --- x2_gen <- JNK_freq(covar = vcov(res)[c('x','z','x:z'), c('x','z','x:z')], coefs = coef(res)[c('x','z','x:z')], name = c('x', 'z'), theta_1 = 'x', theta_2 = 'z', theta_1_vals = c(-3, 3), theta_2_vals = c(-3, 3), range_size = 50)