| Title: | Relational Event and Durational Event Models |
|---|---|
| Description: | Model relational and durational events in a counting process framework, with functions for estimating and simulating Relational Event Models (REM) and Durational Event Models (DEM). Includes support for time-varying covariates, windowed statistics, and high-dimensional node-level fixed effects. References include Fritz et al. (2026) "Scalable Durational Event Models: Application to Physical and Digital Interactions" <https://arxiv.org/abs/2504.00049>. |
| Authors: | Cornelius Fritz [aut, cre] |
| Maintainer: | Cornelius Fritz <[email protected]> |
| License: | GPL-3 |
| Version: | 1.0.0 |
| Built: | 2026-06-23 10:49:45 UTC |
| Source: | https://github.com/corneliusfritz/redeem |
This function checks the validity of a dyadic interaction matrix by ensuring that each interaction start event has a corresponding end event, that no interactions overlap within a dyad, and that no missing values are present.
check_matrix(df, return_matrix = FALSE, start_time = NULL)check_matrix(df, return_matrix = FALSE, start_time = NULL)
df |
A data frame with at least four columns, representing events, where:
|
return_matrix |
Logical; if TRUE, returns the (potentially repaired) event matrix.
Defaults to FALSE, in which case the function returns |
start_time |
Numeric; optional reference time for adding missing start events. Defaults to NULL, in which case the earliest time in the data is used. |
The function performs the following checks:
Missing values: If any are found, a warning is issued and FALSE is returned.
Interaction pairing: Each start event (1) must have a corresponding end event (0) without overlap.
Non-overlapping intervals: Ensures that no start event occurs while another interaction is active.
Logical; TRUE if all interactions are valid, FALSE otherwise.
If the data contains missing values, the function issues a warning and returns FALSE.
# Create a valid event matrix with durational events (start=1, end=0) df <- matrix(c( 1.0, 1, 2, 1, 2.0, 1, 2, 0, 1.5, 3, 4, 1, 3.0, 3, 4, 0 ), ncol = 4, byrow = TRUE) colnames(df) <- c("time", "from", "to", "type") # Check if the event matrix is valid check_matrix(df)# Create a valid event matrix with durational events (start=1, end=0) df <- matrix(c( 1.0, 1, 2, 1, 2.0, 1, 2, 0, 1.5, 3, 4, 1, 3.0, 3, 4, 0 ), ncol = 4, byrow = TRUE) colnames(df) <- c("time", "from", "to", "type") # Check if the event matrix is valid check_matrix(df)
Unified control object to manage estimation parameters for rem
and dem functions.
control.redeem( it_max = 100, tol = 1e-10, accelerated = FALSE, verbose = FALSE, weighting = TRUE, subsample = 1, build_time = NULL, use_glm = FALSE, return_data = FALSE, save_hist = TRUE, estimate = "Blockwise", legacy = FALSE, check_matrix = FALSE, inf_unidentifiable = TRUE )control.redeem( it_max = 100, tol = 1e-10, accelerated = FALSE, verbose = FALSE, weighting = TRUE, subsample = 1, build_time = NULL, use_glm = FALSE, return_data = FALSE, save_hist = TRUE, estimate = "Blockwise", legacy = FALSE, check_matrix = FALSE, inf_unidentifiable = TRUE )
it_max |
Integer; maximum number of iterations for the algorithm. Defaults to 100. |
tol |
Numeric; convergence tolerance. Defaults to 1e-10. |
accelerated |
Logical; if |
verbose |
Logical; if |
weighting |
Logical; whether to use weighting to group identical observations. Defaults to TRUE. |
subsample |
Numeric; proportion of data to subsample for internal GLM checks. Defaults to 1. |
build_time |
Numeric; time at which to start building the estimation dataset. Events before this time are used to compute statistics but not included as observations. Defaults to NULL, in which case all events are included. |
use_glm |
Logical; if |
return_data |
Logical; whether to return preprocessed data frames in the result. Defaults to FALSE. |
save_hist |
Logical; whether to save the iteration history of coefficients. Defaults to TRUE. |
estimate |
Character; estimation method for |
legacy |
Logical; if |
check_matrix |
Logical; whether to apply |
inf_unidentifiable |
Logical; whether to set unidentifiable
coefficients (e.g., actors with 0 event counts, globally
invariant/collinear covariates) to |
A list of class "redeem_control" containing the specified
parameters.
Estimates a Durational Event Model (DEM) for relational event sequences where interactions have a duration.
dem( events, training_start = 0, exogenous_end = NULL, formula_0_1 = NULL, formula_1_0 = NULL, n_nodes = NULL, directed = FALSE, estimate_0_1 = NULL, estimate_1_0 = NULL, coef_0_1 = NULL, coef_1_0 = NULL, semiparametric = FALSE, simultaneous_interactions = TRUE, control = control.redeem() )dem( events, training_start = 0, exogenous_end = NULL, formula_0_1 = NULL, formula_1_0 = NULL, n_nodes = NULL, directed = FALSE, estimate_0_1 = NULL, estimate_1_0 = NULL, coef_0_1 = NULL, coef_1_0 = NULL, semiparametric = FALSE, simultaneous_interactions = TRUE, control = control.redeem() )
events |
A matrix of events with columns |
training_start |
Numeric; the time point at which to start the estimation. Defaults to 0. |
exogenous_end |
Numeric; the exogenous time point at which the observational period ends. Defaults to NULL, which implies that time when the final event was observed is taken as the end of the observational period. |
formula_0_1 |
A one-sided |
formula_1_0 |
A one-sided |
n_nodes |
Integer; the total number of actors in the network. If |
directed |
Logical; whether the interaction events are directed. Defaults to FALSE. |
estimate_0_1 |
Logical; whether to estimate the formation process.
Defaults to NULL, in which case it is estimated if |
estimate_1_0 |
Logical; whether to estimate the dissolution process.
Defaults to NULL, in which case it is estimated if |
coef_0_1 |
Numeric vector; initial coefficients for the formation model. If provided, this must be a concatenated vector of:
Defaults to NULL, in which case default starting values are automatically computed. |
coef_1_0 |
Numeric vector; initial coefficients for the dissolution model. If provided, this must be a concatenated vector of:
Defaults to NULL, in which case default starting values are automatically computed. |
semiparametric |
Logical; whether to use a semiparametric baseline. Defaults to FALSE. See the 'Semiparametric Baseline' section for details. |
simultaneous_interactions |
Logical; whether to allow simultaneous interactions (i.e. multiple active events for the same actor or dyad at the same time). Defaults to TRUE. |
control |
A list of control parameters from |
The Durational Event Model (DEM) is a general framework for analyzing durational events, extending standard Relational Event Models (REM) by decoupling the modeling of event incidence from event duration. It characterizes the dynamics via two separate continuous-time counting processes:
)Counts the number of times that
actor pair starts an interaction up to time . The incidence intensity
is denoted by .
)Counts the number of times that
actor pair stops interacting up to time . The dissolution intensity
is denoted by .
Under the assumption that the processes are non-homogeneous Poisson processes, the intensities are modeled as:
where:
is a vector of dynamic network statistics
capturing the history of past interactions .
is a parameter vector determining the covariate effects.
and are actor-specific sociality/popularity
parameters (degree correction) capturing actor heterogeneity.
is a piecewise-constant step function modeling
temporal baseline fluctuations across a set of changepoints.
To satisfy the Feller criterion and ensure that the continuous-time
counting process remains non-explosive, count-based network statistics
(such as inertia or common partners) are typically log-transformed on
the scale.
An object of class dem_object containing model estimates,
log-likelihoods, and preprocessed data. See dem_object
for details on the components of the returned object and S3 methods.
The likelihood of the model is separable with respect to
and , allowing
independent estimation of the incidence and duration components.
Traditional maximum likelihood estimation via standard Newton-Raphson
requires computing and inverting an Hessian matrix, which
is computationally prohibitive for larger networks. To bypass this, the
redeem package implements a highly scalable block-coordinate
ascent algorithm that separates parameter updates:
Step 1: Update covariate parameters using
a standard Newton-Raphson update.
Step 2: Update high-dimensional actor popularity
baselines using Minorization-Maximization
(MM) steps, avoiding explicit matrix inversion.
Step 3: Update baseline step function parameters
via a closed-form step.
More information is provided in Fritz et at. (2026).
When semiparametric = TRUE, the baseline rates for both the formation
() and dissolution () processes are
left completely unspecified. Both processes are estimated as separate Cox proportional
hazards models using the survival package. In this path:
For the formation process, each start event (1) is treated as a failure, and all inactive dyads at that time constitute the risk set.
For the dissolution process, each end event (0) is treated as a failure, and all currently active interactions constitute the risk set.
The exact waiting times (durations of the active and inactive states) are conditioned out, and estimation is based solely on the ordering of events and the relative dyadic intensities at each transition time.
This approach is highly robust to arbitrary temporal fluctuations in baseline rates since no piecewise-constant temporal baselines or changepoints need to be specified.
Limitations: This path does not support the specialized
scalable estimation of sender/receiver popularity effects (degree) or
piecewise-constant temporal baselines.
Fritz, C., Rastelli, R., Fop, M., & Caimo, A. (2026). Scalable Durational Event Models: Application to Physical and Digital Interactions. arXiv:2504.00049.
# Simulate some durational data n <- 20 events <- matrix(c( 1.2, 1, 5, 1, 2.5, 1, 5, 0, 3.1, 2, 8, 1, 4.4, 2, 8, 0 ), ncol = 4, byrow = TRUE) colnames(events) <- c("time", "from", "to", "type") # Estimate a simple DEM fit <- dem( events = events, n_nodes = n, formula_0_1 = ~1, formula_1_0 = ~1, control = control.redeem(estimate = "Blockwise") ) summary(fit)# Simulate some durational data n <- 20 events <- matrix(c( 1.2, 1, 5, 1, 2.5, 1, 5, 0, 3.1, 2, 8, 1, 4.4, 2, 8, 0 ), ncol = 4, byrow = TRUE) colnames(events) <- c("time", "from", "to", "type") # Estimate a simple DEM fit <- dem( events = events, n_nodes = n, formula_0_1 = ~1, formula_1_0 = ~1, control = control.redeem(estimate = "Blockwise") ) summary(fit)
An object of class dem returned by the dem function,
representing a fitted Durational Event Model.
A dem object is a list containing the following components:
call: The matched call.
event_numbers: A vector containing the number of events.
model_0_1: The fitted model for transition 0 -> 1 (formation).
model_1_0: The fitted model for transition 1 -> 0 (dissolution).
events: The preprocessed event matrix.
formula_0_1: The formula for transition 0 -> 1.
formula_1_0: The formula for transition 1 -> 0.
n_nodes: The number of nodes.
simultaneous_interactions: Logical indicating whether
simultaneous interactions were allowed.
directed: Logical indicating whether the events are directed.
training_start: The start time of the training period.
build_time: The time at which the estimation dataset started
building.
max_time: The maximum event time.
exogenous_end: The end time of the exogenous period.
time_changepoints: Time points where baseline intensity changes.
labels_changepoints: Labels for the time intervals.
subsample: Subsample proportion used.
return_data: Logical indicating whether preprocessed data
frames were returned.
runtime: The estimation runtime.
window_map: The window map used for calculation.
preprocessed: Preprocessed data structures.
The following S3 methods are implemented for dem objects:
print(x, ...): Prints a brief summary of the DEM model.
x: A dem object.
...: Additional arguments passed to printing function.
summary(object, ...): Summarizes model results, including
parameter estimates, standard errors, and fit statistics (AIC/BIC).
Returns an object of class summary.dem.
object: A dem object.
...: Additional arguments passed to summary method.
plot(x, which = 3, separate = FALSE, baseline = FALSE, ...):
Generates trace plots for coefficients and log-likelihood histories.
x: A dem object.
which: Integer indicating transition plots to display.
Options are 1 for formation (0 -> 1), 2 for
dissolution (1 -> 0), or 3 (default) for both.
separate: Logical. If TRUE, each plot is
generated in a new window or as a separate sequence.
Defaults to FALSE.
baseline: Logical. If TRUE, plots the estimated
baseline step function. Defaults to FALSE.
...: Additional arguments passed to the underlying
trace plotting method. Supported parameters include:
coefs: Logical. If TRUE (default), plots
iteration traces for core/fixed coefficients.
degree: Logical. If TRUE (default), plots
iteration traces for degree/actor effects.
time: Logical. If TRUE (default), plots
iteration traces for temporal baseline effects.
llh: Logical. If TRUE (default), plots
trace of log-likelihood history.
sub_label: Character. Optional subtitle to display
at the bottom of the figure.
plot_baseline(x, process = c("formation", "dissolution"), ...):
Plots the step function of the estimated baseline intensity.
x: A dem object.
process: Character. Specifies whether to plot the
baseline for "formation" (0 -> 1) (default) or the
"dissolution" (1 -> 0) process.
...: Additional graphical parameters passed to
plot.
predict(object, time = NULL, type = c("response", "lp", "terms"), process = c("both", "formation", "dissolution"), ...):
Predicts the intensity, linear predictor, or term contributions for a fitted DEM model.
object: A dem object.
time: Numeric vector; optional time point(s) at which to predict. Defaults to NULL.
type: Character; the type of prediction. Defaults to "response".
process: Character; the transition process to predict. Defaults to "both".
...: Additional arguments.
Simulate events based on specified formulas and coefficients
dem.simulate( events = matrix(0, 0, 4), formula_0_1 = NULL, formula_1_0 = NULL, coef_0_1 = numeric(0), coef_1_0 = numeric(0), coef_degree_0_1 = 0, coef_degree_1_0 = 0, n_events = 0, time = 0, max_events = 4e+05, n_nodes, verbose = FALSE, baseline_0_1 = NULL, baseline_1_0 = NULL, simultaneous_interactions = TRUE, seed = 123, directed = FALSE )dem.simulate( events = matrix(0, 0, 4), formula_0_1 = NULL, formula_1_0 = NULL, coef_0_1 = numeric(0), coef_1_0 = numeric(0), coef_degree_0_1 = 0, coef_degree_1_0 = 0, n_events = 0, time = 0, max_events = 4e+05, n_nodes, verbose = FALSE, baseline_0_1 = NULL, baseline_1_0 = NULL, simultaneous_interactions = TRUE, seed = 123, directed = FALSE )
events |
A matrix representing the initial events with columns |
formula_0_1 |
A one-sided |
formula_1_0 |
A one-sided |
coef_0_1 |
Numeric vector; coefficients for the formation process ( |
coef_1_0 |
Numeric vector; coefficients for the dissolution process ( |
coef_degree_0_1 |
Numeric; degree coefficient for the formation process ( |
coef_degree_1_0 |
Numeric; degree coefficient for the dissolution process ( |
n_events |
Integer; number of events to simulate. Defaults to 0. |
time |
Numeric; simulation time limit. Defaults to 0. |
max_events |
Integer; maximum number of total events. Defaults to 400000. |
n_nodes |
Integer; the total number of actors in the network. |
verbose |
Logical; if |
baseline_0_1 |
Numeric vector; baseline for the 0 to 1 transition. If the formula for this process
contains an |
baseline_1_0 |
Numeric vector; baseline for the 1 to 0 transition. Similar to |
simultaneous_interactions |
Logical; whether to allow simultaneous interactions (i.e. multiple active events for the same actor or dyad at the same time). Defaults to TRUE. |
seed |
Integer; random seed for simulation. Defaults to 123. |
directed |
Logical; whether the interaction events are directed. Defaults to FALSE. |
A matrix of simulated events.
Multi-stream event models are currently not supported in simulation.
# Simulate events from a DEM model structure n <- 10 f_0_1 <- ~ 1 + inertia(transformation = "identity") f_1_0 <- ~ 1 # Simulating events evs <- dem.simulate( formula_0_1 = f_0_1, formula_1_0 = f_1_0, n_nodes = n, time = 2.0, coef_0_1 = c(1.0, 0.5), coef_1_0 = c(-0.5), seed = 42, max_events = 100 ) head(evs)# Simulate events from a DEM model structure n <- 10 f_0_1 <- ~ 1 + inertia(transformation = "identity") f_1_0 <- ~ 1 # Simulating events evs <- dem.simulate( formula_0_1 = f_0_1, formula_1_0 = f_1_0, n_nodes = n, time = 2.0, coef_0_1 = c(1.0, 0.5), coef_1_0 = c(-0.5), seed = 42, max_events = 100 ) head(evs)
This function computes the out-of-sample log-likelihood (a strictly proper scoring rule) for each test event under a fitted REM or DEM.
get_oos_likelihood( object, verbose = FALSE, edgelist_test, edgelist_train = NULL, baseline_method = c("last", "trend", "mean", "beginning"), loess_span = 0.75 )get_oos_likelihood( object, verbose = FALSE, edgelist_test, edgelist_train = NULL, baseline_method = c("last", "trend", "mean", "beginning"), loess_span = 0.75 )
object |
|
verbose |
Logical; if 'TRUE', prints verbose output. Defaults to FALSE. |
edgelist_test |
A matrix or data frame of test events (timing, from, to, type). |
edgelist_train |
A matrix or data frame of train events (timing, from, to, type). Defaults to 'NULL', in which case it retrieves the training events from the 'object' or the preprocessed data. |
baseline_method |
Character; how to compute the fixed log-baseline intensity used for out-of-sample scoring. One of: '"last"' (uses the last estimated baseline value), '"trend"' (extrapolates a LOESS trend), '"mean"', or '"beginning"'. Defaults to '"last"'. |
loess_span |
Numeric; LOESS span (0, 1] passed to
|
A numeric vector of log-likelihoods for each test event.
rem_object and dem_object for details on prediction methods.
Evaluates the out-of-sample predictive performance of a fitted model on a test event sequence using a ranking-based Goodness-of-Fit (GoF) procedure.
get_ranking( object, verbose = FALSE, k_max = 1000, edgelist_test, edgelist_train = NULL, ties.method = c("average", "first", "last", "random", "max", "min"), return_probabilities = FALSE, baseline_method = c("trend", "mean", "last", "beginning"), loess_span = 0.75 )get_ranking( object, verbose = FALSE, k_max = 1000, edgelist_test, edgelist_train = NULL, ties.method = c("average", "first", "last", "random", "max", "min"), return_probabilities = FALSE, baseline_method = c("trend", "mean", "last", "beginning"), loess_span = 0.75 )
object |
|
verbose |
Logical; if 'TRUE', prints verbose output. Defaults to FALSE. |
k_max |
Maximum number of ranked pairs to return. Defaults to 1000. |
edgelist_test |
A matrix of test events (timing, from, to, type). |
edgelist_train |
A matrix of train events (timing, from, to, type). Defaults to NULL. |
ties.method |
Character; the method to handle ties when ranking event intensities,
passed directly to
|
return_probabilities |
Logical; if TRUE, returns the predicted probabilities/scores instead of recall curves. Defaults to FALSE. |
baseline_method |
Character; how to compute the fixed log-baseline
intensity used for out-of-sample scoring. Defaults to
|
loess_span |
Numeric; LOESS span (0, 1] passed to
|
For each event observed in the test period (edgelist_test), the function:
Determines the set of all potential candidate dyads (the risk set) at that event's timestamp.
Computes the predicted event intensities (or probabilities) for all candidate dyads using the fitted model's parameters and the network history up to that moment.
Ranks all candidate dyads in descending order of their predicted intensities.
Determines the rank of the actually observed dyad.
A well-fitting model will consistently assign higher intensities to the dyads that actually interact, ranking them near the top.
The function summarizes the rankings across all test events to compute:
Mean Reciprocal Rank (MRR): The average of the reciprocal ranks of the true dyads.
Recall at K: The proportion of test events where the true dyad is ranked within the top candidate dyads.
Precision at K: The proportion of top recommendations that correspond to true events.
A ranking_redeem data frame with columns:
CutpointInteger value from 0 to k_max.
RecallThe proportion of test events where the true dyad is ranked at or within the cutpoint.
PrecisionThe precision value at the cutpoint.
Additionally, the returned object has the following attributes:
"mrr"Mean Reciprocal Rank (MRR) of the true dyads.
"mean_rank"Mean rank of the true dyads (excluding ranks > k_max).
"median_rank"Median rank of the true dyads (excluding ranks > k_max).
"hits_summary"A data frame summarizing Recall, Precision, and F1 values at K = 1, 5, 10, and 50.
Computes Cox-Snell residuals for a fitted model to diagnose goodness-of-fit and calibration.
get_residuals(object, get_0_1 = TRUE, get_1_0 = TRUE, raw = FALSE)get_residuals(object, get_0_1 = TRUE, get_1_0 = TRUE, raw = FALSE)
object |
|
get_0_1 |
Logical; if 'TRUE', computes residuals for the formation (0 -> 1) process. Defaults to TRUE. |
get_1_0 |
Logical; if 'TRUE', computes residuals for the dissolution (1 -> 0) process. Defaults to TRUE. |
raw |
Logical; if 'TRUE', returns the raw Cox-Snell residuals. Defaults to FALSE. |
Cox-Snell residuals are a standard diagnostic tool for continuous-time
survival models and counting processes.
Under the true model specification, the integrated cumulative intensity
computed up to the exact time of an observed event
is distributed as a standard exponential random variable, i.e.,
.
Consequently, if the model is correctly specified:
The empirical survival function of these residuals should
closely match the theoretical survival function of a standard
exponential distribution, .
Deviations between the empirical Kaplan-Meier curve of the residuals and the theoretical exponential curve signal model misspecification, unmodeled dyadic heterogeneity, or non-stationarity.
The function can compute residuals for both the formation/incidence
() process and the dissolution/duration
() process.
If 'raw = TRUE', a list containing the raw residuals for the selected process(es). If 'raw = FALSE', a list of data frames containing the Kaplan-Meier coordinates ('time', 'surv') and the corresponding 'theoretical' standard exponential survival values.
Cox, D. R., & Snell, E. J. (1968). A general definition of residuals. Journal of the Royal Statistical Society: Series B (Methodological), 30(2), 248-265.
Draws a step-function plot of the estimated piecewise-constant baseline
intensity against time. The function dispatches to class-specific methods
for dem, rem, and redeem_result objects.
plot_baseline(x, ...)plot_baseline(x, ...)
x |
|
... |
Additional arguments passed to |
The original object x is returned invisibly. Called
primarily for its side effect of producing a plot.
Decomposes the estimated piecewise-constant log-baseline (est_time)
into a smooth trend component (via LOESS) and a seasonal/residual component,
following the same approach used in the application plot script. The fitted
trend is then extrapolated to target_times using
predict.loess() so that the baseline used for out-of-sample scoring
reflects the long-run level of activity rather than any arbitrary fixed
value.
predict_baseline_trend(model, target_times, loess_span = 0.75)predict_baseline_trend(model, target_times, loess_span = 0.75)
model |
A |
target_times |
Numeric vector: the times at which to predict the trend (typically the unique timestamps of the test events). |
loess_span |
Numeric; the span argument passed to |
The decomposition mirrors the plot code in the application:
Build a data frame of (time, est_time) using the changepoints
stored in model$time_changepoints. The first interval [0,
changepoint_1) is given time = 0; each subsequent interval gets the
corresponding changepoint value.
Fit LOESS on the log-scale est_time values.
Predict at each target_times; predictions are clamped to the
range of the observed est_time to avoid wild extrapolation.
A numeric vector of predicted log-baseline (trend component) values,
one per element of target_times. Falls back to
mean(est_time) for each time point if there are fewer than 3
observations or if the LOESS fit fails.
The help pages of rem and dem describe the model
formulation and estimation details. This page documents all statistics
available to be used in the model formulas, characterizing the intensities
of event formation and dissolution.
In the redeem framework, models like DEM (fitted via dem)
and REM (fitted via rem) are specified using R formulas.
The right-hand side of these formulas defines the structural statistics and
covariates, where each term must be specified separately as an explicit
function call (e.g., ~ inertia() + reciprocity(window = 10)).
All terms support an optional transformation argument .
The available transformations are:
"identity" (default):
"log":
"recip":
"bin":
"sig": sigmoid-like saturation,
Throughout, denotes the cumulative number of events from
to up to (but not including) time ;
is the windowed analogue on ;
is the historical
out-degree of ; and
is the total event count sent by .
The superscript indicates that the quantity is computed
on the currently active DEM network.
The implemented terms are grouped into five categories:
Baseline and Nuisance Terms: Intercept, time-varying baseline, and degree fixed effects.
Endogenous Dyadic Terms: Inertia, reciprocity, interaction duration, and participation shifts.
Triadic Closure and Shared Partners: Common partners and triangle statistics.
Degree and Centrality Statistics: Actor degree and event count statistics.
Exogenous Covariates: Dyadic and monadic covariate terms.
K |
Numeric; the evaluation point or scaling/saturation factor for the sufficient statistic (default is 1). |
transformation |
Character; specifies the transformation to apply to the statistic. One of:
|
event_stream |
Optional matrix or data frame; an alternative event
stream to use for calculating the statistic. If |
window |
Numeric; time window for calculating the statistic (default
|
type |
Character; the specific variation of the statistic or triangle
type (e.g., |
mode |
Character; the participation shift mode (e.g., |
data |
For |
fun |
A function taking two arguments |
change_points |
Optional numeric vector; time points for time-varying
covariates if |
changepoints |
Numeric vector; time points where the baseline intensity is allowed to change. |
labels |
Character vector; optional labels for the resulting time intervals. |
history |
Character; |
count |
Logical; if |
... |
Arguments passed to the underlying initialization function. |
A redeem_term object (a list containing structural information about the statistic) to be used inside model formulas.
Most endogenous terms support covariates calculated from multiple event
streams. By providing an event_stream argument to a term (e.g.,
inertia(event_stream = other_events)), users can model one event
process while accounting for the history of another. The package
automatically handles the splintering and union of these timelines.
Intercept(): Intercept: Constant log-intensity baseline.
. Also available as intercept().
baseline(changepoints, labels): Baseline: Stepwise constant
log-baseline with user-specified change points
.
.
Coefficients are treated as nuisance parameters.
degree / degrees: Degree Fixed Effects: Node-specific sender
and receiver baselines and estimated via
Minorization-Maximization (MM).
Contribution to linear predictor: .
Treated as nuisance parameters.
inertia(transformation, K, event_stream, window): Inertia:
Cumulative count of past events from to .
; windowed: .
reciprocity(transformation, K, event_stream, window): Reciprocity:
Cumulative count of past events from to .
(Directed only).
current_interaction(transformation, K, event_stream): Duration:
Time elapsed since the currently active event started.
(DEM only). Alias: duration().
Participation Shifts (for two consecutive events
, each statistic is 1 if the specified
pattern holds, 0 otherwise; REM only, Directed only):
psABBA(event_stream): PS-ABBA: Receiver responds
to sender. .
psABBY(event_stream): PS-ABBY: Receiver initiates
to a new target. .
psABAY(event_stream): PS-ABAY: Sender initiates
to a new target. .
psABXA(event_stream): PS-ABXA: Outsider targets
original sender. .
psABXB(event_stream): PS-ABXB: Outsider targets
original receiver. .
psABXY(event_stream): PS-ABXY: Entirely new dyad.
.
ps(mode, event_stream): PS Shorthand: Dispatches to
one of the six participation shift statistics above based on
mode (one of "ABBA", "ABBY", "ABAY",
"ABXA", "ABXB", "ABXY").
general_common_partners(
transformation, K, type,
event_stream, window):
Historical Common Partners: Number of nodes sharing a historical
directed path of the specified type with both and .
.
"OSP" (Outgoing Shared Partner):
and .
"ISP" (Incoming Shared Partner):
and .
"OTP" (Outgoing Two-Path):
and .
"ITP" (Incoming Two-Path):
and .
Aliases: general_common_partner(),
general_common_partner_OSP(),
general_common_partner_ISP(),
general_common_partner_OTP(),
general_common_partner_ITP().
current_common_partners(
transformation, K, type,
event_stream):
Active Common Partners: As general_common_partners but restricted
to currently active edges.
(DEM only).
Aliases: current_common_partner(),
current_common_partner_OSP(),
current_common_partner_ISP(),
current_common_partner_OTP(),
current_common_partner_ITP().
general_triangle(transformation, K, type, event_stream, window):
Historical Triangles: Number of closed triads around in the
historical event network of the specified type.
(Directed only).
current_triangle(transformation, K, type, event_stream):
Active Triangles: As general_triangle but restricted to currently
active edges. (DEM only, Directed only).
common_partner(history, type, ...): Common Partner Shorthand:
Dispatches to general_common_partners() (history="general")
or current_common_partners() (history="current").
triangle(history, type, ...): Triangle Shorthand:
Dispatches to general_triangle() (history="general")
or current_triangle() (history="current").
general_degree_out_sender(
transformation, K, event_stream, window):
Sender Out-Degree: Historical out-degree of sender .
(Directed only).
general_degree_out_receiver(
transformation, K, event_stream, window):
Receiver Out-Degree: Historical out-degree of receiver .
(Directed only).
general_degree_in_sender(
transformation, K, event_stream, window):
Sender In-Degree: Historical in-degree of sender .
(Directed only).
general_degree_in_receiver(
transformation, K, event_stream, window):
Receiver In-Degree: Historical in-degree of receiver .
(Directed only).
general_degree_sum(transformation, K, event_stream, window):
Degree Sum: Sum of historical degrees of both endpoints.
(Undirected only).
general_degree_absdiff(
transformation, K, event_stream, window):
Degree Absolute Difference: Absolute difference in historical degrees.
(Undirected only).
general_count_out_sender(
transformation, K, event_stream, window):
Sender Out-Count: Total events sent by sender .
(Directed only).
general_count_out_receiver(
transformation, K, event_stream, window):
Receiver Out-Count: Total events sent by receiver .
(Directed only).
general_count_in_sender(
transformation, K, event_stream, window):
Sender In-Count: Total events received by sender .
(Directed only).
general_count_in_receiver(
transformation, K, event_stream, window):
Receiver In-Count: Total events received by receiver .
(Directed only).
general_count_sum(transformation, K, event_stream, window):
Count Sum: Sum of total event counts of both endpoints.
(Undirected only).
general_count_absdiff(
transformation, K, event_stream, window):
Count Absolute Difference: Absolute difference in total event counts.
(Undirected only).
current_degree_out_sender(transformation, K, event_stream):
Active Sender Out-Degree: Out-degree of in the active DEM network.
(DEM only, Directed only).
current_degree_out_receiver(
transformation, K, event_stream):
Active Receiver Out-Degree: Out-degree of in active DEM network.
(DEM only, Directed only).
current_degree_in_sender(transformation, K, event_stream):
Active Sender In-Degree: In-degree of in the active DEM network.
(DEM only, Directed only).
current_degree_in_receiver(
transformation, K, event_stream):
Active Receiver In-Degree: In-degree of in active DEM network.
(DEM only, Directed only).
current_degree_sum(transformation, K, event_stream):
Active Degree Sum: Sum of active degrees of both endpoints.
(DEM only, Undirected only).
current_degree_absdiff(transformation, K, event_stream):
Active Degree Absolute Difference: Absolute difference in active degrees.
(DEM only, Undirected only).
current_count_out_sender(transformation, K, event_stream):
Active Sender Out-Count: Total active events sent by .
(DEM only, Directed only).
current_count_out_receiver(
transformation, K, event_stream):
Active Receiver Out-Count: Total active events sent by .
(DEM only, Directed only).
current_count_in_sender(transformation, K, event_stream):
Active Sender In-Count: Total active events received by .
(DEM only, Directed only).
current_count_in_receiver(
transformation, K, event_stream):
Active Receiver In-Count: Total active events received by .
(DEM only, Directed only).
current_count_sum(transformation, K, event_stream):
Active Count Sum: Sum of active event counts of both endpoints.
(DEM only, Undirected only).
current_count_absdiff(transformation, K, event_stream):
Active Count Absolute Difference: Absolute difference in active event counts.
(DEM only, Undirected only).
degree(
history, type, count, transformation, K, event_stream, window):
Degree Shorthand: Dispatches to the appropriate degree statistic based
on history ("general" or "current") and type
("out_sender", "out_receiver", "in_sender",
"in_receiver", "sum", "absdiff").
Set count = TRUE for weighted (count-based) variants.
Alias: degrees().
count(history, type, transformation, K, event_stream, window):
Count Shorthand: Equivalent to degree(..., count = TRUE).
dyadic_cov(data, change_points): Dyadic Covariate: Time-constant
or time-varying external dyadic covariate matrix .
.
monadic_cov(data, fun, change_points): Monadic Covariate: External
monadic covariate vector converted to a dyadic matrix via
user-supplied function .
.
Estimates a Relational Event Model (REM) for network data, focusing on the
incidence of discrete events between pairs of actors.
See dem for the full Durational Event Model, which extends
the REM to handle interactions with non-negligible duration.
rem( events, training_start = 0, exogenous_end = NULL, formula = NULL, n_nodes = NULL, directed = FALSE, coef = NULL, semiparametric = FALSE, control = control.redeem() )rem( events, training_start = 0, exogenous_end = NULL, formula = NULL, n_nodes = NULL, directed = FALSE, coef = NULL, semiparametric = FALSE, control = control.redeem() )
events |
A matrix of events with columns |
training_start |
Numeric; the time point at which to start the estimation. Defaults to 0. |
exogenous_end |
Numeric; optional end time for exogenous baseline changes. Defaults to NULL. |
formula |
A one-sided |
n_nodes |
Integer; the total number of actors in the network. If |
directed |
Logical; whether the interaction events are directed. Defaults to FALSE. |
coef |
Numeric vector; initial coefficients for the model. If provided, this must be a concatenated vector of:
Defaults to NULL, in which case default starting values are automatically computed. |
semiparametric |
Logical; whether to use a semiparametric baseline. Defaults to FALSE. See the 'Semiparametric Baseline' section for details. |
control |
A list of control parameters from
|
The REM can be viewed as the incidence sub-model of the full
dem, corresponding to the formation process
. It uses a counting process approach to
estimate the influence of various covariates on the timing and occurrence
of events, assuming that events are instantaneous points in time.
An object of class rem_object containing model estimates
and log-likelihoods. See rem_object for details on the
components of the returned object and S3 methods.
The Relational Event Model characterizes the instantaneous rate at which
actor pair initiates an event. Under the log-linear
specification, the event intensity at time is:
where:
is a vector of sufficient statistics
computed from the event history ; see
redeem_terms for available terms.
is the vector of covariate effects.
and are optional actor-specific
baselines (sender and receiver sociality), included via the bare
symbol degree in the formula.
is an optional piecewise-constant temporal
baseline, included via baseline(changepoints) in the formula.
When semiparametric = TRUE, the temporal baseline rate of event occurrence
is left completely unspecified, and the model parameters are estimated via the Cox
partial likelihood using the survival package. In this path:
Each observed event time is treated as a failure time, and all non-occurring dyads at that time constitute the risk set.
The exact waiting times between events are conditioned away, meaning that inference is based solely on the sequence of events and the relative dyadic intensities.
This approach is equivalent to the ordered (or conditional) REM likelihood introduced by Butts (2008). It is highly robust to temporal fluctuations and baseline misspecification since no piecewise baseline or changepoints need to be specified.
Limitations: This path does not support the specialized
scalable estimation of sender/receiver popularity effects (degree) or
piecewise-constant temporal baselines.
Fritz, C., Rastelli, R., Fop, M., & Caimo, A. (2026). Scalable Durational Event Models: Application to Physical and Digital Interactions. arXiv:2504.00049.
Butts, C. T. (2008). A Relational Event Framework for Social Action. Sociological Methodology, 38(1), 155-200.
# Simulate some relational event data n <- 20 events <- matrix(c( 1.2, 1, 5, 3.1, 2, 8, 4.5, 1, 3 ), ncol = 3, byrow = TRUE) colnames(events) <- c("time", "from", "to") # Estimate a simple REM fit <- rem( events = events, n_nodes = n, formula = ~1, control = control.redeem(it_max = 50) ) summary(fit)# Simulate some relational event data n <- 20 events <- matrix(c( 1.2, 1, 5, 3.1, 2, 8, 4.5, 1, 3 ), ncol = 3, byrow = TRUE) colnames(events) <- c("time", "from", "to") # Estimate a simple REM fit <- rem( events = events, n_nodes = n, formula = ~1, control = control.redeem(it_max = 50) ) summary(fit)
An object of class rem returned by the rem function,
representing a fitted Relational Event Model.
A rem object is a list containing the following components:
call: The matched call.
event_numbers: A vector containing the number of events.
model: The fitted underlying model.
events: The preprocessed event matrix.
formula: The formula used.
n_nodes: The number of nodes.
directed: Logical indicating whether the events are directed.
build_time: The time at which the estimation dataset started
building.
max_time: The maximum event time.
time_changepoints: Time points where baseline intensity changes.
labels_changepoints: Labels for the time intervals.
training_start: The start time of the training period.
exogenous_end: The end time of the exogenous period.
subsample: Subsample proportion used.
return_data: Logical indicating whether preprocessed data
frames were returned.
runtime: The estimation runtime.
window_map: The window map used for calculation.
preprocessed: Preprocessed data structures.
The following S3 methods are implemented for rem objects:
print(x, ...): Prints a brief summary of the fitted REM model.
x: A rem object.
...: Additional arguments passed to printing function.
summary(object, ...): Summarizes model results, including
parameter estimates, standard errors, and fit statistics. Returns
an object of class summary.rem.
object: A rem object.
...: Additional arguments passed to summary method.
plot(x, baseline = FALSE, ...): Generates trace plots for
model coefficients and log-likelihood histories.
x: A rem object.
baseline: Logical. If TRUE, plots the estimated
baseline step function. Defaults to FALSE.
...: Additional arguments passed to underlying trace
plotting method. Supported parameters include:
coefs: Logical. If TRUE (default), plots
iteration traces for core/fixed coefficients.
degree: Logical. If TRUE (default), plots
iteration traces for degree/actor effects.
time: Logical. If TRUE (default), plots
iteration traces for temporal baseline effects.
llh: Logical. If TRUE (default), plots
trace of log-likelihood history.
separate: Logical. If TRUE, each plot is
generated in a new window or as a separate sequence.
Defaults to FALSE.
sub_label: Character. Optional subtitle to display
at the bottom of the figure.
logLik(object, ...): Extracts the log-likelihood of the
fitted model.
object: A rem object.
...: Additional arguments.
plot_baseline(x, ...): Plots the step function of the
estimated baseline intensity.
x: A rem object.
...: Additional graphical parameters passed to
plot.
predict(object, time = NULL, type = c("response", "lp", "terms"), ...):
Predicts the intensity, linear predictor, or term contributions for a fitted REM model.
object: A rem object.
time: Numeric vector; optional time point(s) at which to predict. Defaults to NULL.
type: Character; the type of prediction. Defaults to "response".
...: Additional arguments.
Simulate a Relational Event Model (REM)
rem.simulate( events = matrix(0, 0, 4), formula, coef = NULL, coef_degree = 0, n_events = 0, time = 0, max_events = 4e+05, n_nodes, verbose = FALSE, baseline = NULL, seed = 123, block = 1, directed = FALSE )rem.simulate( events = matrix(0, 0, 4), formula, coef = NULL, coef_degree = 0, n_events = 0, time = 0, max_events = 4e+05, n_nodes, verbose = FALSE, baseline = NULL, seed = 123, block = 1, directed = FALSE )
events |
A matrix representing the initial events with columns |
formula |
A one-sided |
coef |
Numeric vector; coefficients for the model. Defaults to NULL. |
coef_degree |
Numeric; degree coefficient. Defaults to 0. |
n_events |
Integer; number of events to simulate. Defaults to 0. |
time |
Numeric; simulation time. Defaults to 0. |
max_events |
Integer; maximum number of events. Defaults to 400000. |
n_nodes |
Integer; the total number of actors in the network. |
verbose |
Logical; if |
baseline |
Numeric vector; baseline intensity values for intervals defined by changepoints. Defaults to NULL. |
seed |
Integer; random seed. Defaults to 123. |
block |
An integer vector of length |
directed |
Logical; whether the interaction events are directed. Defaults to FALSE. |
The block parameter allows the user to specify a partition of the nodes into different groups (blocks).
When the vector contains more than one unique block identifier:
The simulation suppresses all within-block dyad intensities by setting them to 0.
Consequently, only events between nodes belonging to different blocks are generated (between-block interactions).
If all nodes belong to the same block (e.g., if a single value or NULL is passed), no block-level constraints are applied, and all dyads are simulated according to the specified model formula.
A matrix of simulated events.
Multi-stream event models are currently not supported in simulation.
# Simulate events from a REM model structure n <- 10 f1 <- ~ 1 + inertia(transformation = "identity") # Simulating events evs <- rem.simulate( formula = f1, n_nodes = n, time = 1.0, coef = c(1.0, 0.5), seed = 42, max_events = 100 ) head(evs)# Simulate events from a REM model structure n <- 10 f1 <- ~ 1 + inertia(transformation = "identity") # Simulating events evs <- rem.simulate( formula = f1, n_nodes = n, time = 1.0, coef = c(1.0, 0.5), seed = 42, max_events = 100 ) head(evs)
redeem_result Model FitComputes a summary of a fitted redeem_result object, collecting
the estimated fixed effects, log-likelihood, and (if present) degree and
temporal baseline effects into a structured list suitable for printing.
## S3 method for class 'redeem_result' summary(object, ...)## S3 method for class 'redeem_result' summary(object, ...)
object |
A |
... |
Additional arguments (currently unused). |
An object of class summary.redeem_result, which is a list
containing:
coefficients: A numeric matrix with one row per fixed-effect
covariate and columns Estimate, Std. Error, t value,
and Pr(>|t|).
llh: The log-likelihood of the fitted model (scalar).
degree_summary: A list with summary statistics (n,
n_unidentifiable, mean, sd, range) of the
estimated degree effects, only present when more than 10 degree
parameters were estimated.
degree_effects: A named numeric vector of estimated degree
effects, only present when 10 or fewer degree parameters were estimated.
time_summary: A list with summary statistics of the estimated
temporal baseline effects, only present when more than 10 time intervals
were used.
time_effects: A named numeric vector of estimated temporal
baseline effects, only present when 10 or fewer time intervals were used.
iter: Integer; the number of iterations performed by the
optimizer (NA if history was not saved).