% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pheno_normals.R
\name{pheno_normals}
\alias{pheno_normals}
\title{Calculate Phenological Normals (Climatology)}
\usage{
pheno_normals(
  pep,
  period = 1991:2020,
  by = c("country", "genus", "phase_id"),
  species = NULL,
  phase_id = NULL,
  min_years = 20,
  probs = c(0.05, 0.1, 0.25, 0.75, 0.9, 0.95),
  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{period}{Integer vector specifying the years to include in the normal
calculation. Default is \code{1991:2020} (current WMO standard period).}

\item{by}{Character vector of column names to group by. Common choices:
\itemize{
\item \code{c("country", "genus", "phase_id")} - Regional normals by genus/phase
\item \code{c("s_id", "species", "phase_id")} - Station-level normals
\item \code{c("genus", "phase_id")} - Overall normals ignoring geography
}
Default is \code{c("country", "genus", "phase_id")}.}

\item{species}{Optional character string to filter by species column.
Can be genus name (e.g., "Triticum") or full species (e.g., "Triticum aestivum").
If \code{NULL} (default), all species in the data are included.}

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

\item{min_years}{Minimum number of years required to calculate valid normals.
Default is 20 (WMO standard). Groups with fewer years return \code{NA}.}

\item{probs}{Numeric vector of probabilities for percentile calculation.
Default is \code{c(0.05, 0.10, 0.25, 0.75, 0.90, 0.95)}.}

\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{n_years}{Number of years with data in the period}
\item{n_obs}{Total number of observations}
\item{mean_doy}{Arithmetic mean DOY}
\item{median_doy}{Median DOY (more robust to outliers)}
\item{sd_doy}{Standard deviation}
\item{iqr_doy}{Interquartile range}
\item{mad_doy}{Median absolute deviation (robust spread)}
\item{q05, q10, q25, q75, q90, q95}{Percentiles with the default
\code{probs}. Custom \code{probs} produce column names derived from
the actual levels — integer percents pad to two digits
(e.g., \code{q05}, \code{q10}), fractional percents use an
underscore in place of the decimal point (e.g., \code{q02_5} for
the 2.5\\% quantile, \code{q97_5} for the 97.5\\% quantile).
The mapping is also stored in \code{attr(result, "q_names")}.}
\item{period}{Character string describing the reference period}
}
}
\description{
Computes reference "normal" phenology for a specified period, analogous to
WMO climate normals. Returns central tendency, spread, and percentile
statistics for phenological day-of-year (DOY) values.
}
\details{
Phenological normals provide a baseline for comparing individual years or
detecting trends. This function calculates both classical statistics (mean, SD)
and robust alternatives (median, MAD, IQR) that are less sensitive to outliers.

The function can be used in two ways:
\enumerate{
\item \strong{Full dataset}: Pass the complete \code{pep} object and use
\code{species} and \code{phase_id} parameters to filter internally.
\item \strong{Pre-filtered subset}: Filter the data first using data.table
syntax, then pass the subset to the function.
}
}
\section{Standard Reference Periods}{

\itemize{
\item \strong{1961-1990}: Historical reference (pre-acceleration of warming)
\item \strong{1991-2020}: Current WMO standard normal period
}
}

\examples{
\donttest{
# Download synthetic data first
pep <- pep_download()

# Use Swiss subset for faster computation
pep_ch <- pep[country == "Switzerland"]

# Calculate normals for all species and phases
normals_all <- pheno_normals(pep_ch)

# Normals for apples, flowering phase (60)
apple_normals <- pheno_normals(pep_ch,
                               species = "Malus",
                               phase_id = 60)

# Using a pre-filtered subset
apples <- pep_ch[genus == "Malus" & phase_id \%in\% c(60, 65)]
apple_normals <- pheno_normals(apples,
                               by = c("species", "phase_id"))

# Station-level normals for detailed analysis
station_normals <- pheno_normals(pep_ch,
                                 species = "Malus",
                                 phase_id = 60,
                                 by = c("s_id"))

# Historical reference period
historical <- pheno_normals(pep_ch,
                            period = 1961:1990,
                            species = "Malus")

# Compare two periods
period1 <- pheno_normals(pep_ch, period = 1961:1990, species = "Malus")
period2 <- pheno_normals(pep_ch, period = 1991:2020, species = "Malus")
shift <- period2$mean_doy - period1$mean_doy
}

}
\references{
WMO (2017). \emph{WMO Guidelines on the Calculation of Climate Normals}.
WMO-No. 1203, World Meteorological Organization, Geneva.

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_anomaly}} for calculating anomalies relative to normals,
\code{\link{pep_download}} for obtaining the main dataset
}
\author{
Matthias Templ
}
