Skip to contents

cube_aggregate_time() groups the canonical time axis into calendar periods and applies one controlled reducer to every longitude, latitude, depth, and variable cell. It changes only the time dimension and always returns an in-memory <ocean_cube>.

Usage

cube_aggregate_time(
  x,
  by,
  method = c("mean", "sum", "min", "max", "median"),
  na.rm = TRUE,
  min_n = 1L,
  diagnostics = FALSE
)

Arguments

x

A valid <ocean_cube> using the memory or NetCDF backend.

by

A character scalar selecting "day", "week", "month", "season", or "year".

method

A character scalar selecting "mean", "sum", "min", "max", or "median". Arbitrary reducer functions are not supported.

na.rm

A non-missing logical scalar. If TRUE, only finite values are reduced. If FALSE, any non-finite value makes that cell-period missing.

min_n

A positive integer-like scalar giving the minimum number of finite values required per cell, depth, variable, and period.

diagnostics

A non-missing logical scalar. If TRUE, aligned n_valid and observation-coverage arrays are retained in qa$temporal_aggregation; lightweight period metadata are always retained.

Value

An in-memory <ocean_cube> with unchanged longitude, latitude, depth, variable, and unit coordinates, and a regularized aggregated time axis.

Details

Date input produces Date period starts. POSIXct input produces UTC POSIXct period starts, and all POSIXct boundaries are evaluated in UTC. Weeks use ISO-8601 Monday–Sunday groups: week 1 contains January 4 and the ISO year is the year containing the week's Thursday. Seasons are DJF, MAM, JJA, and SON; DJF 2026 contains December 2025 through February 2026 and is timestamped 2025-12-01. All frequencies use canonical period-start timestamps.

Every canonical period between the first and last represented periods is returned. Partial boundary periods remain present, and internal periods with no timestamps contain missing values. A finite value is one for which is.finite() is true, so NA, NaN, Inf, and -Inf are invalid. n_total is the number of stored timestamps in a period, n_valid is cell-specific, and coverage_fraction = n_valid / n_total is observation coverage, not duration coverage. Empty periods have zero counts and undefined coverage.

All methods use equal observation weighting; duration weighting is not performed. Irregular or gapped input emits a warning because an observation-weighted summary can differ from a duration-weighted temporal summary. method = "sum" means a sum of sampled finite values, retains the input unit string, and does not perform integration or unit conversion.

Lazy NetCDF cubes are read through bounded indexed backend reads, one period and spatial/depth/variable block at a time; the complete multi-period cube is not materialized. Exact median retains the complete temporal period only for the current bounded block and can therefore require more memory than the other reducers.

Examples

monthly <- ocean_cube(
  lon = -80, lat = -12, depth = 0,
  time = as.Date(c("2020-01-01", "2020-01-15", "2020-02-01")),
  data = array(c(1, 3, 10), c(1, 1, 1, 3, 1)), vars = "temperature"
)
cube_aggregate_time(monthly, by = "month")
#> Warning: Temporal aggregation uses equal observation weighting; irregular or gapped sampling can make observation-weighted summaries differ from duration-weighted temporal summaries.
#> <ocean_cube>
#>   backend    : memory
#>   source     : <unspecified>
#>   dimensions : 1 x 1 x 1 x 2 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       : 2020-01-01 to 2020-02-01 (n = 2)
#>   variables  : temperature

hourly <- ocean_cube(
  lon = -80, lat = -12, depth = 0,
  time = as.POSIXct(
    c("2020-01-01 00:00:00", "2020-01-01 12:00:00"), tz = "UTC"
  ),
  data = array(c(1, 3), c(1, 1, 1, 2, 1)), vars = "temperature"
)
cube_aggregate_time(hourly, by = "day")
#> <ocean_cube>
#>   backend    : memory
#>   source     : <unspecified>
#>   dimensions : 1 x 1 x 1 x 1 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       : 2020-01-01 to 2020-01-01 (n = 1)
#>   variables  : temperature

djf <- 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_aggregate_time(djf, by = "season", diagnostics = TRUE)
#> <ocean_cube>
#>   backend    : memory
#>   source     : <unspecified>
#>   dimensions : 1 x 1 x 1 x 1 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       : 2025-12-01 to 2025-12-01 (n = 1)
#>   variables  : temperature