% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pheno_anomaly.R
\name{pheno_anomaly}
\alias{pheno_anomaly}
\title{Calculate Phenological Anomalies}
\usage{
pheno_anomaly(
  pep,
  baseline_period = 1961:1990,
  target_years = NULL,
  by = c("country", "genus", "phase_id"),
  species = NULL,
  phase_id = NULL,
  robust = TRUE,
  min_years = 15,
  extreme_threshold = 2,
  normals = NULL,
  na.rm = TRUE
)
}
\arguments{
\item{pep}{A \code{pep} object or \code{data.table} containing phenological
observations with columns \code{year}, \code{day}, and grouping variables.}

\item{baseline_period}{Integer vector specifying the years to use for
baseline calculation. Default is \code{1961:1990} (pre-acceleration
warming reference period).}

\item{target_years}{Integer vector specifying years to calculate anomalies
for. If \code{NULL} (default), calculates for all years in the data.}

\item{by}{Character vector of column names to group by. Must match columns
in the data. Default is \code{c("country", "genus", "phase_id")}.}

\item{species}{Optional character string to filter by species/genus.
If \code{NULL} (default), all species are included.}

\item{phase_id}{Optional integer vector to filter by BBCH phase codes.
If \code{NULL} (default), all phases are included.}

\item{robust}{Logical. If \code{TRUE} (default), uses median and MAD for
baseline and standardization. If \code{FALSE}, uses mean and SD.}

\item{min_years}{Minimum number of years required in the baseline period
to calculate valid anomalies. Default is 15.}

\item{extreme_threshold}{Numeric. Z-score threshold for flagging extreme
events. Default is 2 (approximately 95th percentile for normal distribution).}

\item{normals}{Optional pre-computed \code{pheno_normals} object. If provided,
baseline statistics are taken from this object instead of being computed.}

\item{na.rm}{Logical. Should missing values be removed? Default \code{TRUE}.}
}
\value{
A \code{data.table} with the following columns:
\describe{
\item{by variables}{Grouping variables as specified in \code{by}}
\item{year}{Year of observation}
\item{observed_doy}{Observed mean day-of-year for the group/year}
\item{baseline_doy}{Long-term baseline (median if robust, mean otherwise)}
\item{baseline_spread}{Baseline spread (MAD if robust, SD otherwise)}
\item{anomaly_days}{Deviation in days (negative = early, positive = late)}
\item{z_score}{Standardized anomaly (anomaly / spread)}
\item{percentile}{Percentile rank relative to baseline distribution}
\item{is_extreme}{Logical flag for extreme events (|z_score| > threshold)}
\item{direction}{Character: "early", "late", or "normal"}
}
}
\description{
Computes deviations from long-term phenological baselines to identify
extreme years and detect climate signals. Returns both raw anomalies
(in days) and standardized anomalies for cross-species comparison.
}
\details{
Phenological anomalies quantify how much a given year deviates from
long-term expectations. This is crucial for:
\itemize{
\item Detecting climate change signals in phenology
\item Identifying extreme phenological years
\item Comparing anomalies across different species/regions
}

The function supports two approaches:
\itemize{
\item \strong{Robust} (default): Uses median for central tendency and MAD
(Median Absolute Deviation) for spread. More resistant to outliers.
\item \strong{Classical}: Uses mean and standard deviation. More sensitive
to extreme values but provides interpretable z-scores under normality.
}
}
\section{Interpretation}{

\itemize{
\item \strong{anomaly_days}: Direct interpretation - "X days earlier/later
than normal"
\item \strong{z_score}: Standardized - values > 2 or < -2 are typically
considered extreme
\item \strong{percentile}: Normal approximation from z-score - e.g.,
5th percentile means "earlier than 95\\% of baseline years"
}
}

\examples{
\donttest{
pep <- pep_download()

# Grapevine in Switzerland (longest historical records back to 1775)
vine_ch <- pep[country == "Switzerland" & species == "Vitis vinifera"]

if (nrow(vine_ch) > 0) {
  # Calculate anomalies relative to 1961-1990 baseline
  anomalies <- pheno_anomaly(vine_ch,
                             baseline_period = 1961:1990,
                             phase_id = 65)
  print(anomalies)

  # Find extreme early years
  extreme_early <- anomalies[is_extreme == TRUE & direction == "early"]
  extreme_early

  # Anomalies for recent years only
  recent <- pheno_anomaly(vine_ch,
                          baseline_period = 1961:1990,
                          target_years = 2000:2020,
                          phase_id = 65)
  recent
}
}

}
\references{
Menzel, A. et al. (2006). European phenological response to climate
change matches the warming pattern.
\emph{Global Change Biology}, 12(10), 1969--1976.
\doi{10.1111/j.1365-2486.2006.01193.x}

Templ, M., Templ, B., and Filzmoser, P. (2018).
Modelling and prediction of phenological data of the beginning of
flowering: Austrian indicators of climate change.
\emph{International Journal of Biometeorology}, 62, 1319--1334.
\doi{10.1007/s00484-018-1534-2}
}
\seealso{
\code{\link{pheno_normals}} for calculating baseline statistics,
\code{\link{pep_download}} for obtaining the main dataset
}
\author{
Matthias Templ
}
