| Type: | Package |
| Title: | Projected Actor Locations for Spatial Interaction Modeling |
| Version: | 0.1.0 |
| Description: | Implements the Projected Actor Locations (PALS) method for spatial modeling of dyadic interactions between geographically mobile actors, as described in Kim, Liu and Desmarais (2023) <doi:10.1017/psrm.2022.6>. PALS applies exponential-smoothing weights to the spatiotemporal histories of a focal actor and its interaction partners ("alters") to project the location of future interactions. The package provides projection, maximum-similarity parameter estimation by minimizing great-circle (Haversine) prediction error, nonparametric bootstrap with multiple-imputation (Rubin's Rules) pooling, dyadic distance covariate construction, visualization, and a simulated example dataset of subnational conflict. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| LazyData: | true |
| Depends: | R (≥ 4.1.0) |
| Imports: | Rcpp, stats |
| LinkingTo: | Rcpp |
| Suggests: | testthat (≥ 3.0.0), knitr, rmarkdown, mice, ggplot2 |
| URL: | https://github.com/bdesmarais/palsr |
| BugReports: | https://github.com/bdesmarais/palsr/issues |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | yes |
| Packaged: | 2026-06-25 11:47:24 UTC; bbd5087 |
| Author: | Bruce A. Desmarais [aut, cre], Sangyeon Kim [aut], Howard Liu [aut] |
| Maintainer: | Bruce A. Desmarais <bruce.desmarais@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-01 10:00:13 UTC |
palsr: Projected Actor Locations for Spatial Interaction Modeling
Description
Implements the Projected Actor Locations (PALS) method for spatial modeling of dyadic interactions between geographically mobile actors, as described in Kim, Liu and Desmarais (2023) doi:10.1017/psrm.2022.6. PALS applies exponential-smoothing weights to the spatiotemporal histories of a focal actor and its interaction partners ("alters") to project the location of future interactions. The package provides projection, maximum-similarity parameter estimation by minimizing great-circle (Haversine) prediction error, nonparametric bootstrap with multiple-imputation (Rubin's Rules) pooling, dyadic distance covariate construction, visualization, and a simulated example dataset of subnational conflict.
Author(s)
Maintainer: Bruce A. Desmarais bruce.desmarais@gmail.com
Authors:
Bruce A. Desmarais bruce.desmarais@gmail.com
Sangyeon Kim
Howard Liu
See Also
Useful links:
Nonparametric bootstrap for PALS estimates and projections
Description
Quantifies uncertainty in PALS parameter estimates and in projected actor
locations by resampling events with replacement and re-estimating the model on
each bootstrap replicate, following Kim, Liu and Desmarais (2023). Each replicate
yields a parameter vector and (optionally) a set of Projected Actor Locations; the
collection of replicate PAL sets can be treated as multiple imputations and pooled
with Rubin's Rules (see pool_rubin()).
Usage
bootstrap_pals(
events,
R = 50,
model = c("four", "one"),
predict_time = NULL,
actors = NULL,
seed = NULL,
...
)
Arguments
events |
A pal_events object. |
R |
Number of bootstrap replicates (default |
model |
|
predict_time |
Optional |
actors |
For projection, which actors to project (default: all in |
seed |
Optional integer seed; replicate |
... |
Further arguments passed to estimate_pals (e.g. |
Details
Resampling is over rows of events (the nonparametric event bootstrap).
Duplicated events are kept as ordinary repeated events. Replicates whose
optimizer fails to converge are retained but flagged via the convergence
column of estimates.
Value
An object of class pals_boot with components:
estimatesAn
R-rowdata.frameof replicate parameter estimates.estimateThe point estimate on the full sample (an estimate_pals fit).
projectionsIf
predict_timewas given, adata.frameof projectedlon/latfor every actor-time-replicate combination; otherwiseNULL.R,model,callBookkeeping.
Methods: print(), summary() (bootstrap SEs / percentile intervals), and
coef() (the full-sample point estimate).
See Also
estimate_pals(), pool_rubin().
Examples
ev <- simulate_conflict_events(n_actors = 8, n_events = 200, seed = 1)
bt <- bootstrap_pals(ev, R = 10, model = "one", seed = 1)
summary(bt)
Estimate PALS parameters
Description
Estimates the PALS smoothing parameters by minimizing the mean great-circle (Haversine) distance between observed event locations and the locations predicted from each event's preceding history ("marching forward": every prediction uses only events strictly earlier than the event being predicted).
Usage
estimate_pals(
events,
fit_events = NULL,
model = c("four", "one"),
start = NULL,
method = NULL,
aggregate = c("mean", "sum"),
alter_weight = c("normalized", "legacy"),
eps = 0.01,
radius = 6371.0088,
cutoff = c("day", "month", "year"),
control = list()
)
Arguments
events |
A pal_events object providing the actor histories. |
fit_events |
Optional |
model |
|
start |
Optional numeric starting vector on the optimizer's scale
( |
method |
Optimizer method passed to stats::optim ( |
aggregate |
|
alter_weight, eps, cutoff |
See project_pal. |
radius |
Sphere radius for the Haversine objective (km). |
control |
A list of control parameters for stats::optim. |
Value
An object of class pals_fit with components params (estimated
pals_params), model, objective (minimized mean/sum distance), n_used
(events contributing), convergence, optim (raw optimizer output), events,
settings, and call. Methods: print(), summary(), coef(), predict(),
plot().
See Also
project_pals(), predict_event_locations(), bootstrap_pals().
Examples
ev <- simulate_conflict_events(n_actors = 10, n_events = 300, seed = 1)
fit <- estimate_pals(ev, model = "one")
fit
coef(fit)
Great-circle (Haversine) distance
Description
Vectorized great-circle distance between longitude/latitude points. Arguments are recycled to a common length, so any may be length 1.
Usage
haversine(lon1, lat1, lon2, lat2, radius = 6371.0088)
Arguments
lon1, lat1, lon2, lat2 |
Numeric vectors of coordinates in decimal degrees. |
radius |
Sphere radius in the desired output units. Defaults to the mean Earth
radius, |
Value
A numeric vector of distances. NA in any coordinate gives NA.
Examples
haversine(0, 0, 0, 1) # ~111 km per degree of latitude
haversine(7.4, 9.1, 8.5, 12.0) # Abuja-ish to Kano-ish
Subnational conflict events in Nigeria
Description
Real dyadic conflict events in Nigeria, bundled from the replication archive for the authors' study, Kim, Liu and Desmarais (2023). Each row is a recorded interaction between two actors at a known date and location; this is the data on which the PALS method was developed and validated.
Usage
nigeria_acled
Format
A pal_events object (a data.frame subclass) with 1,549 rows and 5 columns:
- actor1
Character name of the first actor in the dyad.
- actor2
Character name of the second actor in the dyad.
- time
Dateof the event.- lon
Event longitude (decimal degrees).
- lat
Event latitude (decimal degrees).
Details
These data are part of the publicly available replication materials for that study and can be downloaded directly from the Harvard Dataverse at doi:10.7910/DVN/NLWWPE.
Source
Public replication archive for Kim, Liu and Desmarais (2023), Harvard Dataverse, doi:10.7910/DVN/NLWWPE.
References
Kim, S., Liu, H., and Desmarais, B. A. (2023). Spatial modeling of dyadic geopolitical interactions between moving actors. Political Science Research and Methods, 11(3), 633-644. doi:10.1017/psrm.2022.6
Examples
data(nigeria_acled)
nigeria_acled
fit <- estimate_pals(nigeria_acled, model = "one")
coef(fit)
Simulated subnational conflict events (Nigeria-like)
Description
A deterministic, seeded simulation of dyadic interaction events among 25 mobile
actors over 2000-2016, with the qualitative spatiotemporal structure that the PALS
method targets: actors drift slowly through space and interact preferentially with
nearby actors. It is produced by simulate_conflict_events() and is used in the
package examples, tests, and vignette so that they run without any external
dependency. It complements nigeria_acled, the bundled real-data example.
Usage
nigeria_sim
Format
A pal_events object (a data.frame subclass) with 1500 rows and 5
columns:
- actor1
Character id of the first actor in the dyad.
- actor2
Character id of the second actor in the dyad.
- time
Dateof the event.- lon
Event longitude (decimal degrees).
- lat
Event latitude (decimal degrees).
Source
Generated by data-raw/nigeria_sim.R via
simulate_conflict_events(n_actors = 25, n_events = 1500, years = 2000:2016, seed = 20230101).
Examples
data(nigeria_sim)
nigeria_sim
fit <- estimate_pals(nigeria_sim, model = "one")
coef(fit)
Dyadic distance between Projected Actor Locations
Description
Builds the dyadic distance covariate used to model interaction likelihood: the Haversine distance between the two actors' Projected Actor Locations.
Usage
pal_distance(
events,
dyads,
params,
transform = c("none", "log"),
offset = 0.01,
alter_weight = c("normalized", "legacy"),
eps = 0.01,
cutoff = c("day", "month", "year")
)
Arguments
events |
A pal_events object. |
dyads |
A |
params |
A pals_params or fitted estimate_pals object. |
transform |
|
offset |
Offset added before logging (default |
alter_weight, eps, cutoff |
See project_pal. |
Value
dyads augmented with pal_distance (and, for transform = "log",
pal_log_distance).
Examples
ev <- simulate_conflict_events(n_actors = 8, n_events = 200, seed = 1)
fit <- estimate_pals(ev, model = "one")
dy <- data.frame(actor1 = "G01", actor2 = "G02",
time = as.Date("2012-12-01"))
pal_distance(ev, dy, fit)
Construct a validated dyadic-event table
Description
pal_events() builds the core data object used throughout palsr: a table of
dyadic interaction events, each involving two actors at a known time and location.
Projected Actor Locations are computed from these histories.
Usage
pal_events(
data,
actor1 = "actor1",
actor2 = "actor2",
time = "time",
lon = "lon",
lat = "lat",
drop_self = TRUE
)
Arguments
data |
A |
actor1, actor2 |
Column names (length-1 character) identifying the two actors involved in each event. The pair is treated as unordered. |
time |
Column name of the event time. Must be a |
lon, lat |
Column names of the event longitude and latitude, in decimal degrees. |
drop_self |
Logical; drop events whose two actors are identical (default |
Details
Longitudes must lie in [-180, 180] and latitudes in [-90, 90]. Rows with
missing actor, time, or coordinate values are dropped with a message.
Value
An object of class pal_events (a data.frame subclass) with canonical
columns actor1, actor2, time, lon, lat, sorted by time.
Examples
df <- data.frame(
from = c("A", "A", "B"),
to = c("B", "C", "C"),
when = as.Date(c("2001-01-01", "2001-06-01", "2002-01-01")),
x = c(7.1, 8.0, 7.5),
y = c(9.0, 9.4, 10.1)
)
ev <- pal_events(df, actor1 = "from", actor2 = "to",
time = "when", lon = "x", lat = "y")
ev
Create a PALS parameter set
Description
A lightweight container for the four PALS smoothing parameters. Use it to project actor locations with known parameters (e.g. values reported in a paper), without estimating them from data.
Usage
pals_params(alpha, beta = 0, gamma = 0, eta = 0, model = c("four", "one"))
Arguments
alpha |
Time-decay of the focal actor's own event history ( |
beta |
Time-decay of the alters' event histories ( |
gamma |
Intercept of the logistic mixing weight |
eta |
Slope of the logistic mixing weight on the event-count ratio. Ignored in the one-parameter model. |
model |
Either |
Details
The mixing weight is \pi = \mathrm{plogis}(\gamma + \eta v), where
v = (n_i / n_k)^{1/\sqrt{n_k}} compares the number of focal events
(n_i) with the number of alter events (n_k). The projected location is
(1-\pi) times the recency-weighted mean of the focal actor's own past event
locations plus \pi times the recency-weighted mean of its alters' locations.
See project_pals() and the package vignette.
Value
An object of class pals_params.
Examples
p <- pals_params(alpha = 0.9, beta = 0.2, gamma = -10, eta = -10)
p
pals_params(alpha = 0.9, model = "one")
Pool estimates across imputations with Rubin's Rules
Description
Combines per-imputation point estimates and variances of a scalar quantity into a
single pooled estimate with a variance that accounts for both within- and
between-imputation uncertainty (Rubin, 1987). Use it to pool estimands computed on
each bootstrap/imputation replicate of bootstrap_pals() — for example a
regression coefficient from a dyadic model fit on each replicate's PAL distances.
Usage
pool_rubin(estimates, variances, df = FALSE, dfcom = Inf)
Arguments
estimates |
Numeric vector of per-imputation point estimates |
variances |
Numeric vector of per-imputation variances |
df |
Logical; if |
dfcom |
Complete-data degrees of freedom, used only when |
Details
With m imputations,
\bar Q = \tfrac1m \sum_j Q_j,\quad \bar U = \tfrac1m \sum_j U_j,\quad
B = \tfrac{1}{m-1}\sum_j (Q_j-\bar Q)^2,
and total variance T = \bar U + (1 + 1/m) B. The fraction of missing
information is (1 + 1/m)B / T. When df = TRUE, the Barnard-Rubin (1999)
small-sample degrees of freedom are used.
Value
A one-row data.frame with the pooled estimate qbar, within-imputation
variance ubar, between-imputation variance b, total variance t, standard
error se, fraction of missing information fmi, and (if df = TRUE) df and
p.value.
References
Rubin, D. B. (1987). Multiple Imputation for Nonresponse in Surveys. Wiley.
Barnard, J. and Rubin, D. B. (1999). Small-sample degrees of freedom with multiple imputation. Biometrika, 86(4), 948-955.
See Also
Examples
# Five imputations of a coefficient and its variance.
q <- c(1.10, 0.95, 1.20, 1.05, 0.98)
u <- c(0.04, 0.05, 0.045, 0.038, 0.052)
pool_rubin(q, u)
pool_rubin(q, u, df = TRUE, dfcom = 100)
Project locations from a fitted PALS model
Description
Project locations from a fitted PALS model
Usage
## S3 method for class 'pals_fit'
predict(
object,
newdata = NULL,
predict_time = NULL,
type = c("pal", "event"),
actors = NULL,
...
)
Arguments
object |
A |
newdata |
Optional pal_events (for |
predict_time |
For |
type |
|
actors |
For |
... |
Unused. |
Value
A data.frame of projections (see project_pals / predict_event_locations).
Examples
ev <- simulate_conflict_events(n_actors = 8, n_events = 200, seed = 1)
fit <- estimate_pals(ev, model = "one")
predict(fit, predict_time = as.Date("2013-12-01"), type = "pal")[1:5, ]
Predict dyadic event locations
Description
For each dyadic target (a pair of actors at a time), predicts the interaction location as the mean of the two actors' Projected Actor Locations. Optionally scores the prediction against an observed location.
Usage
predict_event_locations(
events,
targets,
params,
alter_weight = c("normalized", "legacy"),
eps = 0.01,
cutoff = c("day", "month", "year")
)
Arguments
events |
A pal_events object supplying the histories. |
targets |
A |
params |
A pals_params or fitted estimate_pals object. |
alter_weight, eps, cutoff |
See project_pal. |
Value
targets augmented with pred_lon, pred_lat, and (if observed lon/lat
were supplied) error_km, the Haversine distance between predicted and observed
locations. Predictions are NA when both actors lack usable history.
Examples
ev <- simulate_conflict_events(n_actors = 10, n_events = 300, seed = 1)
fit <- estimate_pals(ev, model = "one")
tg <- ev[ev$time > as.Date("2012-01-01"), ]
head(predict_event_locations(ev, tg, fit))
Project the location of a single actor
Description
Computes the Projected Actor Location (PAL) for one actor at one or more prediction times, given a parameter set.
Usage
project_pal(
events,
actor,
predict_time,
params,
alter_weight = c("normalized", "legacy"),
eps = 0.01,
cutoff = c("day", "month", "year")
)
Arguments
events |
A pal_events object. |
actor |
The focal actor id (length-1 character). |
predict_time |
A |
params |
A pals_params object or a fitted estimate_pals object. |
alter_weight |
|
eps |
Numerical offset inside each age weight (default |
cutoff |
History granularity: |
Value
A data.frame with one row per prediction time and columns actor, time,
lon, lat, n_focal, n_alter, has_history. lon/lat are NA when the
actor has no prior events.
Examples
ev <- simulate_conflict_events(n_actors = 8, n_events = 200, seed = 1)
p <- pals_params(alpha = 0.9, model = "one")
project_pal(ev, actor = "G01", predict_time = as.Date("2010-12-01"), params = p)
Project locations for multiple actors
Description
Computes Projected Actor Locations for a set of actors at one or more prediction times (an actor-by-time grid).
Usage
project_pals(
events,
actors = NULL,
predict_time,
params,
alter_weight = c("normalized", "legacy"),
eps = 0.01,
cutoff = c("day", "month", "year")
)
Arguments
events |
A pal_events object. |
actors |
Character vector of actor ids. Defaults to all actors in |
predict_time |
A |
params |
A pals_params object or a fitted estimate_pals object. |
alter_weight |
|
eps |
Numerical offset inside each age weight (default |
cutoff |
History granularity: |
Value
A data.frame with columns actor, time, lon, lat, n_focal,
n_alter, has_history (one row per actor-time combination).
Examples
ev <- simulate_conflict_events(n_actors = 10, n_events = 300, seed = 1)
p <- pals_params(alpha = 0.9, beta = 0.2, gamma = -10, eta = -10)
pal <- project_pals(ev, predict_time = as.Date("2010-12-01"), params = p)
head(pal)
Simulate dyadic conflict events between moving actors
Description
Generates a synthetic dataset of dyadic interaction events with the qualitative structure PALS is designed for: a set of armed-group-like actors, each following a slowly drifting spatial trajectory, that interact preferentially with nearby actors. Useful for examples, tests, and the package vignette. The geographic frame approximates Nigeria, echoing the application in Kim, Liu and Desmarais (2023).
Usage
simulate_conflict_events(
n_actors = 30,
n_events = 2000,
years = 2000:2016,
drift = 0.18,
jitter = 0.25,
decay = 2,
bbox = c(2.7, 14.7, 4, 13.9),
seed = NULL
)
Arguments
n_actors |
Number of actors (default 30). |
n_events |
Number of dyadic events (default 2000). |
years |
Integer vector of years to span (default |
drift |
Standard deviation (decimal degrees per year) of each actor's directional
drift; larger values make actors more mobile (default |
jitter |
Standard deviation (decimal degrees) of event-location noise around the
midpoint of the two actors' current locations (default |
decay |
Spatial interaction scale (degrees): partners are chosen with probability
proportional to |
bbox |
Bounding box |
seed |
Optional integer seed for reproducibility. |
Value
A pal_events object with columns actor1, actor2, time, lon, lat.
Examples
ev <- simulate_conflict_events(n_actors = 12, n_events = 400, seed = 42)
ev
summary(ev)