cube_climatology() computes a recurrent daily, monthly, or meteorological
seasonal climatology without pooling raw observations across years. Raw
finite observations are first averaged within each day-year, month-year, or
season-year replicate. The climatological mean and sample standard deviation
are then calculated across those replicates with equal replicate weights.
Usage
cube_climatology(
x,
by,
period = NULL,
leap = c("feb28", "drop", "keep"),
min_n = 1L,
diagnostics = FALSE
)Arguments
- x
A valid
<ocean_cube>using the memory or NetCDF backend.- by
A character scalar selecting
"day","month", or"season".- period
NULLfor the full source range, or two ordered bounds defining a closed reference interval. Bounds must use the same Date or POSIXct semantics asx$time; POSIXct bounds are exact UTC instants. Intersecting bounds outside the source range are clipped with one warning and both the requested and effective periods are retained.- leap
Daily leap-day policy:
"drop"removes February 29,"keep"retains it as an independent group, and"feb28"first combines February 28 and 29 within a leap year into one equally weighted February-28-equivalent replicate.leapis not applicable to monthly or seasonal climatologies.- min_n
A finite positive integer-like scalar giving the minimum number of valid period-year replicates required per cell and recurrent group.
- diagnostics
A non-missing logical scalar. If
TRUE, alignedn_clim_validand replicate-coverage arrays are retained inqa$climatology. Sample SD is always retained independently of this flag.
Value
An in-memory <ocean_cube>. data contains the climatological mean.
The aligned sample SD is in climatology$sd, and recurrent keys are in
climatology$group_key.
Details
Inner period means use equal finite-observation weighting; duration weighting
is not performed. Across years or season-years, every valid replicate has one
equal weight. Irregular or gapped sampling emits at most one warning per call
and is recorded in provenance. n_clim_total counts eligible calendar-period
opportunities, n_clim_valid counts finite period-year replicates, and
coverage_fraction = n_clim_valid / n_clim_total when the denominator is
positive.
The output always contains a complete recurrent cycle. Daily keys are stable
MM-DD values: drop and feb28 use the 365-day year 2001, while keep
uses leap year 2000. Monthly timestamps are the first days of 2001. Seasonal
timestamps are DJF 2000-12-01, MAM 2001-03-01, JJA 2001-06-01, and SON
2001-09-01. These timestamps are a strictly increasing climatological
pseudo-time representation, not the historical reference period. Date input
produces Date output; POSIXct input produces UTC POSIXct midnight output.
Partial first and last periods are retained. Lazy NetCDF input is processed
with bounded source-period and spatial/depth/variable reads; neither the full
source cube nor a full chronological intermediate cube is materialized.
cube_slice() and cube_crop() deliberately discard dimensional scientific
metadata and record that action in provenance, so select or crop the source
before computing a climatology when the SD must remain attached.
Examples
monthly <- ocean_cube(
lon = -80, lat = -12, depth = 0,
time = as.Date(c("2020-01-01", "2021-01-01")),
data = array(c(10, 20), c(1, 1, 1, 2, 1)), vars = "temperature"
)
suppressWarnings(cube_climatology(monthly, by = "month"))
#> <ocean_cube>
#> backend : memory
#> source : <unspecified>
#> dimensions : 1 x 1 x 1 x 12 x 1 [lon x lat x depth x time x var]
#> lon : -80 to -80 (n = 1)
#> lat : -12 to -12 (n = 1)
#> depth : 0 to 0 (n = 1)
#> time : 2001-01-01 to 2001-12-01 (n = 12)
#> variables : temperature
daily <- ocean_cube(
lon = -80, lat = -12, depth = 0,
time = as.Date(c("2020-02-28", "2020-02-29")),
data = array(c(20, 40), c(1, 1, 1, 2, 1)), vars = "temperature"
)
cube_climatology(daily, by = "day", leap = "feb28")
#> <ocean_cube>
#> backend : memory
#> source : <unspecified>
#> dimensions : 1 x 1 x 1 x 365 x 1 [lon x lat x depth x time x var]
#> lon : -80 to -80 (n = 1)
#> lat : -12 to -12 (n = 1)
#> depth : 0 to 0 (n = 1)
#> time : 2001-01-01 to 2001-12-31 (n = 365)
#> variables : temperature
seasonal <- ocean_cube(
lon = -80, lat = -12, depth = 0,
time = as.Date(c("2025-12-15", "2026-01-15", "2026-02-15")),
data = array(c(3, 6, 9), c(1, 1, 1, 3, 1)), vars = "temperature"
)
cube_climatology(seasonal, by = "season")
#> <ocean_cube>
#> backend : memory
#> source : <unspecified>
#> dimensions : 1 x 1 x 1 x 4 x 1 [lon x lat x depth x time x var]
#> lon : -80 to -80 (n = 1)
#> lat : -12 to -12 (n = 1)
#> depth : 0 to 0 (n = 1)
#> time : 2000-12-01 to 2001-09-01 (n = 4)
#> variables : temperature
suppressWarnings(cube_climatology(monthly, by = "month", diagnostics = TRUE))
#> <ocean_cube>
#> backend : memory
#> source : <unspecified>
#> dimensions : 1 x 1 x 1 x 12 x 1 [lon x lat x depth x time x var]
#> lon : -80 to -80 (n = 1)
#> lat : -12 to -12 (n = 1)
#> depth : 0 to 0 (n = 1)
#> time : 2001-01-01 to 2001-12-01 (n = 12)
#> variables : temperature