% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/treespatial_scan.R
\name{treespatial_scan}
\alias{treespatial_scan}
\title{Tree-Spatial Scan Statistic}
\usage{
treespatial_scan(
  data,
  cases,
  population,
  region_id,
  x,
  y,
  node_id,
  tree = NULL,
  tree_node_id = NULL,
  tree_parent_id = NULL,
  max_pop_pct = 0.5,
  nsim = 999L,
  alpha = 0.05,
  model = c("poisson", "binomial"),
  seed = NULL,
  n_cores = 1L
)
}
\arguments{
\item{data}{A \code{data.frame} in long format with one row per
(region, tree-leaf) observation. The \code{cases}, \code{population},
\code{region_id}, \code{x}, \code{y} and \code{node_id} arguments name
columns of this data.frame.}

\item{cases}{Column of \code{data} giving the number of cases observed
for each (region, leaf) row. Given as an unquoted column name (a string
or an expression on columns also works).}

\item{population}{Column of \code{data} giving the population (or
denominator) of the region for each row. The same value should be
repeated across all rows of a given region; if it varies, the first
occurrence per region is used and a warning is issued.}

\item{region_id}{Column of \code{data} giving the region identifier.}

\item{x, y}{Columns of \code{data} giving the region centroid coordinates.
Like \code{population}, these should be constant within region.}

\item{node_id}{Column of \code{data} giving the tree leaf identifier for
each row. Each value must match a leaf of the tree.}

\item{tree}{A \code{data.frame} with columns \code{node_id} and
\code{parent_id}. The root node(s) must have \code{parent_id = NA}.
As an alternative, pass \code{tree_node_id} and \code{tree_parent_id}
as parallel vectors instead of this argument.}

\item{tree_node_id, tree_parent_id}{Optional. Parallel vectors describing
the tree edges, used as an alternative to \code{tree}. If both
\code{tree} and these vectors are supplied, an error is raised.}

\item{max_pop_pct}{Numeric. Maximum proportion of total population
allowed inside a zone. Default \code{0.5}.}

\item{nsim}{Integer. Number of Monte Carlo simulations. Default \code{999}.}

\item{alpha}{Numeric. Significance level. Default \code{0.05}.}

\item{model}{Character. \code{"poisson"} (default) or \code{"binomial"}.}

\item{seed}{Integer or \code{NULL}. Random seed for the Monte
Carlo loop. When non-\code{NULL}, the user's pre-existing RNG
state is saved on entry and restored on exit, so the seed
argument affects only this call and does not leak into
subsequent draws in the user's session.}

\item{n_cores}{Integer. OpenMP threads for the Monte Carlo loop.
Default \code{1L} (serial).}
}
\value{
An object of class \code{"treespatial_scan"}.
}
\description{
Performs the tree-spatial scan statistic, combining Kulldorff's circular
scan (spatial clusters) with the tree-based scan (hierarchical data
mining). Searches all combinations of spatial zones and tree branches
to identify pairs \eqn{(z, g)} with significantly more cases than
expected.
}
\details{
Inputs are supplied through a single \code{data} data.frame in long
format (one row per (region, tree-leaf) observation); the case, population,
region, coordinate and leaf columns are referenced by name. The user is
responsible for choosing which column to use as \code{population} (e.g.,
total population, live births, person-years), making the choice of
denominator explicit.

\strong{Secondary clusters.} The returned object contains the most likely
cluster as well as the full set of evaluated (zone, branch) pairs in
\code{secondary_clusters}. To obtain the distinct secondary clusters as
described in Section 5.1.1 of Cancado et al. (2025) (filtering out pairs
that overlap in regions or branches with already-retained clusters), use
\code{\link{filter_clusters}} or \code{\link{get_cluster_regions}} with
\code{n_clusters > 1}.
}
\examples{
set.seed(123)
n_regions <- 10
tree <- data.frame(
  node_id   = c(1, 2, 3, 4, 5, 6, 7),
  parent_id = c(NA, 1, 1, 2, 2, 3, 3)
)
# Long-format data.frame: one row per (region, leaf) combination
crimes <- expand.grid(region_id = 1:n_regions, node_id = c(4, 5, 6, 7))
xy <- data.frame(region_id = 1:n_regions,
                 x = runif(n_regions, 0, 10),
                 y = runif(n_regions, 0, 10))
crimes <- merge(crimes, xy, by = "region_id")
crimes$population <- 1000
crimes$cases <- rpois(nrow(crimes), lambda = 5)
crimes$cases[crimes$node_id == 4 & crimes$region_id \%in\% 1:3] <- rpois(3, 30)

result <- treespatial_scan(
  crimes,
  cases       = cases,
  population  = population,
  region_id   = region_id,
  x           = x,
  y           = y,
  node_id     = node_id,
  tree        = tree,
  nsim        = 99
)
print(result)
}
\references{
Cancado, A. L. F., Oliveira, G. S., Quadros, A. V. C., & Duczmal, L.
(2025). A tree-spatial scan statistic. \emph{Environmental and Ecological
Statistics}, 32, 953--978. \doi{10.1007/s10651-025-00670-w}
}
\seealso{
\code{\link{circular_scan}}, \code{\link{tree_scan}},
  \code{\link{aggregate_tree}}, \code{\link{filter_clusters}},
  \code{\link{get_cluster_regions}}, \code{\link{sequential_scan}}
}
