| Title: | Actor-Partner Interdependence Model Convenience Functions |
|---|---|
| Description: | Utilities for Actor-Partner Interdependence Models (APIM). |
| Authors: | Robert Ackerman [aut, cre] |
| Maintainer: | Robert Ackerman <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.1 |
| Built: | 2026-06-04 03:02:36 UTC |
| Source: | https://github.com/RobAckerman/apim |
Evaluates whether the data meet the three requirements necessary for
meaningful response surface analysis (RSA) results: (1) adequate variance
in both actor and partner scores, (2) sufficient representation of
over-estimators and under-estimators (at least min_pct\
category), and (3) a statistically significant R-squared from the
polynomial mixed model. Results are reported for the overall sample and,
optionally, separately for each level of a moderator variable.
check_rsa_requirements( data, outcome, actor, partner, re_term, moderator = NULL, mod_labels = NULL, congruence_threshold = 0.5, min_pct = 10 )check_rsa_requirements( data, outcome, actor, partner, re_term, moderator = NULL, mod_labels = NULL, congruence_threshold = 0.5, min_pct = 10 )
data |
A data frame. |
outcome |
Character string. Name of the outcome variable. |
actor |
Character string. Name of the (centered) actor predictor. |
partner |
Character string. Name of the (centered) partner predictor. |
re_term |
Character string. The random effects term exactly as it
should appear in the model formula, e.g.
|
moderator |
Character string or |
mod_labels |
Named character vector or |
congruence_threshold |
Numeric. Cutpoint applied to the standardized
difference (partner_z - actor_z) for classifying cases as congruent.
Default |
min_pct |
Numeric. Minimum percentage of cases required in each
bias category. Default |
Participants are classified into three categories based on the standardized
difference between actor and partner scores, matching the convention in
RSA::summary.RSA (Schönbrodt et al., 2018). Both variables are
first standardized to a common pooled mean and SD, then the difference
(partner_z - actor_z) is computed:
Standardized difference > congruence_threshold
(partner exceeds actor).
Standardized difference < -congruence_threshold
(actor exceeds partner).
|standardized difference| <= congruence_threshold.
R-squared and its significance are estimated using estimate_Rsq,
which fits null and polynomial glmmTMB models with the same random
effect structure specified in re_term and uses a deviance difference
test. This properly accounts for dyadic non-independence, unlike the OLS
approach used in RSA::summary.RSA. R-squared is always estimated on
the full sample. When a moderator is supplied, bias percentages are reported
separately per group but R-squared is not re-estimated per group.
Invisibly returns a data.frame with one row per group.
Schönbrodt, F. D., Humberg, S., & Nestler, S. (2018). Testing similarity effects with dyadic response surface analysis. European Journal of Personality, 32(6), 627–641. doi:10.1002/per.2169
Edwards, J. R. (1994). The study of congruence in organizational behavior research: Critique and a proposed alternative. Organizational Behavior and Human Decision Processes, 58(1), 51–100.
## Not run: check_rsa_requirements( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_labels = c("-1" = "Women", "1" = "Men") ) ## End(Not run)## Not run: check_rsa_requirements( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_labels = c("-1" = "Women", "1" = "Men") ) ## End(Not run)
Computes and prints the chi-square statistic, degrees of freedom, and
p-value for a deviance difference test comparing a reduced and full model.
Accepts either fitted gls or glmmTMB model objects directly,
or raw deviance values and parameter counts for use with output from other
software.
When comparing models that differ in their fixed effects, both models must be estimated using Maximum Likelihood (ML). When comparing models that differ only in their random effects, REML estimation is acceptable.
deviance_diff_test( model_r = NULL, model_f = NULL, deviance_r = NULL, deviance_f = NULL, p_r = NULL, p_f = NULL )deviance_diff_test( model_r = NULL, model_f = NULL, deviance_r = NULL, deviance_f = NULL, p_r = NULL, p_f = NULL )
model_r |
A fitted |
model_f |
A fitted |
deviance_r |
Numeric. Deviance for the reduced model. Only required when not supplying model objects (e.g. when using output from other software). |
deviance_f |
Numeric. Deviance for the full model. Only required when not supplying model objects. |
p_r |
Integer. Number of parameters in the reduced model. Only required when not supplying model objects. |
p_f |
Integer. Number of parameters in the full model. Only required when not supplying model objects. |
Invisibly returns a data.frame with columns deviance_r,
deviance_f, p_r, p_f, chi2, df,
and p.
## Not run: # Using model objects deviance_diff_test(model_r = m_reduced, model_f = m_full) # Using raw values from other software deviance_diff_test(deviance_r = 3689.3, deviance_f = 3674.1, p_r = 10, p_f = 12) ## End(Not run)## Not run: # Using model objects deviance_diff_test(model_r = m_reduced, model_f = m_full) # Using raw values from other software deviance_diff_test(deviance_r = 3689.3, deviance_f = 3674.1, p_r = 10, p_f = 12) ## End(Not run)
Reports the estimate(s) of R-squared and the corresponding deviance difference test(s) for the indistinguishable and distinguishable Actor-Partner Interdependence Model (APIM).
If researchers use the nlme (with the gls function) or
glmmTMB packages, they need only specify the full model object with
the model_full argument. Either ML or REML estimation can be used
for the supplied model; the function handles refitting internally.
By default, the function assumes an indistinguishable APIM. If the model
is distinguishable, researchers must specify indistinguishable = FALSE
and supply the names of the dummy-coded variables for the two dyad members
via person_1 and person_2.
For gls models with indistinguishable = FALSE, the model
must be in the two-intercept form (e.g.
RelSat_A ~ 0 + man + woman + man:c_Amity_A + woman:c_Amity_A).
If your model uses the interaction approach, use switch_to_twoint()
first. The person_1 argument is assumed to correspond to the
reference level of varIdent (the level with ratio = 1.0, determined
by the first value of the grouping variable encountered in the data) and
person_2 to the non-reference level. A note is printed at runtime
showing which factor levels correspond to person_1 and
person_2 so you can verify the mapping is correct.
For glmmTMB models with indistinguishable = FALSE, the
random effects term must use explicit dummy-coded variables
(e.g. cs(0 + man + woman | DyadID)) rather than as.factor().
The names supplied to person_1 and person_2 must match the
dummy variable names exactly.
To ensure valid estimates of R-squared and deviance difference tests, the supplied model object should not contain any missing data for the predictors.
If researchers use other software to estimate the models, they must provide all individual quantities needed to estimate and test R-squared. When supplying these values, researchers must ensure that the deviances are from models estimated with ML and that the residual variances are from models estimated with REML.
estimate_Rsq( model_full = NULL, indistinguishable = TRUE, deviance_null = NULL, deviance_full = NULL, deviance_p1 = NULL, deviance_p2 = NULL, p_null = NULL, p_full = NULL, p_p1 = NULL, p_p2 = NULL, resvar_null = NULL, resvar_full = NULL, resvar_null_p1 = NULL, resvar_null_p2 = NULL, resvar_full_p1 = NULL, resvar_full_p2 = NULL, person_1 = "Person 1", person_2 = "Person 2" )estimate_Rsq( model_full = NULL, indistinguishable = TRUE, deviance_null = NULL, deviance_full = NULL, deviance_p1 = NULL, deviance_p2 = NULL, p_null = NULL, p_full = NULL, p_p1 = NULL, p_p2 = NULL, resvar_null = NULL, resvar_full = NULL, resvar_null_p1 = NULL, resvar_null_p2 = NULL, resvar_full_p1 = NULL, resvar_full_p2 = NULL, person_1 = "Person 1", person_2 = "Person 2" )
model_full |
A fitted |
indistinguishable |
Logical. If |
deviance_null |
Numeric. ML deviance for the null model. Only required when not supplying model objects. |
deviance_full |
Numeric. ML deviance for the full model. Only required when not supplying model objects. |
deviance_p1 |
Numeric. ML deviance for the person 1 model. Only required for the distinguishable case when not supplying model objects. |
deviance_p2 |
Numeric. ML deviance for the person 2 model. Only required for the distinguishable case when not supplying model objects. |
p_null |
Integer. Number of parameters in the null model. Only required when not supplying model objects. |
p_full |
Integer. Number of parameters in the full model. Only required when not supplying model objects. |
p_p1 |
Integer. Number of parameters in the person 1 model. Only required for the distinguishable case when not supplying model objects. |
p_p2 |
Integer. Number of parameters in the person 2 model. Only required for the distinguishable case when not supplying model objects. |
resvar_null |
Numeric. REML residual variance from the null model. Only required for the indistinguishable case when not supplying model objects. |
resvar_full |
Numeric. REML residual variance from the full model. Only required for the indistinguishable case when not supplying model objects. |
resvar_null_p1 |
Numeric. REML residual variance for person 1 from the null model. Only required for the distinguishable case when not supplying model objects. |
resvar_null_p2 |
Numeric. REML residual variance for person 2 from the null model. Only required for the distinguishable case when not supplying model objects. |
resvar_full_p1 |
Numeric. REML residual variance for person 1 from the full model. Only required for the distinguishable case when not supplying model objects. |
resvar_full_p2 |
Numeric. REML residual variance for person 2 from the full model. Only required for the distinguishable case when not supplying model objects. |
person_1 |
Character. Display label and variable name for the first
dyad member. For |
person_2 |
Character. Display label and variable name for the second
dyad member. For |
Invisibly returns a data.frame with columns person,
R2, chi2, df, and p. For the
indistinguishable case the data frame has one row; for the distinguishable
case it has three rows (omnibus, person 1, person 2).
## Not run: # Indistinguishable APIM — supply model object estimate_Rsq(model_full = fullmodel_REML) # Indistinguishable APIM — supply raw values estimate_Rsq(deviance_null = 1472.455, deviance_full = 1341.497, p_null = 3, p_full = 5, resvar_null = 0.722, resvar_full = 0.562) # Distinguishable APIM — gls, must be in two-intercept form m_twoint <- switch_to_twoint(m_interact, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") estimate_Rsq(m_twoint, indistinguishable = FALSE, person_1 = "man", person_2 = "woman") # Distinguishable APIM — glmmTMB, RE must use explicit dummy codes estimate_Rsq(model_full = fulldismodel_REML, indistinguishable = FALSE, person_1 = "man", person_2 = "woman") # Distinguishable APIM — supply raw values estimate_Rsq(indistinguishable = FALSE, deviance_null = 1187.010, deviance_full = 1137.756, deviance_p1 = 1176.509, deviance_p2 = 1169.441, p_null = 5, p_full = 9, p_p1 = 7, p_p2 = 7, resvar_null_p1 = 0.429, resvar_null_p2 = 0.534, resvar_full_p1 = 0.389, resvar_full_p2 = 0.473, person_1 = "man", person_2 = "woman") ## End(Not run)## Not run: # Indistinguishable APIM — supply model object estimate_Rsq(model_full = fullmodel_REML) # Indistinguishable APIM — supply raw values estimate_Rsq(deviance_null = 1472.455, deviance_full = 1341.497, p_null = 3, p_full = 5, resvar_null = 0.722, resvar_full = 0.562) # Distinguishable APIM — gls, must be in two-intercept form m_twoint <- switch_to_twoint(m_interact, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") estimate_Rsq(m_twoint, indistinguishable = FALSE, person_1 = "man", person_2 = "woman") # Distinguishable APIM — glmmTMB, RE must use explicit dummy codes estimate_Rsq(model_full = fulldismodel_REML, indistinguishable = FALSE, person_1 = "man", person_2 = "woman") # Distinguishable APIM — supply raw values estimate_Rsq(indistinguishable = FALSE, deviance_null = 1187.010, deviance_full = 1137.756, deviance_p1 = 1176.509, deviance_p2 = 1169.441, p_null = 5, p_full = 9, p_p1 = 7, p_p2 = 7, resvar_null_p1 = 0.429, resvar_null_p2 = 0.534, resvar_full_p1 = 0.389, resvar_full_p2 = 0.473, person_1 = "man", person_2 = "woman") ## End(Not run)
Computes and plots Johnson-Neyman regions of significance for the effect
of a focal predictor across the observed range of a moderator variable.
Supports models fitted with glmmTMB, lme, or gls.
Three methods are available for degrees of freedom via df_method:
"z" (default)Large-sample z-test for all model types.
"t"t-test using residual df from the model. Available
for gls and lme only. For lme, residual df are
used rather than per-term df. Not available for glmmTMB;
falls back to "z" with a warning.
"satterthwaite"Satterthwaite df computed on a coarse
grid and interpolated across the moderator range. Available for
glmmTMB with dispformula = ~0 only. Falls back to
"t" for gls and lme with a warning.
johnson_neyman( model, pred, modx, data, alpha = 0.05, n_mod = 1000, df_method = c("z", "t", "satterthwaite"), sw_grid = 20, eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), title = NULL, ylabel = NULL, verbose = FALSE )johnson_neyman( model, pred, modx, data, alpha = 0.05, n_mod = 1000, df_method = c("z", "t", "satterthwaite"), sw_grid = 20, eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), title = NULL, ylabel = NULL, verbose = FALSE )
model |
A fitted model object of class |
pred |
Character string. Name of the focal predictor. |
modx |
Character string. Name of the moderator variable. |
data |
A |
alpha |
Numeric. Significance level. Default is |
n_mod |
Integer. Number of points in the moderator grid. Default
is |
df_method |
Character string. One of |
sw_grid |
Integer. Number of coarse grid points for Satterthwaite
df computation when |
eps |
Numeric. Step size for Jacobian in Satterthwaite computation.
Default is |
n_cores |
Integer. Number of parallel workers for Satterthwaite computation. Default is all physical cores. |
title |
Character string. Plot title. Auto-generated if |
ylabel |
Character string. Y-axis label. Auto-generated if
|
verbose |
Logical. Print progress during Satterthwaite computation.
Default is |
Invisibly returns a data.frame with columns:
Moderator values across the grid.
Simple slope of pred.
Standard error of the simple slope.
Degrees of freedom.
Two-tailed p-value.
## Not run: # glmmTMB with Satterthwaite df johnson_neyman( model = ind_moderation_socA, pred = "c_PosBehavior_A", modx = "c_Support_A", data = pairwise_indisting, df_method = "satterthwaite", sw_grid = 20 ) # gls with residual df t-test johnson_neyman( model = ind_moderation_bdyad_gls, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) # lme with residual df t-test johnson_neyman( model = ind_moderation_bdyad_lme, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) ## End(Not run)## Not run: # glmmTMB with Satterthwaite df johnson_neyman( model = ind_moderation_socA, pred = "c_PosBehavior_A", modx = "c_Support_A", data = pairwise_indisting, df_method = "satterthwaite", sw_grid = 20 ) # gls with residual df t-test johnson_neyman( model = ind_moderation_bdyad_gls, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) # lme with residual df t-test johnson_neyman( model = ind_moderation_bdyad_lme, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) ## End(Not run)
Works for any random-effect covariance structure (us, homcs, ar1, toep, ...) by computing dV/dtheta numerically via model refits – no tape interaction.
kr_glmmTMB_no_resid( model, data = NULL, eps = 1e-04, n_cores = parallel::detectCores(logical = FALSE), verbose = TRUE )kr_glmmTMB_no_resid( model, data = NULL, eps = 1e-04, n_cores = parallel::detectCores(logical = FALSE), verbose = TRUE )
model |
fitted glmmTMB object with dispformula = ~0 and REML = TRUE |
eps |
step size for central differences (default 1e-4) |
n_cores |
parallel workers for dV/dtheta (default: all physical cores) |
verbose |
print progress and results |
data.frame: Term, Estimate, SE (KR-adjusted), df, t, p attribute "vcov_kr": KR-adjusted fixed-effect vcov matrix
Tests an arbitrary linear combination of fixed effects for
models fitted with glmmTMB, gls, or lme. Three
methods are available for computing degrees of freedom, controlled by the
df_method argument:
"z" (default)Large-sample z-test for all model types.
"t"t-test using residual df from the model. Available for
gls and lme only. For lme, residual df are used
for all terms rather than per-term df. Not available for
glmmTMB; falls back to "z" with a warning.
"satterthwaite"Satterthwaite df via numerical
differentiation of the contrast variance. Available for glmmTMB
with dispformula = ~0 only. Falls back to "t" for
gls and lme with a warning.
linear_contrast( model, L, label = "Contrast", alpha = 0.05, df_method = c("z", "t", "satterthwaite"), eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), verbose = FALSE )linear_contrast( model, L, label = "Contrast", alpha = 0.05, df_method = c("z", "t", "satterthwaite"), eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), verbose = FALSE )
model |
A fitted model object of class |
L |
A named numeric vector of contrast weights. Names must match
coefficient names in the model. Coefficients not named in |
label |
A character string label for the contrast. Default is
|
alpha |
Numeric. Significance level for confidence intervals.
Default is |
df_method |
Character string specifying the method for degrees of
freedom. One of |
eps |
Numeric. Step size for Jacobian in Satterthwaite computation.
Only used when |
n_cores |
Integer. Number of parallel workers for Satterthwaite computation. Default is all physical cores. |
verbose |
Logical. Print progress during Satterthwaite computation.
Default is |
Invisibly returns a data.frame with columns:
Contrast label.
Estimated value of .
Standard error.
Degrees of freedom.
t- or z-statistic.
Two-tailed p-value.
Lower confidence interval bound.
Upper confidence interval bound.
## Not run: # simple slope of c_PosBehavior_A at low support (w = -1.31) # glmmTMB with Satterthwaite df linear_contrast( model = ind_moderation_socA, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Support_A" = -1.31), label = "Actor simple slope at Low Support", df_method = "satterthwaite" ) # gls with residual df t-test linear_contrast( model = ind_moderation_bdyad_gls, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Rellengthyrs" = -6.04), label = "Actor simple slope at Low Rellengthyrs", df_method = "t" ) # lme with residual df t-test linear_contrast( model = ind_moderation_bdyad_lme, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Rellengthyrs" = -6.04), label = "Actor simple slope at Low Rellengthyrs", df_method = "t" ) ## End(Not run)## Not run: # simple slope of c_PosBehavior_A at low support (w = -1.31) # glmmTMB with Satterthwaite df linear_contrast( model = ind_moderation_socA, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Support_A" = -1.31), label = "Actor simple slope at Low Support", df_method = "satterthwaite" ) # gls with residual df t-test linear_contrast( model = ind_moderation_bdyad_gls, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Rellengthyrs" = -6.04), label = "Actor simple slope at Low Rellengthyrs", df_method = "t" ) # lme with residual df t-test linear_contrast( model = ind_moderation_bdyad_lme, L = c(c_PosBehavior_A = 1, "c_PosBehavior_A:c_Rellengthyrs" = -6.04), label = "Actor simple slope at Low Rellengthyrs", df_method = "t" ) ## End(Not run)
Computes simple slopes of a focal predictor at specified values of a
moderator variable (the pick-a-point or spotlight approach). Supports
models fitted with glmmTMB, lme, or gls. Three
methods are available for degrees of freedom via df_method:
"z" (default)Large-sample z-test for all model types.
"t"t-test using residual df. Available for gls
and lme only. For lme, residual df are used for all
simple slopes rather than per-term df. Not available for
glmmTMB; falls back to "z" with a warning.
"satterthwaite"Satterthwaite df computed separately for
each simple slope via numerical differentiation of the contrast
variance. Available for glmmTMB with dispformula = ~0
only. Falls back to "t" for gls and lme with
a warning.
pick_a_point( model, pred, modx, data, points = c("mean-sd", "mean", "mean+sd"), alpha = 0.05, df_method = c("z", "t", "satterthwaite"), eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), verbose = FALSE )pick_a_point( model, pred, modx, data, points = c("mean-sd", "mean", "mean+sd"), alpha = 0.05, df_method = c("z", "t", "satterthwaite"), eps = 0.001, n_cores = parallel::detectCores(logical = FALSE), verbose = FALSE )
model |
A fitted model object of class |
pred |
Character string. Name of the focal predictor. |
modx |
Character string. Name of the moderator variable. |
data |
A |
points |
Either a character vector of keywords ( |
alpha |
Numeric. Significance level. Default is |
df_method |
Character string. One of |
eps |
Numeric. Step size for Jacobian in Satterthwaite computation.
Default is |
n_cores |
Integer. Number of parallel workers for Satterthwaite computation. Default is all physical cores. |
verbose |
Logical. Print progress during Satterthwaite computation.
Default is |
Invisibly returns a data.frame with columns:
Description of the moderator value.
Numeric value of the moderator.
Estimated simple slope of pred.
Standard error of the simple slope.
Degrees of freedom.
t- or z-statistic.
Two-tailed p-value.
Lower confidence interval bound.
Upper confidence interval bound.
Significance indicator (* if p < alpha).
## Not run: # glmmTMB with Satterthwaite df pick_a_point( model = ind_moderation_socA, pred = "c_PosBehavior_A", modx = "c_Support_A", data = pairwise_indisting, df_method = "satterthwaite" ) # gls with residual df t-test pick_a_point( model = ind_moderation_bdyad_gls, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) # lme with residual df t-test pick_a_point( model = ind_moderation_bdyad_lme, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) ## End(Not run)## Not run: # glmmTMB with Satterthwaite df pick_a_point( model = ind_moderation_socA, pred = "c_PosBehavior_A", modx = "c_Support_A", data = pairwise_indisting, df_method = "satterthwaite" ) # gls with residual df t-test pick_a_point( model = ind_moderation_bdyad_gls, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) # lme with residual df t-test pick_a_point( model = ind_moderation_bdyad_lme, pred = "c_PosBehavior_A", modx = "c_Rellengthyrs", data = pairwise_indisting, df_method = "t" ) ## End(Not run)
Produces response surface plots from the output of
run_dyadic_rsa. Two plot types are available: an interactive
3D surface using plotly (default), and a static black-and-white
wireframe plot using lattice matching the style of
RSA::plotRSA. One panel is produced per surface (overall, and one
per group in mod_values). The actor axis is reversed by default
to match RSA::plotRSA orientation. The line of congruence
(actor = partner) and line of incongruence (actor = -partner) are overlaid
on each surface.
plot_dyadic_rsa( rsa_out, actor, partner, moderator = NULL, mod_values = NULL, type = "interactive", xlim = c(-3, 3), ylim = c(-3, 3), n = NULL, xlab = "Actor", ylab = "Partner", zlab = "Outcome", rotation = list(x = -63, y = 32, z = 15) )plot_dyadic_rsa( rsa_out, actor, partner, moderator = NULL, mod_values = NULL, type = "interactive", xlim = c(-3, 3), ylim = c(-3, 3), n = NULL, xlab = "Actor", ylab = "Partner", zlab = "Outcome", rotation = list(x = -63, y = 32, z = 15) )
rsa_out |
A list returned by |
actor |
Character string. Name of the actor predictor — must match
the value passed to |
partner |
Character string. Name of the partner predictor — must
match the value passed to |
moderator |
Character string or |
mod_values |
Named list or |
type |
Character string. Plot type: |
xlim |
Numeric vector of length 2. Range of the actor axis.
Default |
ylim |
Numeric vector of length 2. Range of the partner axis.
Default |
n |
Integer. Number of grid points along each axis.
Default |
xlab |
Character string. Label for the actor axis.
Default |
ylab |
Character string. Label for the partner axis.
Default |
zlab |
Character string. Label for the outcome axis.
Default |
rotation |
Named list. Rotation angles for static plot.
Default |
Invisibly returns a named list of plot objects, one per panel.
Schönbrodt, F. D., Humberg, S., & Nestler, S. (2018). Testing similarity effects with dyadic response surface analysis. European Journal of Personality, 32(6), 627–641. doi:10.1002/per.2169
## Not run: rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1) ) # Interactive plotly plot_dyadic_rsa( rsa_out = rsa_out, actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), type = "interactive" ) # Static B&W wireframe plot_dyadic_rsa( rsa_out = rsa_out, actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), type = "static" ) ## End(Not run)## Not run: rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1) ) # Interactive plotly plot_dyadic_rsa( rsa_out = rsa_out, actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), type = "interactive" ) # Static B&W wireframe plot_dyadic_rsa( rsa_out = rsa_out, actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), type = "static" ) ## End(Not run)
Fits a dyadic response surface analysis (RSA) model using glmmTMB,
computes RSA parameters a1–a5 for the overall surface and optionally for
subgroups defined by a moderator variable, and tests moderation of the
response surface. Validated against the dyadic RSA framework of Schönbrodt,
Humberg, & Nestler (2018).
run_dyadic_rsa( data, outcome, actor, partner, re_term, moderator = NULL, mod_values = NULL, alpha = 0.05, df_method = "z", reml = TRUE )run_dyadic_rsa( data, outcome, actor, partner, re_term, moderator = NULL, mod_values = NULL, alpha = 0.05, df_method = "z", reml = TRUE )
data |
A data frame. |
outcome |
Character string. Name of the outcome variable. |
actor |
Character string. Name of the (centered) actor predictor. |
partner |
Character string. Name of the (centered) partner predictor. |
re_term |
Character string. The random effects term exactly as it
should appear in the model formula, e.g.
|
moderator |
Character string or |
mod_values |
Named list or |
alpha |
Numeric. Significance level for confidence intervals.
Default |
df_method |
Character string. Degrees-of-freedom method passed to
|
reml |
Logical. Whether to use REML estimation. Default |
The function automatically constructs the five polynomial terms required for
RSA (actor², partner², actor×partner) and builds the fixed-effects formula.
When a moderator is supplied, all five RSA terms are interacted with the
moderator, and surfaces are estimated at each value supplied in
mod_values as well as at the grand mean (moderator = 0), which under
effect coding equals the unweighted average of the group surfaces.
RSA parameters are estimated as linear contrasts of the fixed effects using
linear_contrast:
Slope along the line of congruence (actor + partner).
Curvature along the line of congruence (actor² + actor×partner + partner²).
Slope along the line of incongruence (actor - partner).
Curvature along the line of incongruence (actor² - actor×partner + partner²).
Rotation of the principal axis (actor² - partner²).
Results have been verified to be numerically identical (differences < 1e-5) to the lavaan-based dyadic RSA implementation of Schönbrodt et al. (2018) when both are estimated with maximum likelihood.
Invisibly returns a named list with components:
The fitted glmmTMB model object.
A named list of data.frames with RSA contrast
results. Always includes $overall. When mod_values is
supplied, also includes one element per group and $moderation.
Named numeric vector of fixed-effect estimates.
Character vector of fixed-effect names.
Schönbrodt, F. D., Humberg, S., & Nestler, S. (2018). Testing similarity effects with dyadic response surface analysis. European Journal of Personality, 32(6), 627–641. doi:10.1002/per.2169
## Not run: # Without moderator — single overall surface rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", df_method = "z" ) # With gender moderator — overall, group, and moderation surfaces rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), df_method = "z" ) # Access results rsa_out$model # glmmTMB model object rsa_out$results$overall # overall surface rsa_out$results$Men # men's surface rsa_out$results$Women # women's surface rsa_out$results$moderation # moderation tests ## End(Not run)## Not run: # Without moderator — single overall surface rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", df_method = "z" ) # With gender moderator — overall, group, and moderation surfaces rsa_out <- run_dyadic_rsa( data = pairwise_data, outcome = "RelSat_A", actor = "c_PosEmotion_A", partner = "c_PosEmotion_P", re_term = "cs(0 + as.factor(ECGender_A) | DyadID)", moderator = "ECGender_A", mod_values = list(Men = 1, Women = -1), df_method = "z" ) # Access results rsa_out$model # glmmTMB model object rsa_out$results$overall # overall surface rsa_out$results$Men # men's surface rsa_out$results$Women # women's surface rsa_out$results$moderation # moderation tests ## End(Not run)
Kenward-Roger summary for glmmTMB models
summary_glmmTMB_kr( model, eps = 1e-04, n_cores = 1L, digits = 5, alpha = 0.05, verbose = FALSE )summary_glmmTMB_kr( model, eps = 1e-04, n_cores = 1L, digits = 5, alpha = 0.05, verbose = FALSE )
model |
a fitted glmmTMB object (REML recommended) |
eps |
step size for central differences in dV/dtheta (only used when dispformula = ~0) |
n_cores |
parallel workers for dV/dtheta refits (only used when dispformula = ~0) |
digits |
decimal places in printed output (currently unused, kept for API consistency with satterthwaite version) |
alpha |
significance level for confidence intervals |
verbose |
print progress from kr_glmmTMB_no_resid() |
invisibly: list(kenward_roger, vc, fit_stats) kenward_roger: data.frame with Term, Estimate, SE, df, t, p, lower, upper vc: VarCorr(model)$cond fit_stats: named numeric vector of AIC, BIC, logLik, -2*log(L), df.resid
Produces a formatted summary for a fitted glmmTMB model using
Satterthwaite degrees of freedom for fixed effects. Confidence intervals
are computed using Satterthwaite df and included in the fixed effects table.
summary_glmmTMB_satterthwaite( model, eps = 0.001, digits = 5, alpha = 0.05, verbose = FALSE )summary_glmmTMB_satterthwaite( model, eps = 0.001, digits = 5, alpha = 0.05, verbose = FALSE )
model |
A fitted |
eps |
Numeric. Step size for central differences in the Jacobian.
Only used when |
digits |
Integer. Number of digits for rounding. Default is |
alpha |
Numeric. Significance level for confidence intervals.
Default is |
verbose |
Logical. If |
Invisibly returns a list with elements: satterthwaite (data frame with Term, Estimate, SE, df, t, p, lower, upper), vc (VarCorr output), and fit_stats (named vector of AIC, BIC, logLik, -2*log(L), df.resid).
## Not run: m <- glmmTMB::glmmTMB(y ~ x, data = dat) summary_glmmTMB_satterthwaite(m) summary_glmmTMB_satterthwaite(m, alpha = 0.10) ## End(Not run)## Not run: m <- glmmTMB::glmmTMB(y ~ x, data = dat) summary_glmmTMB_satterthwaite(m) summary_glmmTMB_satterthwaite(m, alpha = 0.10) ## End(Not run)
Reformulates a fitted gls or glmmTMB Distinguishable Actor-Partner
Interdependence Model (APIM) from the two-intercept parameterisation to the
equivalent interaction approach. The two parameterisations are statistically
equivalent; a numerical ML deviance check confirms this before returning.
For gls models, non-formula arguments (correlation,
weights, na.action) are preserved automatically by
update().
switch_to_interact(object = NULL, disting_variable = NULL)switch_to_interact(object = NULL, disting_variable = NULL)
object |
A fitted |
disting_variable |
Character. Name of the effect-coded distinguishing
variable (e.g. |
A fitted model object of the same class as object,
reformulated using the interaction approach and estimated with the same
method as the original (REML for glmmTMB; the original
method for gls). Stops with an informative message if the
ML deviance of the reformulated model differs from the original.
## Not run: # gls with dummy codes m_twoint <- gls(RelSat_A ~ 0 + man + woman + man:c_Amity_A + woman:c_Amity_A + man:c_Amity_P + woman:c_Amity_P, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_interact <- switch_to_interact(object = m_twoint, disting_variable = "ECGender_A") # gls with as.factor() distinguishing variable m_twoint_f <- gls(RelSat_A ~ 0 + as.factor(ECGender_A) + as.factor(ECGender_A):c_Amity_A + as.factor(ECGender_A):c_Amity_P, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_interact_f <- switch_to_interact(object = m_twoint_f, disting_variable = "ECGender_A") # glmmTMB m_twoint_tmb <- glmmTMB(RelSat_A ~ 0 + man + woman + man:c_Amity_A + woman:c_Amity_A + man:c_Amity_P + woman:c_Amity_P + cs(0 + man + woman | DyadID), dispformula = ~0, REML = TRUE, data = pairwise_disting) m_interact_tmb <- switch_to_interact(object = m_twoint_tmb, disting_variable = "ECGender_A") ## End(Not run)## Not run: # gls with dummy codes m_twoint <- gls(RelSat_A ~ 0 + man + woman + man:c_Amity_A + woman:c_Amity_A + man:c_Amity_P + woman:c_Amity_P, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_interact <- switch_to_interact(object = m_twoint, disting_variable = "ECGender_A") # gls with as.factor() distinguishing variable m_twoint_f <- gls(RelSat_A ~ 0 + as.factor(ECGender_A) + as.factor(ECGender_A):c_Amity_A + as.factor(ECGender_A):c_Amity_P, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_interact_f <- switch_to_interact(object = m_twoint_f, disting_variable = "ECGender_A") # glmmTMB m_twoint_tmb <- glmmTMB(RelSat_A ~ 0 + man + woman + man:c_Amity_A + woman:c_Amity_A + man:c_Amity_P + woman:c_Amity_P + cs(0 + man + woman | DyadID), dispformula = ~0, REML = TRUE, data = pairwise_disting) m_interact_tmb <- switch_to_interact(object = m_twoint_tmb, disting_variable = "ECGender_A") ## End(Not run)
Reformulates a fitted gls or glmmTMB Distinguishable Actor-Partner
Interdependence Model (APIM) from the interaction approach parameterisation to the
equivalent two-intercept approach. The two parameterisations are
statistically equivalent; a numerical ML deviance check confirms this before
returning.
The two-intercept approach suppresses the global intercept and estimates a
separate intercept for each dyad member, with all predictors crossed with
their respective group dummy variable using :.
For gls models, non-formula arguments (correlation,
weights, na.action) are preserved automatically by
update().
switch_to_twoint( object = NULL, disting_variable = NULL, disting_level_1 = NULL, disting_level_2 = NULL )switch_to_twoint( object = NULL, disting_variable = NULL, disting_level_1 = NULL, disting_level_2 = NULL )
object |
A fitted |
disting_variable |
Character. Name of the effect-coded distinguishing
variable (e.g. |
disting_level_1 |
Character. Name of the dummy-coded variable for the
first dyad member in the dataset (e.g. |
disting_level_2 |
Character. Name of the dummy-coded variable for the
second dyad member in the dataset (e.g. |
A fitted model object of the same class as object,
reformulated using the two-intercept approach and estimated with the same
method as the original (REML for glmmTMB; the original
method for gls). Stops with an informative message if the
ML deviance of the reformulated model differs from the original.
## Not run: # gls m_interact <- gls(RelSat_A ~ c_Amity_A * ECGender_A + c_Amity_P * ECGender_A, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_twoint <- switch_to_twoint(object = m_interact, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") # glmmTMB m_interact_tmb <- glmmTMB(RelSat_A ~ c_Amity_A * ECGender_A + c_Amity_P * ECGender_A + cs(0 + man + woman | DyadID), dispformula = ~0, REML = TRUE, data = pairwise_disting) m_twoint_tmb <- switch_to_twoint(object = m_interact_tmb, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") ## End(Not run)## Not run: # gls m_interact <- gls(RelSat_A ~ c_Amity_A * ECGender_A + c_Amity_P * ECGender_A, correlation = corCompSymm(form = ~1 | DyadID), weights = varIdent(form = ~1 | ECGender_A), data = pairwise_disting) m_twoint <- switch_to_twoint(object = m_interact, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") # glmmTMB m_interact_tmb <- glmmTMB(RelSat_A ~ c_Amity_A * ECGender_A + c_Amity_P * ECGender_A + cs(0 + man + woman | DyadID), dispformula = ~0, REML = TRUE, data = pairwise_disting) m_twoint_tmb <- switch_to_twoint(object = m_interact_tmb, disting_variable = "ECGender_A", disting_level_1 = "man", disting_level_2 = "woman") ## End(Not run)