| 1 |
# GREGORIAN CALENDAR |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Fixed from Gregorian ========================================================= |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname fixed |
|
| 8 |
#' @aliases fixed,numeric,missing,missing,GregorianCalendar-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "fixed", |
|
| 11 |
signature = c(year = "numeric", month = "missing", day = "missing", calendar = "GregorianCalendar"), |
|
| 12 |
definition = function(year, calendar, scale = 1) {
|
|
| 13 |
## Rescale to years (if not already) |
|
| 14 | 68x |
year <- year * scale |
| 15 | ||
| 16 | 68x |
rd <- fixed(year, 01, 01, calendar = calendar) |
| 17 | ||
| 18 | 68x |
is_leap <- which(is_gregorian_leap_year(year)) |
| 19 | 68x |
rd[is_leap] <- ceiling(rd[is_leap]) # WHY ??? |
| 20 | 68x |
rd |
| 21 |
} |
|
| 22 |
) |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname fixed |
|
| 26 |
#' @aliases fixed,numeric,numeric,numeric,GregorianCalendar-method |
|
| 27 |
setMethod( |
|
| 28 |
f = "fixed", |
|
| 29 |
signature = c(year = "numeric", month = "numeric", day = "numeric", calendar = "GregorianCalendar"), |
|
| 30 |
definition = function(year, month, day, calendar) {
|
|
| 31 |
## Recycle |
|
| 32 | 358x |
n <- length(year) |
| 33 | 358x |
if (n > 1) {
|
| 34 | 276x |
if (length(month) == 1) month <- rep(month, n) |
| 35 | 278x |
if (length(day) == 1) day <- rep(day, n) |
| 36 |
} |
|
| 37 | ||
| 38 |
## Switch origin |
|
| 39 | 358x |
year <- (year - calendar_epoch(calendar)) * calendar_direction(calendar) |
| 40 | ||
| 41 |
## Correct for 28- or 29-day Feb |
|
| 42 | 358x |
correction <- rep(-2, length(year)) |
| 43 | 358x |
correction[is_gregorian_leap_year(year)] <- -1 |
| 44 | 358x |
correction[month <= 2] <- 0 |
| 45 | ||
| 46 | 358x |
rd <- calendar_fixed(calendar) - 1 + # Days before start of calendar |
| 47 | 358x |
365 * (year - 1) + # Ordinary days since epoch |
| 48 | 358x |
(year - 1) %/% 4 - # Julian leap days since epoch minus... |
| 49 | 358x |
(year - 1) %/% 100 + # ...century years since epoch plus... |
| 50 | 358x |
(year - 1) %/% 400 + # ...years since epoch divisible by 400 |
| 51 | 358x |
(367 * month - 362) %/% 12 + # Days in prior months this year assuming 30-day Feb |
| 52 | 358x |
correction + # Correct for 28- or 29-day Feb |
| 53 | 358x |
day # Days so far this month. |
| 54 | ||
| 55 |
## Fix infinite values |
|
| 56 | 358x |
rd[is.infinite(year)] <- year[is.infinite(year)] |
| 57 | ||
| 58 | 358x |
.RataDie(rd) |
| 59 |
} |
|
| 60 |
) |
|
| 61 |
# Gregorian from fixed ========================================================= |
|
| 62 |
#' @export |
|
| 63 |
#' @rdname as_year |
|
| 64 |
#' @aliases as_year,numeric,GregorianCalendar-method |
|
| 65 |
setMethod( |
|
| 66 |
f = "as_year", |
|
| 67 |
signature = c(object = "numeric", calendar = "GregorianCalendar"), |
|
| 68 |
definition = function(object, calendar, decimal = TRUE, ...) {
|
|
| 69 | 144x |
d0 <- object - calendar_fixed(calendar) |
| 70 | 144x |
n400 <- d0 %/% 146097 |
| 71 | 144x |
d1 <- d0 %% 146097 |
| 72 | 144x |
n100 <- d1 %/% 36524 |
| 73 | 144x |
d2 <- d1 %% 36524 |
| 74 | 144x |
n4 <- d2 %/% 1461 |
| 75 | 144x |
d3 <- d2 %% 1461 |
| 76 | 144x |
n1 <- d3 %/% 365 |
| 77 | ||
| 78 | 144x |
year <- 400 * n400 + 100 * n100 + 4 * n4 + n1 |
| 79 | 144x |
year <- ifelse(n100 == 4 | n1 == 4, year, year + 1) |
| 80 | ||
| 81 |
## Shift origin |
|
| 82 | 144x |
year <- (year - calendar_epoch(calendar)) * calendar_direction(calendar) |
| 83 | ||
| 84 | 144x |
if (isTRUE(decimal)) {
|
| 85 |
## Year length in days |
|
| 86 | 118x |
start <- fixed(year, 01, 01, calendar = calendar) |
| 87 | 118x |
end <- fixed(year, 12, 31, calendar = calendar) |
| 88 | 118x |
total <- end - start + 1 |
| 89 | ||
| 90 |
## Elapsed time |
|
| 91 | 118x |
sofar <- object - start |
| 92 | ||
| 93 | 118x |
year <- year + sofar / total |
| 94 |
} |
|
| 95 | ||
| 96 |
## Fix infinite values |
|
| 97 | 144x |
year[is.infinite(object)] <- object[is.infinite(object)] |
| 98 | ||
| 99 | 144x |
year |
| 100 |
} |
|
| 101 |
) |
|
| 102 | ||
| 103 |
#' @export |
|
| 104 |
#' @rdname as_date |
|
| 105 |
#' @aliases as_date,numeric,GregorianCalendar-method |
|
| 106 |
setMethod( |
|
| 107 |
f = "as_date", |
|
| 108 |
signature = c(object = "numeric", calendar = "GregorianCalendar"), |
|
| 109 |
definition = function(object, calendar) {
|
|
| 110 | 9x |
year <- as_year(object, calendar = calendar, decimal = FALSE) |
| 111 | 9x |
prior_days <- object - fixed(year, 01, 01, calendar = calendar) |
| 112 | ||
| 113 | 9x |
correction <- rep(2, length(object)) |
| 114 | 9x |
correction[object < fixed(year, 03, 01, calendar = calendar)] <- 0 |
| 115 | 9x |
correction[is_gregorian_leap_year(year)] <- 1 |
| 116 | ||
| 117 | 9x |
month <- (12 * (prior_days + correction) + 373) %/% 367 |
| 118 | 9x |
day <- object - fixed(year, month, 01, calendar = calendar) + 1 |
| 119 | ||
| 120 | 9x |
data.frame( |
| 121 | 9x |
year = as.numeric(year), |
| 122 | 9x |
month = as.numeric(month), |
| 123 | 9x |
day = as.numeric(day) |
| 124 |
) |
|
| 125 |
} |
|
| 126 |
) |
|
| 127 | ||
| 128 |
# Era ========================================================================== |
|
| 129 |
#' @export |
|
| 130 |
#' @rdname fixed_gregorian |
|
| 131 |
fixed_from_BP <- function(year, month, day) {
|
|
| 132 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = BP()) |
| 133 | ! |
else fixed(year, month, day, calendar = BP()) |
| 134 |
} |
|
| 135 |
#' @export |
|
| 136 |
#' @rdname fixed_gregorian |
|
| 137 |
fixed_to_BP <- function(object) {
|
|
| 138 | 1x |
as_year(object, calendar = BP(), decimal = TRUE) |
| 139 |
} |
|
| 140 | ||
| 141 |
#' @export |
|
| 142 |
#' @rdname fixed_gregorian |
|
| 143 |
fixed_from_BC <- function(year, month, day) {
|
|
| 144 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = BC()) |
| 145 | ! |
else fixed(year, month, day, calendar = BC()) |
| 146 |
} |
|
| 147 |
#' @export |
|
| 148 |
#' @rdname fixed_gregorian |
|
| 149 |
fixed_to_BC <- function(object) {
|
|
| 150 | 1x |
as_year(object, calendar = BC(), decimal = TRUE) |
| 151 |
} |
|
| 152 | ||
| 153 |
#' @export |
|
| 154 |
#' @rdname fixed_gregorian |
|
| 155 |
fixed_from_BCE <- function(year, month, day) {
|
|
| 156 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = BCE()) |
| 157 | ! |
else fixed(year, month, day, calendar = BCE()) |
| 158 |
} |
|
| 159 |
#' @export |
|
| 160 |
#' @rdname fixed_gregorian |
|
| 161 |
fixed_to_BCE <- function(object) {
|
|
| 162 | 2x |
as_year(object, calendar = BCE(), decimal = TRUE) |
| 163 |
} |
|
| 164 | ||
| 165 |
#' @export |
|
| 166 |
#' @rdname fixed_gregorian |
|
| 167 |
fixed_from_AD <- function(year, month, day) {
|
|
| 168 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = AD()) |
| 169 | 15x |
else fixed(year, month, day, calendar = AD()) |
| 170 |
} |
|
| 171 |
#' @export |
|
| 172 |
#' @rdname fixed_gregorian |
|
| 173 |
fixed_to_AD <- function(object) {
|
|
| 174 | 1x |
as_year(object, calendar = AD(), decimal = TRUE) |
| 175 |
} |
|
| 176 | ||
| 177 |
#' @export |
|
| 178 |
#' @rdname fixed_gregorian |
|
| 179 |
fixed_from_CE <- function(year, month, day) {
|
|
| 180 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = CE()) |
| 181 | ! |
else fixed(year, month, day, calendar = CE()) |
| 182 |
} |
|
| 183 |
#' @export |
|
| 184 |
#' @rdname fixed_gregorian |
|
| 185 |
fixed_to_CE <- function(object) {
|
|
| 186 | 1x |
as_year(object, calendar = CE(), decimal = TRUE) |
| 187 |
} |
|
| 188 | ||
| 189 |
#' @export |
|
| 190 |
#' @rdname fixed_gregorian |
|
| 191 |
fixed_from_b2k <- function(year, month, day) {
|
|
| 192 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = b2k()) |
| 193 | ! |
else fixed(year, month, day, calendar = b2k()) |
| 194 |
} |
|
| 195 |
#' @export |
|
| 196 |
#' @rdname fixed_gregorian |
|
| 197 |
fixed_to_b2k <- function(object) {
|
|
| 198 | 1x |
as_year(object, calendar = b2k(), decimal = TRUE) |
| 199 |
} |
| 1 |
# AXIS |
|
| 2 | ||
| 3 |
# Pretty ======================================================================= |
|
| 4 |
#' @export |
|
| 5 |
#' @method pretty RataDie |
|
| 6 |
pretty.RataDie <- function(x, calendar = get_calendar(), ...) {
|
|
| 7 | ! |
if (is.null(calendar)) return(pretty(as.numeric(x), ...)) |
| 8 | ||
| 9 | 17x |
x <- as_year(x, calendar = calendar, decimal = FALSE) |
| 10 | 17x |
x <- pretty(x, ...) |
| 11 | 2x |
if (methods::is(calendar, "JulianCalendar")) x[x == 0] <- 1 |
| 12 | 17x |
fixed(year = x, calendar = calendar) |
| 13 |
} |
|
| 14 | ||
| 15 |
#' @export |
|
| 16 |
#' @rdname pretty |
|
| 17 |
setMethod("pretty", "RataDie", pretty.RataDie)
|
|
| 18 | ||
| 19 |
# Axis ========================================================================= |
|
| 20 |
#' @export |
|
| 21 |
#' @rdname year_axis |
|
| 22 |
year_axis <- function(side, at = NULL, format = c("a", "ka", "Ma", "Ga"),
|
|
| 23 |
labels = TRUE, calendar = get_calendar("current"),
|
|
| 24 |
current_calendar = get_calendar("current"),
|
|
| 25 |
...) {
|
|
| 26 | 19x |
no_at <- missing(at) || is.null(at) || !is.numeric(at) |
| 27 | 19x |
if (no_at) at <- graphics::axTicks(side = side) |
| 28 | ||
| 29 | 19x |
if (!is.logical(labels)) {
|
| 30 | ! |
labels <- labels[keep] |
| 31 | 19x |
} else if (isTRUE(labels)) {
|
| 32 |
## If last_calendar is NULL, then the last plot was expressed in rata die |
|
| 33 | 19x |
if (is.null(current_calendar)) {
|
| 34 | 3x |
at <- as_fixed(at) |
| 35 |
} else {
|
|
| 36 | 2x |
if (methods::is(calendar, "JulianCalendar")) at[at == 0] <- 1 |
| 37 | 16x |
at <- fixed(at, calendar = current_calendar) |
| 38 |
} |
|
| 39 | 19x |
if (!is.null(calendar)) {
|
| 40 | 16x |
at <- pretty(at, calendar = calendar) |
| 41 | 16x |
labels <- format(at, prefix = format, label = FALSE, calendar = calendar) |
| 42 | 16x |
if (!is.null(current_calendar)) at <- as_year(at, calendar = current_calendar) |
| 43 |
} |
|
| 44 | ! |
} else if (isFALSE(labels)) {
|
| 45 | ! |
labels <- rep("", length(at))
|
| 46 |
} |
|
| 47 | ||
| 48 | 19x |
graphics::axis(side, at = as.numeric(at), labels = labels, ...) |
| 49 |
} |
| 1 |
# GENERIC METHODS |
|
| 2 |
#' @include AllClasses.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Tools ======================================================================== |
|
| 6 |
## Mutators -------------------------------------------------------------------- |
|
| 7 |
# Get or Set Parts of an Object |
|
| 8 |
# |
|
| 9 |
# Getters and setters to extract or replace parts of an object. |
|
| 10 |
# @param x An object from which to get or set element(s). |
|
| 11 |
# @param value A possible value for the element(s) of `x`. |
|
| 12 |
# @return |
|
| 13 |
# An object of the same sort as `x` with the new values assigned. |
|
| 14 |
# @example inst/examples/ex-mutator.R |
|
| 15 |
# @author N. Frerebeau |
|
| 16 |
# @docType methods |
|
| 17 |
# @family mutators |
|
| 18 |
# @name mutators |
|
| 19 |
# @rdname mutators |
|
| 20 |
# @aliases get set |
|
| 21 |
# NULL |
|
| 22 | ||
| 23 |
#' Labels |
|
| 24 |
#' |
|
| 25 |
#' Find a suitable set of labels from an object. |
|
| 26 |
#' @param object An \R object. |
|
| 27 |
#' @param ... Currently not used. |
|
| 28 |
#' @return |
|
| 29 |
#' A [`character`] vector. |
|
| 30 |
#' @author N. Frerebeau |
|
| 31 |
#' @docType methods |
|
| 32 |
#' @family mutators |
|
| 33 |
#' @name labels |
|
| 34 |
#' @rdname labels |
|
| 35 |
NULL |
|
| 36 | ||
| 37 |
#' Names |
|
| 38 |
#' |
|
| 39 |
#' Get or set the names of an object. |
|
| 40 |
#' @param x An \R object. |
|
| 41 |
#' @param value A [`character`] vector of up to the same length as `x`, or |
|
| 42 |
#' `NULL`. |
|
| 43 |
#' @return |
|
| 44 |
#' The updated object. |
|
| 45 |
#' @author N. Frerebeau |
|
| 46 |
#' @docType methods |
|
| 47 |
#' @family mutators |
|
| 48 |
#' @name names |
|
| 49 |
#' @rdname names |
|
| 50 |
NULL |
|
| 51 | ||
| 52 |
#' Length |
|
| 53 |
#' |
|
| 54 |
#' Get the length of an object. |
|
| 55 |
#' @param x An \R object. |
|
| 56 |
#' @return |
|
| 57 |
#' A length-one [`integer`] vector. |
|
| 58 |
#' @author N. Frerebeau |
|
| 59 |
#' @docType methods |
|
| 60 |
#' @family mutators |
|
| 61 |
#' @name length |
|
| 62 |
#' @rdname length |
|
| 63 |
NULL |
|
| 64 | ||
| 65 |
## Subset ---------------------------------------------------------------------- |
|
| 66 |
#' Extract or Replace Parts of an Object |
|
| 67 |
#' |
|
| 68 |
#' Operators acting on objects to extract or replace parts. |
|
| 69 |
#' @param x An object from which to extract element(s) or in which to replace |
|
| 70 |
#' element(s). |
|
| 71 |
#' @param i,j,k Indices specifying elements to extract or replace. |
|
| 72 |
#' @param drop A [`logical`] scalar: should the result be coerced to |
|
| 73 |
#' the lowest possible dimension? This only works for extracting elements, |
|
| 74 |
#' not for the replacement. |
|
| 75 |
# @param value A possible value for the element(s) of `x`. |
|
| 76 |
# @param ... Currently not used. |
|
| 77 |
#' @return |
|
| 78 |
#' A subsetted object. |
|
| 79 |
# @example inst/examples/ex-subset.R |
|
| 80 |
#' @author N. Frerebeau |
|
| 81 |
#' @docType methods |
|
| 82 |
#' @family mutators |
|
| 83 |
#' @name subset |
|
| 84 |
#' @rdname subset |
|
| 85 |
NULL |
|
| 86 | ||
| 87 |
## Coerce ---------------------------------------------------------------------- |
|
| 88 |
#' Coerce to a Data Frame |
|
| 89 |
#' |
|
| 90 |
#' @param x A [`TimeSeries-class`] or a [`TimeIntervals-class`] object. |
|
| 91 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 92 |
#' (see [calendar()]). If `NULL` (the default), *rata die* are returned. |
|
| 93 |
#' @param ... Further parameters to be passed to [data.frame()]. |
|
| 94 |
#' @return |
|
| 95 |
#' A [`data.frame`]. |
|
| 96 |
#' @example inst/examples/ex-series.R |
|
| 97 |
#' @author N. Frerebeau |
|
| 98 |
#' @docType methods |
|
| 99 |
#' @family mutators |
|
| 100 |
#' @name as.data.frame |
|
| 101 |
#' @rdname as.data.frame |
|
| 102 |
NULL |
|
| 103 | ||
| 104 |
# Calendars ==================================================================== |
|
| 105 |
#' Calendar |
|
| 106 |
#' |
|
| 107 |
#' @param object A [`character`] string specifying the abbreviated label of |
|
| 108 |
#' the time scale (see details). |
|
| 109 |
#' @details |
|
| 110 |
#' The following time scales are available: |
|
| 111 |
#' |
|
| 112 |
#' \tabular{lll}{
|
|
| 113 |
#' **label** \tab **era** \tab **calendar** \cr |
|
| 114 |
#' `BP` \tab Before Present \tab Gregorian \cr |
|
| 115 |
#' `BC` \tab Before Christ \tab Gregorian \cr |
|
| 116 |
#' `BCE` \tab Before Common Era \tab Gregorian \cr |
|
| 117 |
#' `AD` \tab Anno Domini \tab Gregorian \cr |
|
| 118 |
#' `CE` \tab Common Era \tab Gregorian \cr |
|
| 119 |
#' `b2k` \tab Years before 2000 \tab Gregorian \cr |
|
| 120 |
#' `julian` \tab \tab Julian \cr |
|
| 121 |
#' } |
|
| 122 |
#' @return |
|
| 123 |
#' A [`TimeScale-class`] object. |
|
| 124 |
#' @note |
|
| 125 |
#' Inspired by [era::era()] by Joe Roe. |
|
| 126 |
#' @example inst/examples/ex-calendar.R |
|
| 127 |
#' @author N. Frerebeau |
|
| 128 |
#' @docType methods |
|
| 129 |
#' @family calendar tools |
|
| 130 |
#' @aliases calendar-method |
|
| 131 |
setGeneric( |
|
| 132 |
name = "calendar", |
|
| 133 |
def = function(object) standardGeneric("calendar"),
|
|
| 134 |
valueClass = "TimeScale" |
|
| 135 |
) |
|
| 136 | ||
| 137 |
#' Gregorian Calendar |
|
| 138 |
#' |
|
| 139 |
#' @param ... Currently not used. |
|
| 140 |
#' @return |
|
| 141 |
#' A [`GregorianCalendar-class`] object. |
|
| 142 |
#' @example inst/examples/ex-calendar.R |
|
| 143 |
#' @seealso [calendar()] |
|
| 144 |
#' @author N. Frerebeau |
|
| 145 |
#' @docType methods |
|
| 146 |
#' @family calendar tools |
|
| 147 |
#' @name gregorian |
|
| 148 |
#' @rdname gregorian |
|
| 149 |
NULL |
|
| 150 | ||
| 151 |
#' Julian Calendar |
|
| 152 |
#' |
|
| 153 |
#' @param ... Currently not used. |
|
| 154 |
#' @return |
|
| 155 |
#' A [`JulianCalendar-class`] object. |
|
| 156 |
#' @example inst/examples/ex-calendar.R |
|
| 157 |
#' @seealso [calendar()] |
|
| 158 |
#' @author N. Frerebeau |
|
| 159 |
#' @docType methods |
|
| 160 |
#' @family calendar tools |
|
| 161 |
#' @name julian |
|
| 162 |
#' @rdname julian |
|
| 163 |
NULL |
|
| 164 | ||
| 165 |
#' Get or Set the Default Calendar |
|
| 166 |
#' |
|
| 167 |
#' @param x A [`character`] string specifying the abbreviated label of |
|
| 168 |
#' the time scale (see [calendar()]) or an object from which to extract the |
|
| 169 |
#' time scale. |
|
| 170 |
#' @param which A [`character`] string specifying the calendar to be set. |
|
| 171 |
#' It must be one of "`default`" or "`current`". Note that "`current`" is |
|
| 172 |
#' automatically set by [plot()] or [image()] and should not be changed |
|
| 173 |
#' manually. |
|
| 174 |
#' @return |
|
| 175 |
#' A [`TimeScale-class`] object. |
|
| 176 |
#' @example inst/examples/ex-calendar.R |
|
| 177 |
#' @author N. Frerebeau |
|
| 178 |
#' @docType methods |
|
| 179 |
#' @family calendar tools |
|
| 180 |
#' @name get_calendar |
|
| 181 |
#' @rdname get_calendar |
|
| 182 |
NULL |
|
| 183 | ||
| 184 |
#' Calendar Parameters |
|
| 185 |
#' |
|
| 186 |
#' @param object A [`TimeScale-class`] object. |
|
| 187 |
#' @return |
|
| 188 |
#' * `calendar_label()` returns a [`character`] string giving the |
|
| 189 |
#' abbreviated label of the time scale. |
|
| 190 |
#' * `calendar_name()` returns a [`character`] string giving the name of |
|
| 191 |
#' the time scale. |
|
| 192 |
#' * `calendar_unit()` returns a [`character`] string giving the unit of |
|
| 193 |
#' the calendar. |
|
| 194 |
#' * `calendar_fixed()` returns a length-one [`numeric`] vector giving the |
|
| 195 |
#' reference date of the calendar (in *rata die*). |
|
| 196 |
#' * `calendar_epoch()` returns a length-one [`numeric`] vector giving the |
|
| 197 |
#' epoch year from which years are counted (starting date of the calendar, |
|
| 198 |
#' in years). |
|
| 199 |
#' * `calendar_direction()` returns a length-one [`integer`] vector specifying |
|
| 200 |
#' if years are counted backwards (\eqn{-1}) or forwards (\eqn{1}) from
|
|
| 201 |
#' `epoch`. Only the [sign][sign()] of `calendar_direction()` is relevant. |
|
| 202 |
#' * `calendar_year()` returns a length-one [`numeric`] vector giving the |
|
| 203 |
#' average length of the year in solar days. |
|
| 204 |
#' @example inst/examples/ex-calendar.R |
|
| 205 |
#' @author N. Frerebeau |
|
| 206 |
#' @docType methods |
|
| 207 |
#' @family calendar tools |
|
| 208 |
#' @name calendar_get |
|
| 209 |
#' @rdname calendar_get |
|
| 210 |
NULL |
|
| 211 | ||
| 212 |
#' @rdname calendar_get |
|
| 213 |
#' @aliases calendar_label-method |
|
| 214 |
setGeneric( |
|
| 215 |
name = "calendar_label", |
|
| 216 | 26x |
def = function(object) standardGeneric("calendar_label")
|
| 217 |
) |
|
| 218 | ||
| 219 |
#' @rdname calendar_get |
|
| 220 |
#' @aliases calendar_name-method |
|
| 221 |
setGeneric( |
|
| 222 |
name = "calendar_name", |
|
| 223 | 2x |
def = function(object) standardGeneric("calendar_name")
|
| 224 |
) |
|
| 225 | ||
| 226 |
#' @rdname calendar_get |
|
| 227 |
#' @aliases calendar_unit-method |
|
| 228 |
setGeneric( |
|
| 229 |
name = "calendar_unit", |
|
| 230 | 19x |
def = function(object) standardGeneric("calendar_unit")
|
| 231 |
) |
|
| 232 | ||
| 233 |
#' @rdname calendar_get |
|
| 234 |
#' @aliases calendar_epoch-method |
|
| 235 |
setGeneric( |
|
| 236 |
name = "calendar_epoch", |
|
| 237 | 507x |
def = function(object) standardGeneric("calendar_epoch")
|
| 238 |
) |
|
| 239 | ||
| 240 |
#' @rdname calendar_get |
|
| 241 |
#' @aliases calendar_fixed-method |
|
| 242 |
setGeneric( |
|
| 243 |
name = "calendar_fixed", |
|
| 244 | 560x |
def = function(object) standardGeneric("calendar_fixed")
|
| 245 |
) |
|
| 246 | ||
| 247 |
#' @rdname calendar_get |
|
| 248 |
#' @aliases calendar_direction-method |
|
| 249 |
setGeneric( |
|
| 250 |
name = "calendar_direction", |
|
| 251 | 523x |
def = function(object) standardGeneric("calendar_direction")
|
| 252 |
) |
|
| 253 | ||
| 254 |
#' @rdname calendar_get |
|
| 255 |
#' @aliases calendar_year-method |
|
| 256 |
setGeneric( |
|
| 257 |
name = "calendar_year", |
|
| 258 | 2x |
def = function(object) standardGeneric("calendar_year")
|
| 259 |
) |
|
| 260 | ||
| 261 |
# @rdname calendar_get |
|
| 262 |
# @aliases calendar_fixed-method |
|
| 263 |
# setGeneric( |
|
| 264 |
# name = "calendar_fixed", |
|
| 265 |
# def = function(object) standardGeneric("calendar_fixed")
|
|
| 266 |
# ) |
|
| 267 | ||
| 268 |
# @rdname calendar_get |
|
| 269 |
# @aliases calendar_year-method |
|
| 270 |
# setGeneric( |
|
| 271 |
# name = "calendar_year", |
|
| 272 |
# def = function(object) standardGeneric("calendar_year")
|
|
| 273 |
# ) |
|
| 274 | ||
| 275 |
#' Calendar Converter |
|
| 276 |
#' |
|
| 277 |
#' Interconverts dates in a variety of calendars. |
|
| 278 |
#' @param from A [`TimeScale-class`] object describing the source calendar. |
|
| 279 |
#' @param to A [`TimeScale-class`] object describing the target calendar. |
|
| 280 |
#' @param ... Currently not used. |
|
| 281 |
#' @return |
|
| 282 |
#' A [`function`] that when called with a single numeric argument (factional |
|
| 283 |
#' years) converts years from one calendar to another. |
|
| 284 |
#' @example inst/examples/ex-convert.R |
|
| 285 |
#' @author N. Frerebeau |
|
| 286 |
#' @docType methods |
|
| 287 |
#' @family calendar tools |
|
| 288 |
#' @aliases convert-method |
|
| 289 |
setGeneric( |
|
| 290 |
name = "convert", |
|
| 291 | 4x |
def = function(from, to, ...) standardGeneric("convert")
|
| 292 |
) |
|
| 293 | ||
| 294 |
# Fixed Dates ================================================================== |
|
| 295 |
#' *Rata Die* (Fixed Date) |
|
| 296 |
#' |
|
| 297 |
#' @param year A [`numeric`] vector of years. If `month` and `day` are missing, |
|
| 298 |
#' decimal years are expected. |
|
| 299 |
#' @param month A [`numeric`] vector of months. |
|
| 300 |
#' @param day A [`numeric`] vector of days. |
|
| 301 |
#' @param calendar A [`TimeScale-class`] object specifying the calendar of |
|
| 302 |
#' `year`, `month` and `day` (see [calendar()]). |
|
| 303 |
#' @param scale A length-one [`integer`] vector specifying the number of years |
|
| 304 |
#' represented by one unit. It should be a power of 10 (i.e. 1000 means ka). |
|
| 305 |
#' @param ... Currently not used. |
|
| 306 |
#' @details |
|
| 307 |
#' *Rata die* are represented as the number of days since 01-01-01 (Gregorian), |
|
| 308 |
#' with negative values for earlier dates. |
|
| 309 |
#' @return |
|
| 310 |
#' A [`RataDie-class`] object. |
|
| 311 |
#' @example inst/examples/ex-fixed.R |
|
| 312 |
#' @references |
|
| 313 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 314 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 315 |
#' \doi{10.1017/9781107415058}.
|
|
| 316 |
#' @author N. Frerebeau |
|
| 317 |
#' @docType methods |
|
| 318 |
#' @family fixed date tools |
|
| 319 |
#' @aliases fixed-method |
|
| 320 |
setGeneric( |
|
| 321 |
name = "fixed", |
|
| 322 |
def = function(year, month, day, calendar, ...) standardGeneric("fixed"),
|
|
| 323 |
valueClass = "RataDie" |
|
| 324 |
) |
|
| 325 | ||
| 326 |
#' Coerce to *Rata Die* |
|
| 327 |
#' |
|
| 328 |
#' @param from A [`numeric`] vector of *rata die*. |
|
| 329 |
#' @return |
|
| 330 |
#' A [`RataDie-class`] object. |
|
| 331 |
#' @example inst/examples/ex-fixed.R |
|
| 332 |
#' @references |
|
| 333 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 334 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 335 |
#' \doi{10.1017/9781107415058}.
|
|
| 336 |
#' @author N. Frerebeau |
|
| 337 |
#' @docType methods |
|
| 338 |
#' @family fixed date tools |
|
| 339 |
#' @aliases as_fixed-method |
|
| 340 |
setGeneric( |
|
| 341 |
name = "as_fixed", |
|
| 342 |
def = function(from) standardGeneric("as_fixed"),
|
|
| 343 |
valueClass = "RataDie" |
|
| 344 |
) |
|
| 345 | ||
| 346 |
#' Year Conversion from *Rata Die* |
|
| 347 |
#' |
|
| 348 |
#' @param object A [`RataDie-class`] object (see [fixed()]). |
|
| 349 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 350 |
#' (see [calendar()]). |
|
| 351 |
#' @param decimal A [`logical`] scalar: should decimal years be returned? |
|
| 352 |
#' If `FALSE`, the decimal part is dropped. |
|
| 353 |
#' @param ... Currently not used. |
|
| 354 |
#' @return |
|
| 355 |
#' A [`numeric`] vector of (decimal) years. |
|
| 356 |
#' @example inst/examples/ex-fixed.R |
|
| 357 |
#' @references |
|
| 358 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 359 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 360 |
#' \doi{10.1017/9781107415058}.
|
|
| 361 |
#' @author N. Frerebeau |
|
| 362 |
#' @docType methods |
|
| 363 |
#' @family fixed date tools |
|
| 364 |
#' @aliases as_year-method |
|
| 365 |
setGeneric( |
|
| 366 |
name = "as_year", |
|
| 367 | 165x |
def = function(object, calendar, ...) standardGeneric("as_year")
|
| 368 |
) |
|
| 369 | ||
| 370 |
#' *Rata Die* Conversion to and from Gregorian Years |
|
| 371 |
#' |
|
| 372 |
#' Convenient functions for conversion from and to *rata die* for a given |
|
| 373 |
#' Gregorian era. |
|
| 374 |
#' @inheritParams fixed |
|
| 375 |
#' @inheritParams as_year |
|
| 376 |
#' @return |
|
| 377 |
#' * `fixed_from_*()` returns a [`RataDie-class`] object. |
|
| 378 |
#' * `fixed_to_*()` returns a [`numeric`] vector of Gregorian years. |
|
| 379 |
#' @example inst/examples/ex-fixed.R |
|
| 380 |
#' @details |
|
| 381 |
#' The astronomical notation is used for Gregorian years (there *is* a year 0). |
|
| 382 |
#' @references |
|
| 383 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 384 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 385 |
#' \doi{10.1017/9781107415058}.
|
|
| 386 |
#' @author N. Frerebeau |
|
| 387 |
#' @docType methods |
|
| 388 |
#' @family fixed date tools |
|
| 389 |
#' @name fixed_gregorian |
|
| 390 |
#' @rdname fixed_gregorian |
|
| 391 |
NULL |
|
| 392 | ||
| 393 |
#' *Rata Die* Conversion to and from Julian Years |
|
| 394 |
#' |
|
| 395 |
#' Convenient functions for conversion from and to *rata die*. |
|
| 396 |
#' @inheritParams fixed |
|
| 397 |
#' @inheritParams as_year |
|
| 398 |
#' @return |
|
| 399 |
#' * `fixed_from_julian()` returns a [`RataDie-class`] object. |
|
| 400 |
#' * `fixed_to_julian()` returns a [`numeric`] vector of Julian years. |
|
| 401 |
#' @example inst/examples/ex-fixed.R |
|
| 402 |
#' @references |
|
| 403 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 404 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 405 |
#' \doi{10.1017/9781107415058}.
|
|
| 406 |
#' @author N. Frerebeau |
|
| 407 |
#' @docType methods |
|
| 408 |
#' @family fixed date tools |
|
| 409 |
#' @name fixed_julian |
|
| 410 |
#' @rdname fixed_julian |
|
| 411 |
NULL |
|
| 412 | ||
| 413 |
#' Date Conversion from *Rata Die* |
|
| 414 |
#' |
|
| 415 |
#' @param object A [`RataDie-class`] object (see [fixed()]). |
|
| 416 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 417 |
#' (see [calendar()]). |
|
| 418 |
#' @return |
|
| 419 |
#' A [`numeric`] vector of (decimal) years. |
|
| 420 |
#' @example inst/examples/ex-fixed.R |
|
| 421 |
#' @references |
|
| 422 |
#' Reingold, E. M. and Dershowitz, N. (2018). *Calendrical Calculations: |
|
| 423 |
#' The Ultimate Edition*. Cambridge University Press. |
|
| 424 |
#' \doi{10.1017/9781107415058}.
|
|
| 425 |
#' @author N. Frerebeau |
|
| 426 |
#' @docType methods |
|
| 427 |
#' @family fixed date tools |
|
| 428 |
#' @aliases as_date-method |
|
| 429 |
setGeneric( |
|
| 430 |
name = "as_date", |
|
| 431 |
def = function(object, calendar) standardGeneric("as_date"),
|
|
| 432 |
valueClass = "data.frame" |
|
| 433 |
) |
|
| 434 | ||
| 435 |
#' Converts a Date to a Decimal of its Year |
|
| 436 |
#' |
|
| 437 |
#' @param year A [`numeric`] vector of years. If `month` and `day` are missing, |
|
| 438 |
#' decimal years are expected. |
|
| 439 |
#' @param month A [`numeric`] vector of months. |
|
| 440 |
#' @param day A [`numeric`] vector of days. |
|
| 441 |
#' @param calendar A [`TimeScale-class`] object specifying the calendar of |
|
| 442 |
#' `year`, `month` and `day` (see [calendar()]). |
|
| 443 |
#' @return |
|
| 444 |
#' A [`numeric`] vector of (ecimal years. |
|
| 445 |
#' @example inst/examples/ex-fixed.R |
|
| 446 |
#' @author N. Frerebeau |
|
| 447 |
#' @docType methods |
|
| 448 |
#' @family fixed date tools |
|
| 449 |
#' @aliases as_decimal-method |
|
| 450 |
setGeneric( |
|
| 451 |
name = "as_decimal", |
|
| 452 | 4x |
def = function(year, month, day, calendar) standardGeneric("as_decimal")
|
| 453 |
) |
|
| 454 | ||
| 455 |
#' Date Conversion to Character |
|
| 456 |
#' |
|
| 457 |
#' @param x A [`RataDie-class`] object. |
|
| 458 |
#' @param prefix A [`character`] string specifying the prefix. |
|
| 459 |
#' It should be one of "`a`", "`ka`", "`Ma`" or "`Ga`". |
|
| 460 |
#' If `TRUE`, a good guess for an appropriate format is made. |
|
| 461 |
#' @param label A [`logical`] scalar: should the label of the calendar be |
|
| 462 |
#' displayed? |
|
| 463 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 464 |
#' (see [calendar()]). |
|
| 465 |
#' @param ... Currently not used. |
|
| 466 |
#' @return |
|
| 467 |
#' A [`character`] vector representing the date. |
|
| 468 |
#' @example inst/examples/ex-fixed.R |
|
| 469 |
#' @author N. Frerebeau |
|
| 470 |
#' @docType methods |
|
| 471 |
#' @family fixed date tools |
|
| 472 |
#' @name format |
|
| 473 |
#' @rdname format |
|
| 474 |
NULL |
|
| 475 | ||
| 476 |
#' Pretty Breakpoints |
|
| 477 |
#' |
|
| 478 |
#' @param x A [`RataDie-class`] object. |
|
| 479 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 480 |
#' (see [calendar()]). |
|
| 481 |
#' @param ... Further parameters to be passed to [base::pretty()]. |
|
| 482 |
#' @details |
|
| 483 |
#' `pretty()` computes a vector of increasing numbers which are "pretty" in |
|
| 484 |
#' decimal notation of `calendar`. Pretty breakpoints are then converted to |
|
| 485 |
#' *rata die*. |
|
| 486 |
#' @return |
|
| 487 |
#' A [`RataDie-class`] object. |
|
| 488 |
#' @docType methods |
|
| 489 |
#' @family fixed date tools |
|
| 490 |
#' @name pretty |
|
| 491 |
#' @rdname pretty |
|
| 492 |
NULL |
|
| 493 | ||
| 494 |
#' Arithmetic Operators |
|
| 495 |
#' |
|
| 496 |
#' Operators performing arithmetic operations. |
|
| 497 |
#' @param e1,e2 A [`RataDie-class`] object or a [`numeric`] vector. |
|
| 498 |
#' @details |
|
| 499 |
#' *Rata die* will be converted to a plain `numeric` vector if a computation no |
|
| 500 |
#' longer makes sense in temporal terms. |
|
| 501 |
#' @return |
|
| 502 |
#' A [`logical`] vector. |
|
| 503 |
#' @example inst/examples/ex-arith.R |
|
| 504 |
#' @author N. Frerebeau |
|
| 505 |
#' @docType methods |
|
| 506 |
#' @family fixed date tools |
|
| 507 |
#' @name arithmetic |
|
| 508 |
#' @rdname arithmetic |
|
| 509 |
NULL |
|
| 510 | ||
| 511 |
# Time Series ================================================================== |
|
| 512 |
#' Create Time Series |
|
| 513 |
#' |
|
| 514 |
#' @param object A [`numeric`] `vector`, `matrix` or `array` of the observed |
|
| 515 |
#' time-series values. A [`data.frame`] will be coerced to a `numeric` `matrix` |
|
| 516 |
#' via [data.matrix()]. |
|
| 517 |
#' @param time A [`numeric`] vector of (decimal) years or a [`RataDie-class`] |
|
| 518 |
#' object (see [fixed()]). |
|
| 519 |
#' @param calendar A [`TimeScale-class`] object specifying the calendar of |
|
| 520 |
#' `time` (see [calendar()]). If missing, `time` must be a [`RataDie-class`] |
|
| 521 |
#' object. |
|
| 522 |
#' @param scale A length-one [`numeric`] vector specifying the number of years |
|
| 523 |
#' represented by one unit. It should be a power of 10 (i.e. 1000 means ka). |
|
| 524 |
#' @param names A [`character`] string specifying the names of the time |
|
| 525 |
#' series. |
|
| 526 |
#' @param ... Currently not used. |
|
| 527 |
#' @details |
|
| 528 |
#' Data will be sorted in chronological order. |
|
| 529 |
#' @return |
|
| 530 |
#' A [`TimeSeries-class`] object. |
|
| 531 |
#' @example inst/examples/ex-series.R |
|
| 532 |
#' @author N. Frerebeau |
|
| 533 |
#' @docType methods |
|
| 534 |
#' @family time series |
|
| 535 |
#' @aliases series-method |
|
| 536 |
setGeneric( |
|
| 537 |
name = "series", |
|
| 538 |
def = function(object, time, calendar, ...) standardGeneric("series"),
|
|
| 539 |
valueClass = "TimeSeries" |
|
| 540 |
) |
|
| 541 | ||
| 542 |
# Time Intervals =============================================================== |
|
| 543 |
#' Create Time Intervals |
|
| 544 |
#' |
|
| 545 |
#' An Interval is elapsed time in seconds between two specific years. |
|
| 546 |
#' @param start A [`numeric`] vector of (decimal) years or a [`RataDie-class`] |
|
| 547 |
#' object (see [fixed()]) giving the beginning of the time intervals. |
|
| 548 |
#' @param end A [`numeric`] vector of (decimal) years or a [`RataDie-class`] |
|
| 549 |
#' object (see [fixed()]) giving the end of the time intervals. |
|
| 550 |
#' @param calendar A [`TimeScale-class`] object specifying the calendar of |
|
| 551 |
#' `time` (see [calendar()]). If missing, `time` must be a [`RataDie-class`] |
|
| 552 |
#' object. |
|
| 553 |
#' @param scale A length-one [`numeric`] vector specifying the number of years |
|
| 554 |
#' represented by one unit. It should be a power of 10 (i.e. 1000 means ka). |
|
| 555 |
#' @param names A [`character`] string specifying the names of the time |
|
| 556 |
#' series. |
|
| 557 |
#' @param ... Currently not used. |
|
| 558 |
#' @return |
|
| 559 |
#' A [`TimeIntervals-class`] object. |
|
| 560 |
#' @example inst/examples/ex-intervals.R |
|
| 561 |
#' @author N. Frerebeau |
|
| 562 |
#' @docType methods |
|
| 563 |
#' @family time intervals |
|
| 564 |
#' @aliases intervals-method |
|
| 565 |
setGeneric( |
|
| 566 |
name = "intervals", |
|
| 567 |
def = function(start, end, calendar, ...) standardGeneric("intervals"),
|
|
| 568 |
valueClass = "TimeIntervals" |
|
| 569 |
) |
|
| 570 | ||
| 571 |
# Tools ======================================================================== |
|
| 572 |
#' Terminal Times |
|
| 573 |
#' |
|
| 574 |
#' Get the times the first and last observations were taken. |
|
| 575 |
#' @param x A [`TimeSeries-class`] object. |
|
| 576 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 577 |
#' (see [calendar()]). If `NULL` (the default), *rata die* are returned. |
|
| 578 |
#' @param ... Currently not used. |
|
| 579 |
#' @return |
|
| 580 |
#' A [`numeric`] vector of decimal years (if `calendar` is not `NULL`). |
|
| 581 |
#' @example inst/examples/ex-series.R |
|
| 582 |
#' @author N. Frerebeau |
|
| 583 |
#' @docType methods |
|
| 584 |
#' @family tools |
|
| 585 |
#' @aliases start-method end-method |
|
| 586 |
#' @name start |
|
| 587 |
#' @rdname start |
|
| 588 |
NULL |
|
| 589 | ||
| 590 |
#' Sampling Times |
|
| 591 |
#' |
|
| 592 |
#' Get the sampling times: |
|
| 593 |
#' * `time()` creates the vector of times at which a time series was sampled. |
|
| 594 |
#' * `frequency()` returns the mean number of samples per unit time. |
|
| 595 |
#' @param x A [`TimeSeries-class`] object. |
|
| 596 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 597 |
#' (see [calendar()]). If `NULL` (the default), *rata die* are returned. |
|
| 598 |
#' @param ... Currently not used. |
|
| 599 |
#' @return |
|
| 600 |
#' A [`numeric`] vector of decimal years (if `calendar` is not `NULL`). |
|
| 601 |
#' @example inst/examples/ex-series.R |
|
| 602 |
#' @author N. Frerebeau |
|
| 603 |
#' @docType methods |
|
| 604 |
#' @family tools |
|
| 605 |
#' @aliases time-method frequency-method |
|
| 606 |
#' @name time |
|
| 607 |
#' @rdname time |
|
| 608 |
NULL |
|
| 609 | ||
| 610 |
#' Time Windows |
|
| 611 |
#' |
|
| 612 |
#' Extracts the subset of the object `x` observed between the times `start` and |
|
| 613 |
#' `end` (expressed in *rata die*). |
|
| 614 |
#' @param x A [`TimeSeries-class`] object. |
|
| 615 |
#' @param start A length-one [`numeric`] vector specifying the start time of the |
|
| 616 |
#' period of interest. |
|
| 617 |
#' @param end A length-one [`numeric`] vector specifying the end time of the |
|
| 618 |
#' period of interest. |
|
| 619 |
#' @param ... Currently not used. |
|
| 620 |
#' @return |
|
| 621 |
#' A [`TimeSeries-class`] object. |
|
| 622 |
#' @example inst/examples/ex-window.R |
|
| 623 |
#' @author N. Frerebeau |
|
| 624 |
#' @docType methods |
|
| 625 |
#' @family tools |
|
| 626 |
#' @aliases window-method |
|
| 627 |
#' @name window |
|
| 628 |
#' @rdname window |
|
| 629 |
NULL |
|
| 630 | ||
| 631 |
#' Duration |
|
| 632 |
#' |
|
| 633 |
#' Get the duration of time series or intervals. |
|
| 634 |
#' @param x A [`TimeSeries-class`] or a [`TimeIntervals-class`] object. |
|
| 635 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 636 |
#' (see [calendar()]). If `NULL` (the default), *rata die* are returned. |
|
| 637 |
#' @param ... Currently not used. |
|
| 638 |
#' @return |
|
| 639 |
#' A [`numeric`] vector of years. |
|
| 640 |
#' @example inst/examples/ex-duration.R |
|
| 641 |
#' @author N. Frerebeau |
|
| 642 |
#' @docType methods |
|
| 643 |
#' @family tools |
|
| 644 |
#' @aliases span-method |
|
| 645 |
setGeneric( |
|
| 646 |
name = "span", |
|
| 647 | 8x |
def = function(x, ...) standardGeneric("span")
|
| 648 |
) |
|
| 649 | ||
| 650 |
# Plot ========================================================================= |
|
| 651 |
#' Plot Time Series and Time Intervals |
|
| 652 |
#' |
|
| 653 |
#' @param x A [`TimeSeries-class`] or a [`TimeIntervals-class`] object. |
|
| 654 |
#' @param facet A [`character`] string specifying whether the series should be |
|
| 655 |
#' plotted separately (with a common time axis) or on a single plot? |
|
| 656 |
#' It must be one of "`multiple`" or "`single`". Any unambiguous substring can |
|
| 657 |
#' be given. |
|
| 658 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 659 |
#' (see [calendar()]). |
|
| 660 |
#' @param groups A [`character`] vector specifying the group each interval |
|
| 661 |
#' belongs to. |
|
| 662 |
#' @param sort A [`logical`] scalar: should the data be sorted in chronological |
|
| 663 |
#' order? |
|
| 664 |
#' @param decreasing A [`logical`] scalar: should the sort order be decreasing? |
|
| 665 |
#' Only used if `sort` is `TRUE`. |
|
| 666 |
#' @param panel A [`function`] in the form `function(x, y, ...)` |
|
| 667 |
#' which gives the action to be carried out in each panel of the display. |
|
| 668 |
#' The default is [graphics::lines()]. |
|
| 669 |
#' @param flip A [`logical`] scalar: should the y-axis (ticks and numbering) be |
|
| 670 |
#' flipped from side 2 (left) to 4 (right) from series to series when `facet` |
|
| 671 |
#' is "`multiple`"? |
|
| 672 |
#' @param ncol An [`integer`] specifying the number of columns to use when |
|
| 673 |
#' `facet` is "`multiple`". Defaults to 1 for up to 4 series, otherwise to 2. |
|
| 674 |
#' @param xlab,ylab A [`character`] vector giving the x and y axis labels. |
|
| 675 |
#' @param main A [`character`] string giving a main title for the plot. |
|
| 676 |
#' @param sub A [`character`] string giving a subtitle for the plot. |
|
| 677 |
#' @param ann A [`logical`] scalar: should the default annotation (title and x |
|
| 678 |
#' and y axis labels) appear on the plot? |
|
| 679 |
#' @param axes A [`logical`] scalar: should axes be drawn on the plot? |
|
| 680 |
#' @param frame.plot A [`logical`] scalar: should a box be drawn around the |
|
| 681 |
#' plot? |
|
| 682 |
#' @param panel.first An `expression` to be evaluated after the plot axes are |
|
| 683 |
#' set up but before any plotting takes place. This can be useful for drawing |
|
| 684 |
#' background grids. |
|
| 685 |
#' @param panel.last An `expression` to be evaluated after plotting has taken |
|
| 686 |
#' place but before the axes, title and box are added. |
|
| 687 |
#' @param ... Further parameters to be passed to `panel` |
|
| 688 |
#' (e.g. [graphical parameters][graphics::par]). |
|
| 689 |
#' @return |
|
| 690 |
#' `plot()` is called for its side-effects: it results in a graphic |
|
| 691 |
#' being displayed. Invisibly returns `x`. |
|
| 692 |
#' @example inst/examples/ex-plot.R |
|
| 693 |
#' @seealso [graphics::plot()] |
|
| 694 |
#' @author N. Frerebeau |
|
| 695 |
#' @docType methods |
|
| 696 |
#' @family plotting tools |
|
| 697 |
#' @name plot |
|
| 698 |
#' @rdname plot |
|
| 699 |
NULL |
|
| 700 | ||
| 701 |
#' Heat Map |
|
| 702 |
#' |
|
| 703 |
#' @param x A [`TimeSeries-class`] object. |
|
| 704 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 705 |
#' (see [calendar()]). |
|
| 706 |
#' @param k An [`integer`] specifying the slice of `x` along the third |
|
| 707 |
#' dimension to be plotted. |
|
| 708 |
#' @param ... Further parameters to be passed to [graphics::image()]. |
|
| 709 |
#' @return |
|
| 710 |
#' `image()` is called for its side-effects: it results in a graphic |
|
| 711 |
#' being displayed. Invisibly returns `x`. |
|
| 712 |
#' @example inst/examples/ex-image.R |
|
| 713 |
#' @seealso [graphics::image()] |
|
| 714 |
#' @author N. Frerebeau |
|
| 715 |
#' @docType methods |
|
| 716 |
#' @family plotting tools |
|
| 717 |
#' @name image |
|
| 718 |
#' @rdname image |
|
| 719 |
NULL |
|
| 720 | ||
| 721 |
#' Time Series Plotting Functions |
|
| 722 |
#' |
|
| 723 |
#' @param side An [`integer`] specifying which side of the plot the axis is to |
|
| 724 |
#' be drawn on. The axis is placed as follows: 1=below, 2=left, 3=above and |
|
| 725 |
#' 4=right. |
|
| 726 |
#' @param at A [`numeric`] vector giving the points at which tick-marks are to |
|
| 727 |
#' be drawn. If `NULL`, tickmark locations are computed. |
|
| 728 |
#' @param format A [`character`] string specifying the prefix. |
|
| 729 |
#' It should be one of "`a`", "`ka`", "`Ma`" or "`Ga`". |
|
| 730 |
#' If `TRUE`, a good guess for an appropriate format is made. |
|
| 731 |
#' @param labels A [`logical`] scalar specifying whether annotations are to be |
|
| 732 |
#' made at the tickmarks, or a vector of [`character`] strings to be placed at |
|
| 733 |
#' the tickpoints. |
|
| 734 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 735 |
#' (see [calendar()]). |
|
| 736 |
#' @param current_calendar A [`TimeScale-class`] object specifying the calendar |
|
| 737 |
#' used by the last call to [plot()]. |
|
| 738 |
#' @param ... Further parameters to be passed to [graphics::axis()]. |
|
| 739 |
#' (e.g. [graphical parameters][graphics::par]). |
|
| 740 |
#' @return |
|
| 741 |
#' `year_axis()` is called it for its side-effects. |
|
| 742 |
#' @example inst/examples/ex-axis.R |
|
| 743 |
#' @author N. Frerebeau |
|
| 744 |
#' @docType methods |
|
| 745 |
#' @family plotting tools |
|
| 746 |
#' @name year_axis |
|
| 747 |
#' @rdname year_axis |
|
| 748 |
NULL |
|
| 749 | ||
| 750 |
# Chronological Reasoning ====================================================== |
|
| 751 |
#' Create a Graph |
|
| 752 |
#' |
|
| 753 |
#' Creates an interval or a stratigraphic graph. |
|
| 754 |
#' @param object A [`TimeIntervals-class`] object or a two-columns `character` |
|
| 755 |
#' [`matrix`] of edges (i.e. where each row specifies one relation element). |
|
| 756 |
#' @param type A [`character`] string specifying the type of the graph to be |
|
| 757 |
#' computed. It must be one of "`interval`" (the default) or "`stratigraphy`" |
|
| 758 |
#' (see details). Any unambiguous substring can be given. |
|
| 759 |
#' @param direction A [`character`] string specifying the direction of the |
|
| 760 |
#' relations in `x`. It must be one of "`above`" (the default) or "`below`" |
|
| 761 |
#' (see details). Any unambiguous substring can be given. |
|
| 762 |
#' Only relevant if `type` is "`stratigraphy`". |
|
| 763 |
#' @param verbose A [`logical`] scalar: should \R report extra information |
|
| 764 |
#' on progress? |
|
| 765 |
#' @param ... Currently not used. |
|
| 766 |
#' @details |
|
| 767 |
#' \describe{
|
|
| 768 |
#' \item{`interval`}{An interval graph is the graph showing intersecting
|
|
| 769 |
#' intervals on a line. As time is linear and not circular, an interval graph |
|
| 770 |
#' contains no cycles with more than three edges and no shortcuts (it must be |
|
| 771 |
#' a chordal graph).} |
|
| 772 |
#' \item{`stratigraphy`}{A stratigraphic graph represents the directed
|
|
| 773 |
#' relationships between temporal units (archaeological deposits), from the |
|
| 774 |
#' most recent to the oldest (Harris 1997). It can be formally defined as a |
|
| 775 |
#' directed acyclic graph (DAG), in which each vertex represents a layer and |
|
| 776 |
#' the edges represent stratigraphic relations.} |
|
| 777 |
#' } |
|
| 778 |
#' @return |
|
| 779 |
#' An \pkg{igraph} graph object.
|
|
| 780 |
#' @note |
|
| 781 |
#' Experimental. |
|
| 782 |
#' |
|
| 783 |
#' The \pkg{igraph} and \pkg{relations} packages need to be installed on your
|
|
| 784 |
#' machine. |
|
| 785 |
#' @references |
|
| 786 |
#' Harris, Edward C., 1997. *Principles of Archaeological Stratigraphy*. |
|
| 787 |
#' Seconde edition. Academic Press. |
|
| 788 |
#' @example inst/examples/ex-graph.R |
|
| 789 |
#' @author N. Frerebeau |
|
| 790 |
#' @docType methods |
|
| 791 |
#' @family graph tools |
|
| 792 |
#' @aliases graph_create-method |
|
| 793 |
setGeneric( |
|
| 794 |
name = "graph_create", |
|
| 795 | 10x |
def = function(object, ...) standardGeneric("graph_create")
|
| 796 |
) |
|
| 797 | ||
| 798 |
#' Prune a Graph |
|
| 799 |
#' |
|
| 800 |
#' Removes redundant relations from a graph. |
|
| 801 |
#' @param object An \pkg{igraph} object (typically returned by
|
|
| 802 |
#' [graph_create()]). |
|
| 803 |
#' @param reduce A [`logical`] scalar: should transitive reduction be performed? |
|
| 804 |
#' Only used if `object` is a directed acyclic graph. |
|
| 805 |
#' @param remove_multiple A [`logical`] scalar: should multiple edges be |
|
| 806 |
#' removed? |
|
| 807 |
#' @param remove_loops A [`logical`] scalar: should loop edges be removed? |
|
| 808 |
#' @param ... Currently not used. |
|
| 809 |
#' @return |
|
| 810 |
#' An \pkg{igraph} graph object.
|
|
| 811 |
#' @note |
|
| 812 |
#' Experimental. |
|
| 813 |
#' |
|
| 814 |
#' The \pkg{igraph} and \pkg{relations} packages need to be installed on your
|
|
| 815 |
#' machine. |
|
| 816 |
#' @example inst/examples/ex-graph.R |
|
| 817 |
#' @author N. Frerebeau |
|
| 818 |
#' @docType methods |
|
| 819 |
#' @family graph tools |
|
| 820 |
#' @aliases graph_prune-method |
|
| 821 |
setGeneric( |
|
| 822 |
name = "graph_prune", |
|
| 823 | 1x |
def = function(object, ...) standardGeneric("graph_prune")
|
| 824 |
) |
|
| 825 | ||
| 826 |
# Temporal Relations =========================================================== |
|
| 827 |
#' Time Overlap |
|
| 828 |
#' |
|
| 829 |
#' Computes the length of overlap of time intervals. |
|
| 830 |
#' @param x A [`TimeIntervals-class`] object. |
|
| 831 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 832 |
#' (see [calendar()]). If `NULL` (the default), *rata die* are returned. |
|
| 833 |
#' @param aggregate A [`logical`] scalar: should disjoint intervals referring to |
|
| 834 |
#' the same event be aggregated? |
|
| 835 |
#' @param ... Currently not used. |
|
| 836 |
#' @details |
|
| 837 |
#' The overlap of two time intervals is a difference between the minimum value |
|
| 838 |
#' of the two upper boundaries and the maximum value of the two lower |
|
| 839 |
#' boundaries, plus 1. |
|
| 840 |
#' @return |
|
| 841 |
#' A symmetric `numeric` [`matrix`] of years. |
|
| 842 |
#' @example inst/examples/ex-intervals.R |
|
| 843 |
#' @author N. Frerebeau |
|
| 844 |
#' @docType methods |
|
| 845 |
#' @family temporal relations |
|
| 846 |
#' @aliases overlap-method |
|
| 847 |
setGeneric( |
|
| 848 |
name = "overlap", |
|
| 849 | 4x |
def = function(x, ...) standardGeneric("overlap")
|
| 850 |
) |
|
| 851 | ||
| 852 |
#' Temporal Relations |
|
| 853 |
#' |
|
| 854 |
#' Test for the logical relation between time intervals according to Allen's |
|
| 855 |
#' typology. |
|
| 856 |
#' @param x A [`TimeIntervals-class`] object. |
|
| 857 |
#' @param ... Currently not used. |
|
| 858 |
#' @details |
|
| 859 |
#' Allen (1983) proposed thirteen basic relations between time intervals that |
|
| 860 |
#' are (Alspaugh 2019): |
|
| 861 |
#' |
|
| 862 |
#' * **Distinct**: no pair of definite intervals can be related by more than |
|
| 863 |
#' one of the relationships. |
|
| 864 |
#' * **Exhaustive:** any pair of definite intervals are described by one of the |
|
| 865 |
#' relations. |
|
| 866 |
#' * **Qualitative:** no numeric time spans are considered. |
|
| 867 |
#' |
|
| 868 |
#' \tabular{lrlr}{
|
|
| 869 |
#' **Relation** \tab \tab \tab **Converse** \cr |
|
| 870 |
#' precedes \tab (p) \tab (P) \tab preceded by \cr |
|
| 871 |
#' meets \tab (m) \tab (M) \tab met by \cr |
|
| 872 |
#' overlaps \tab (o) \tab (O) \tab overlapped by \cr |
|
| 873 |
#' finished by \tab (F) \tab (f) \tab finishes \cr |
|
| 874 |
#' contains \tab (D) \tab (d) \tab during \cr |
|
| 875 |
#' starts \tab (s) \tab (S) \tab started by \cr |
|
| 876 |
#' equals \tab (e) \tab \tab \cr |
|
| 877 |
#' } |
|
| 878 |
#' |
|
| 879 |
#' A *precedes* B |
|
| 880 |
#' |
|
| 881 |
#' ``` |
|
| 882 |
#' A === |
|
| 883 |
#' B === |
|
| 884 |
#' ``` |
|
| 885 |
#' |
|
| 886 |
#' A *preceded by* B |
|
| 887 |
#' |
|
| 888 |
#' ``` |
|
| 889 |
#' A === |
|
| 890 |
#' B === |
|
| 891 |
#' ``` |
|
| 892 |
#' |
|
| 893 |
#' A *meets* B |
|
| 894 |
#' |
|
| 895 |
#' ``` |
|
| 896 |
#' A === |
|
| 897 |
#' B === |
|
| 898 |
#' ``` |
|
| 899 |
#' |
|
| 900 |
#' A *met by* B |
|
| 901 |
#' |
|
| 902 |
#' ``` |
|
| 903 |
#' A === |
|
| 904 |
#' B === |
|
| 905 |
#' ``` |
|
| 906 |
#' |
|
| 907 |
#' A *overlaps* B |
|
| 908 |
#' |
|
| 909 |
#' ``` |
|
| 910 |
#' A === |
|
| 911 |
#' B === |
|
| 912 |
#' ``` |
|
| 913 |
#' |
|
| 914 |
#' A *overlapped by* B |
|
| 915 |
#' |
|
| 916 |
#' ``` |
|
| 917 |
#' A === |
|
| 918 |
#' B === |
|
| 919 |
#' ``` |
|
| 920 |
#' |
|
| 921 |
#' A *finished by* B |
|
| 922 |
#' |
|
| 923 |
#' ``` |
|
| 924 |
#' A ===== |
|
| 925 |
#' B === |
|
| 926 |
#' ``` |
|
| 927 |
#' |
|
| 928 |
#' A *finishes* B |
|
| 929 |
#' |
|
| 930 |
#' ``` |
|
| 931 |
#' A === |
|
| 932 |
#' B ===== |
|
| 933 |
#' ``` |
|
| 934 |
#' |
|
| 935 |
#' A *contains* B |
|
| 936 |
#' |
|
| 937 |
#' ``` |
|
| 938 |
#' A ===== |
|
| 939 |
#' B === |
|
| 940 |
#' ``` |
|
| 941 |
#' |
|
| 942 |
#' A *during* B |
|
| 943 |
#' |
|
| 944 |
#' ``` |
|
| 945 |
#' A === |
|
| 946 |
#' B ===== |
|
| 947 |
#' ``` |
|
| 948 |
#' |
|
| 949 |
#' A *starts* B |
|
| 950 |
#' |
|
| 951 |
#' ``` |
|
| 952 |
#' A === |
|
| 953 |
#' B ===== |
|
| 954 |
#' ``` |
|
| 955 |
#' |
|
| 956 |
#' A *started by* B |
|
| 957 |
#' |
|
| 958 |
#' ``` |
|
| 959 |
#' A ===== |
|
| 960 |
#' B === |
|
| 961 |
#' ``` |
|
| 962 |
#' |
|
| 963 |
#' A *equals* B |
|
| 964 |
#' |
|
| 965 |
#' ``` |
|
| 966 |
#' A === |
|
| 967 |
#' B === |
|
| 968 |
#' ``` |
|
| 969 |
#' |
|
| 970 |
#' @return |
|
| 971 |
#' A two-columns `matrix` where each row specifies one relation. |
|
| 972 |
#' @references |
|
| 973 |
#' Allen, J. F. (1983). Maintaining Knowledge about Temporal Intervals. |
|
| 974 |
#' *Communications of the ACM*, 26(11): 832-843. \doi{10.1145/182.358434}.
|
|
| 975 |
#' |
|
| 976 |
#' Alspaugh, T. (2019). Allen's Interval Algebra. |
|
| 977 |
#' URL: \url{https://thomasalspaugh.org/pub/fnd/allen.html}.
|
|
| 978 |
#' @example inst/examples/ex-relation.R |
|
| 979 |
#' @author N. Frerebeau |
|
| 980 |
#' @docType methods |
|
| 981 |
#' @family temporal relations |
|
| 982 |
#' @name relations |
|
| 983 |
#' @rdname relations |
|
| 984 |
NULL |
|
| 985 | ||
| 986 |
#' @rdname relations |
|
| 987 |
#' @aliases precedes-method |
|
| 988 |
setGeneric( |
|
| 989 |
name = "precedes", |
|
| 990 | 1x |
def = function(x, ...) standardGeneric("precedes")
|
| 991 |
) |
|
| 992 | ||
| 993 |
#' @rdname relations |
|
| 994 |
#' @aliases preceded_by-method |
|
| 995 |
setGeneric( |
|
| 996 |
name = "preceded_by", |
|
| 997 | 1x |
def = function(x, ...) standardGeneric("preceded_by")
|
| 998 |
) |
|
| 999 | ||
| 1000 |
#' @rdname relations |
|
| 1001 |
#' @aliases meets-method |
|
| 1002 |
setGeneric( |
|
| 1003 |
name = "meets", |
|
| 1004 | ! |
def = function(x, ...) standardGeneric("meets")
|
| 1005 |
) |
|
| 1006 | ||
| 1007 |
#' @rdname relations |
|
| 1008 |
#' @aliases met_by-method |
|
| 1009 |
setGeneric( |
|
| 1010 |
name = "met_by", |
|
| 1011 | 1x |
def = function(x, ...) standardGeneric("met_by")
|
| 1012 |
) |
|
| 1013 | ||
| 1014 |
#' @rdname relations |
|
| 1015 |
#' @aliases overlaps-method |
|
| 1016 |
setGeneric( |
|
| 1017 |
name = "overlaps", |
|
| 1018 | 2x |
def = function(x, ...) standardGeneric("overlaps")
|
| 1019 |
) |
|
| 1020 | ||
| 1021 |
#' @rdname relations |
|
| 1022 |
#' @aliases overlapped_by-method |
|
| 1023 |
setGeneric( |
|
| 1024 |
name = "overlapped_by", |
|
| 1025 | ! |
def = function(x, ...) standardGeneric("overlapped_by")
|
| 1026 |
) |
|
| 1027 | ||
| 1028 |
#' @rdname relations |
|
| 1029 |
#' @aliases finishes-method |
|
| 1030 |
setGeneric( |
|
| 1031 |
name = "finishes", |
|
| 1032 | 1x |
def = function(x, ...) standardGeneric("finishes")
|
| 1033 |
) |
|
| 1034 | ||
| 1035 |
#' @rdname relations |
|
| 1036 |
#' @aliases finished_by-method |
|
| 1037 |
setGeneric( |
|
| 1038 |
name = "finished_by", |
|
| 1039 | ! |
def = function(x, ...) standardGeneric("finished_by")
|
| 1040 |
) |
|
| 1041 | ||
| 1042 |
#' @rdname relations |
|
| 1043 |
#' @aliases contains-method |
|
| 1044 |
setGeneric( |
|
| 1045 |
name = "contains", |
|
| 1046 | 2x |
def = function(x, ...) standardGeneric("contains")
|
| 1047 |
) |
|
| 1048 | ||
| 1049 |
#' @rdname relations |
|
| 1050 |
#' @aliases during-method |
|
| 1051 |
setGeneric( |
|
| 1052 |
name = "during", |
|
| 1053 | ! |
def = function(x, ...) standardGeneric("during")
|
| 1054 |
) |
|
| 1055 | ||
| 1056 |
#' @rdname relations |
|
| 1057 |
#' @aliases starts-method |
|
| 1058 |
setGeneric( |
|
| 1059 |
name = "starts", |
|
| 1060 | 1x |
def = function(x, ...) standardGeneric("starts")
|
| 1061 |
) |
|
| 1062 | ||
| 1063 |
#' @rdname relations |
|
| 1064 |
#' @aliases started_by-method |
|
| 1065 |
setGeneric( |
|
| 1066 |
name = "started_by", |
|
| 1067 | ! |
def = function(x, ...) standardGeneric("started_by")
|
| 1068 |
) |
|
| 1069 | ||
| 1070 |
#' @rdname relations |
|
| 1071 |
#' @aliases equals-method |
|
| 1072 |
setGeneric( |
|
| 1073 |
name = "equals", |
|
| 1074 | 1x |
def = function(x, ...) standardGeneric("equals")
|
| 1075 |
) |
| 1 |
# CLASSES VALIDATION |
|
| 2 |
#' @include AllClasses.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# TimeScale ===================================================================== |
|
| 6 |
setValidity( |
|
| 7 |
Class = "TimeScale", |
|
| 8 |
method = function(object) {
|
|
| 9 |
## Get data |
|
| 10 |
label <- object@label |
|
| 11 |
name <- object@name |
|
| 12 |
epoch <- object@epoch |
|
| 13 |
fixed <- object@fixed |
|
| 14 |
direction <- object@direction |
|
| 15 |
year <- object@year |
|
| 16 | ||
| 17 |
## Validate |
|
| 18 |
cnd <- list( |
|
| 19 |
arkhe::validate(arkhe::assert_length(label, 1)), |
|
| 20 |
arkhe::validate(arkhe::assert_length(name, 1)), |
|
| 21 |
arkhe::validate(arkhe::assert_length(epoch, 1)), |
|
| 22 |
arkhe::validate(arkhe::assert_length(fixed, 1)), |
|
| 23 |
arkhe::validate(arkhe::assert_length(direction, 1)), |
|
| 24 |
arkhe::validate(arkhe::assert_length(year, 1)) |
|
| 25 |
) |
|
| 26 | ||
| 27 |
## Return conditions, if any |
|
| 28 |
arkhe::check_class(object, cnd) |
|
| 29 |
} |
|
| 30 |
) |
|
| 31 | ||
| 32 |
# Time Series ================================================================== |
|
| 33 |
# setValidity( |
|
| 34 |
# Class = "RataDie", |
|
| 35 |
# method = function(object) {
|
|
| 36 |
# |
|
| 37 |
# } |
|
| 38 |
# ) |
|
| 39 | ||
| 40 |
setValidity( |
|
| 41 |
Class = "TimeSeries", |
|
| 42 |
method = function(object) {
|
|
| 43 |
## Get data |
|
| 44 |
time <- object@.Time |
|
| 45 |
m <- nrow(object) |
|
| 46 | ||
| 47 |
## Validate |
|
| 48 |
cnd <- list( |
|
| 49 |
arkhe::validate(arkhe::assert_type(object, "numeric")), |
|
| 50 |
arkhe::validate(arkhe::assert_length(time, m)), |
|
| 51 |
arkhe::validate(arkhe::assert_infinite(time)) |
|
| 52 |
) |
|
| 53 | ||
| 54 |
## Return conditions, if any |
|
| 55 |
arkhe::check_class(object, cnd) |
|
| 56 |
} |
|
| 57 |
) |
|
| 58 | ||
| 59 |
setValidity( |
|
| 60 |
Class = "TimeIntervals", |
|
| 61 |
method = function(object) {
|
|
| 62 |
## Get data |
|
| 63 |
names <- object@.Id |
|
| 64 |
start <- object@.Start |
|
| 65 |
end <- object@.End |
|
| 66 |
m <- length(start) |
|
| 67 | ||
| 68 |
## Validate |
|
| 69 |
cnd <- list( |
|
| 70 |
arkhe::validate(arkhe::assert_length(names, m)), |
|
| 71 |
arkhe::validate(arkhe::assert_length(end, m)), |
|
| 72 |
arkhe::validate(arkhe::assert_missing(names)), |
|
| 73 |
arkhe::validate(arkhe::assert_missing(start)), |
|
| 74 |
arkhe::validate(arkhe::assert_missing(end)), |
|
| 75 |
arkhe::validate(assert_ordered(start, end)) |
|
| 76 |
) |
|
| 77 | ||
| 78 |
## Return conditions, if any |
|
| 79 |
arkhe::check_class(object, cnd) |
|
| 80 |
} |
|
| 81 |
) |
|
| 82 | ||
| 83 |
assert_ordered <- function(start, end) {
|
|
| 84 | 23x |
arg_start <- deparse(substitute(start)) |
| 85 | 23x |
arg_end <- deparse(substitute(end)) |
| 86 | 23x |
if (any(start > end)) {
|
| 87 | 1x |
msg <- sprintf(tr_("%s is later than %s."), sQuote(arg_start), sQuote(arg_end))
|
| 88 | 1x |
stop(msg) |
| 89 |
} |
|
| 90 | 22x |
invisible(NULL) |
| 91 |
} |
| 1 |
# TIME SCALE |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname calendar |
|
| 7 |
#' @aliases calendar,character-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "calendar", |
|
| 10 |
signature = "character", |
|
| 11 |
definition = function(object) {
|
|
| 12 |
switch ( |
|
| 13 | 50x |
tolower(object), |
| 14 | 7x |
bp = BP(), |
| 15 | ! |
b2k = b2k(), |
| 16 | ! |
bc = BC(), |
| 17 | 12x |
bce = BCE(), |
| 18 | 2x |
ad = AD(), |
| 19 | 27x |
ce = CE(), |
| 20 | 1x |
julian = J(), |
| 21 | 1x |
stop(sprintf(tr_("Unknown calendar: %s"), object), call. = FALSE)
|
| 22 |
) |
|
| 23 |
} |
|
| 24 |
) |
|
| 25 | ||
| 26 |
#' @export |
|
| 27 |
#' @rdname gregorian |
|
| 28 |
BP <- function(...) {
|
|
| 29 | 18x |
.GregorianCalendar( |
| 30 | 18x |
label = tr_("BP"),
|
| 31 | 18x |
name = tr_("Before Present"),
|
| 32 | 18x |
epoch = 1950, |
| 33 | 18x |
direction = -1L |
| 34 |
) |
|
| 35 |
} |
|
| 36 | ||
| 37 |
#' @export |
|
| 38 |
#' @rdname gregorian |
|
| 39 |
b2k <- function(...) {
|
|
| 40 | 5x |
.GregorianCalendar( |
| 41 | 5x |
label = tr_("b2k"),
|
| 42 | 5x |
name = tr_("Before 2000"),
|
| 43 | 5x |
epoch = 2000, |
| 44 | 5x |
direction = -1L |
| 45 |
) |
|
| 46 |
} |
|
| 47 | ||
| 48 |
#' @export |
|
| 49 |
#' @rdname gregorian |
|
| 50 |
BC <- function(...) {
|
|
| 51 | 2x |
.GregorianCalendar( |
| 52 | 2x |
label = tr_("BC"),
|
| 53 | 2x |
name = tr_("Before Christ"),
|
| 54 | 2x |
direction = -1L |
| 55 |
) |
|
| 56 |
} |
|
| 57 | ||
| 58 |
#' @export |
|
| 59 |
#' @rdname gregorian |
|
| 60 |
BCE <- function(...) {
|
|
| 61 | 21x |
.GregorianCalendar( |
| 62 | 21x |
label = tr_("BCE"),
|
| 63 | 21x |
name = tr_("Before Common Era"),
|
| 64 | 21x |
direction = -1L |
| 65 |
) |
|
| 66 |
} |
|
| 67 | ||
| 68 |
#' @export |
|
| 69 |
#' @rdname gregorian |
|
| 70 |
AD <- function(...) {
|
|
| 71 | 19x |
.GregorianCalendar( |
| 72 | 19x |
label = tr_("AD"),
|
| 73 | 19x |
name = tr_("Anno Domini")
|
| 74 |
) |
|
| 75 |
} |
|
| 76 | ||
| 77 |
#' @export |
|
| 78 |
#' @rdname gregorian |
|
| 79 |
CE <- function(...) {
|
|
| 80 | 78x |
.GregorianCalendar( |
| 81 | 78x |
label = tr_("CE"),
|
| 82 | 78x |
name = tr_("Common Era")
|
| 83 |
) |
|
| 84 |
} |
|
| 85 | ||
| 86 |
#' @export |
|
| 87 |
#' @rdname julian |
|
| 88 |
J <- function(...) {
|
|
| 89 | 15x |
.JulianCalendar( |
| 90 | 15x |
label = "", |
| 91 | 15x |
name = "" |
| 92 |
) |
|
| 93 |
} |
|
| 94 | ||
| 95 |
# Default calendar ============================================================= |
|
| 96 |
the <- new.env(parent = emptyenv()) |
|
| 97 |
the$default_calendar <- function(...) calendar("CE")
|
|
| 98 |
the$last_calendar <- function(...) return(NULL) |
|
| 99 | ||
| 100 |
#' @export |
|
| 101 |
#' @rdname get_calendar |
|
| 102 |
get_calendar <- function(which = c("default", "current")) {
|
|
| 103 | 32x |
which <- match.arg(which, several.ok = FALSE) |
| 104 | 32x |
which_calendar <- switch( |
| 105 | 32x |
which, |
| 106 | 32x |
default = "default_calendar", |
| 107 | 32x |
current = "last_calendar" |
| 108 |
) |
|
| 109 | ||
| 110 | 32x |
if (!exists(which_calendar, envir = the)) {
|
| 111 | ! |
stop(tr_("Unspecified calendar."), call. = FALSE)
|
| 112 |
} |
|
| 113 | ||
| 114 | 32x |
cal <- get(which_calendar, envir = the) |
| 115 | 32x |
if (!is.null(cal()) && !is_calendar(cal())) {
|
| 116 | ! |
stop(tr_("Invalid calendar."), call. = FALSE)
|
| 117 |
} |
|
| 118 | 32x |
return(cal()) |
| 119 |
} |
|
| 120 | ||
| 121 |
#' @export |
|
| 122 |
#' @rdname get_calendar |
|
| 123 |
set_calendar <- function(x, which = c("default", "current")) {
|
|
| 124 | 1x |
if (missing(x)) x <- "CE" |
| 125 | 2x |
which <- match.arg(which, several.ok = FALSE) |
| 126 | 2x |
which_calendar <- switch( |
| 127 | 2x |
which, |
| 128 | 2x |
default = "default_calendar", |
| 129 | 2x |
current = "last_calendar" |
| 130 |
) |
|
| 131 | ||
| 132 | 2x |
cal <- function(...) calendar(x) |
| 133 | 2x |
assign(which_calendar, value = cal, envir = the) |
| 134 | 2x |
invisible(cal()) |
| 135 |
} |
|
| 136 | ||
| 137 |
# Predicates =================================================================== |
|
| 138 |
#' Is an Object a Calendar? |
|
| 139 |
#' |
|
| 140 |
#' Test inheritance relationships between an object and a calendar class. |
|
| 141 |
#' @param object Any \R object. |
|
| 142 |
#' @return |
|
| 143 |
#' A [`logical`] scalar. |
|
| 144 |
#' @author N. Frerebeau |
|
| 145 |
#' @docType methods |
|
| 146 |
#' @family calendar tools |
|
| 147 |
#' @export |
|
| 148 |
is_calendar <- function(object) {
|
|
| 149 | 30x |
methods::is(object, "TimeScale") |
| 150 |
} |
|
| 151 | ||
| 152 |
#' @export |
|
| 153 |
#' @rdname is_calendar |
|
| 154 |
is_gregorian <- function(object) {
|
|
| 155 | 21x |
methods::is(object, "GregorianCalendar") |
| 156 |
} |
|
| 157 | ||
| 158 |
#' @export |
|
| 159 |
#' @rdname is_calendar |
|
| 160 |
is_julian <- function(object) {
|
|
| 161 | 6x |
methods::is(object, "JulianCalendar") |
| 162 |
} |
|
| 163 | ||
| 164 |
# Mutators ===================================================================== |
|
| 165 |
## Getters --------------------------------------------------------------------- |
|
| 166 |
#' @export |
|
| 167 |
#' @rdname calendar_get |
|
| 168 |
#' @aliases calendar_label,TimeScale-method |
|
| 169 |
setMethod( |
|
| 170 |
f = "calendar_label", |
|
| 171 |
signature = "TimeScale", |
|
| 172 | 26x |
definition = function(object) object@label |
| 173 |
) |
|
| 174 | ||
| 175 |
#' @export |
|
| 176 |
#' @rdname calendar_get |
|
| 177 |
#' @aliases calendar_name,TimeScale-method |
|
| 178 |
setMethod( |
|
| 179 |
f = "calendar_name", |
|
| 180 |
signature = "TimeScale", |
|
| 181 | 2x |
definition = function(object) object@name |
| 182 |
) |
|
| 183 | ||
| 184 |
#' @export |
|
| 185 |
#' @rdname calendar_get |
|
| 186 |
#' @aliases calendar_unit,TimeScale-method |
|
| 187 |
setMethod( |
|
| 188 |
f = "calendar_unit", |
|
| 189 |
signature = "TimeScale", |
|
| 190 |
definition = function(object) {
|
|
| 191 | 15x |
if (is_gregorian(object)) return(tr_("Gregorian years"))
|
| 192 | 4x |
if (is_julian(object)) return(tr_("Julian years"))
|
| 193 | ! |
return(tr_("Undefined"))
|
| 194 |
} |
|
| 195 |
) |
|
| 196 | ||
| 197 |
#' @export |
|
| 198 |
#' @rdname calendar_get |
|
| 199 |
#' @aliases calendar_epoch,TimeScale-method |
|
| 200 |
setMethod( |
|
| 201 |
f = "calendar_epoch", |
|
| 202 |
signature = "TimeScale", |
|
| 203 | 507x |
definition = function(object) object@epoch |
| 204 |
) |
|
| 205 | ||
| 206 |
#' @export |
|
| 207 |
#' @rdname calendar_get |
|
| 208 |
#' @aliases calendar_fixed,TimeScale-method |
|
| 209 |
setMethod( |
|
| 210 |
f = "calendar_fixed", |
|
| 211 |
signature = "TimeScale", |
|
| 212 | 560x |
definition = function(object) object@fixed |
| 213 |
) |
|
| 214 | ||
| 215 |
#' @export |
|
| 216 |
#' @rdname calendar_get |
|
| 217 |
#' @aliases calendar_direction,TimeScale-method |
|
| 218 |
setMethod( |
|
| 219 |
f = "calendar_direction", |
|
| 220 |
signature = "TimeScale", |
|
| 221 | 522x |
definition = function(object) sign(object@direction) |
| 222 |
) |
|
| 223 | ||
| 224 |
#' @export |
|
| 225 |
#' @rdname calendar_get |
|
| 226 |
#' @aliases calendar_direction,NULL-method |
|
| 227 |
setMethod( |
|
| 228 |
f = "calendar_direction", |
|
| 229 |
signature = "NULL", |
|
| 230 | 1x |
definition = function(object) 1L |
| 231 |
) |
|
| 232 | ||
| 233 |
#' @export |
|
| 234 |
#' @rdname calendar_get |
|
| 235 |
#' @aliases calendar_year,TimeScale-method |
|
| 236 |
setMethod( |
|
| 237 |
f = "calendar_year", |
|
| 238 |
signature = "TimeScale", |
|
| 239 | 2x |
definition = function(object) object@year |
| 240 |
) |
| 1 |
# YEAR |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Decimal years ================================================================ |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname as_decimal |
|
| 8 |
#' @aliases as_decimal,numeric,numeric,numeric,GregorianCalendar-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "as_decimal", |
|
| 11 |
signature = c(year = "numeric", month = "numeric", day = "numeric", calendar = "GregorianCalendar"), |
|
| 12 |
definition = function(year, month, day, calendar) {
|
|
| 13 |
## Shift origin |
|
| 14 | 3x |
year <- (year - calendar_epoch(calendar)) * calendar_direction(calendar) |
| 15 | ||
| 16 | 3x |
.as_decimal(year, month, day, calendar) |
| 17 |
} |
|
| 18 |
) |
|
| 19 | ||
| 20 |
#' @export |
|
| 21 |
#' @rdname as_decimal |
|
| 22 |
#' @aliases as_decimal,numeric,numeric,numeric,JulianCalendar-method |
|
| 23 |
setMethod( |
|
| 24 |
f = "as_decimal", |
|
| 25 |
signature = c(year = "numeric", month = "numeric", day = "numeric", calendar = "JulianCalendar"), |
|
| 26 |
definition = function(year, month, day, calendar) {
|
|
| 27 | 1x |
.as_decimal(year, month, day, calendar) |
| 28 |
} |
|
| 29 |
) |
|
| 30 | ||
| 31 |
.as_decimal <- function(year, month, day, calendar) {
|
|
| 32 |
## Year length in days |
|
| 33 | 4x |
start <- fixed(year, 01, 01, calendar = calendar) |
| 34 | 4x |
end <- fixed(year, 12, 31, calendar = calendar) |
| 35 | 4x |
total <- end - start + 1 |
| 36 | ||
| 37 |
## Elapsed time |
|
| 38 | 4x |
date <- fixed(year, month, day, calendar = calendar) |
| 39 | 4x |
sofar <- date - start |
| 40 | ||
| 41 | 4x |
unclass(year + sofar / total) |
| 42 |
} |
|
| 43 | ||
| 44 |
# Leap year ==================================================================== |
|
| 45 |
is_julian_leap_year <- function(year) {
|
|
| 46 | 43x |
year <- floor(year) # Drop decimal part (if any) |
| 47 | 43x |
leap <- year %% 4 == 3 |
| 48 | 43x |
leap[year > 0] <- year[year > 0] %% 4 == 0 |
| 49 | 43x |
leap |
| 50 |
} |
|
| 51 | ||
| 52 |
is_gregorian_leap_year <- function(year) {
|
|
| 53 | 435x |
year <- floor(year) # Drop decimal part (if any) |
| 54 | 435x |
((year %% 4) == 0) & |
| 55 | 435x |
(year %% 400 != 100) & |
| 56 | 435x |
(year %% 400 != 200) & |
| 57 | 435x |
(year %% 400 != 300) |
| 58 |
} |
| 1 |
# GRAPH |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# S3 class as S4 =============================================================== |
|
| 6 |
setClass("igraph")
|
|
| 7 | ||
| 8 |
# Create ======================================================================= |
|
| 9 |
#' @export |
|
| 10 |
#' @rdname graph_create |
|
| 11 |
#' @aliases graph_create,data.frame-method |
|
| 12 |
setMethod( |
|
| 13 |
f = "graph_create", |
|
| 14 |
signature = c(object = "data.frame"), |
|
| 15 |
definition = function(object, type = c("interval", "stratigraphy"),
|
|
| 16 |
direction = c("above", "below"),
|
|
| 17 |
verbose = getOption("aion.verbose"), ...) {
|
|
| 18 |
## Coerce to character matrix |
|
| 19 | 2x |
object[] <- lapply(X = object, FUN = as.character) |
| 20 | 2x |
object <- as.matrix(object) |
| 21 | ||
| 22 | 2x |
methods::callGeneric(object, type = type, direction = direction, |
| 23 | 2x |
verbose = verbose, ...) |
| 24 |
} |
|
| 25 |
) |
|
| 26 | ||
| 27 |
#' @export |
|
| 28 |
#' @rdname graph_create |
|
| 29 |
#' @aliases graph_create,matrix-method |
|
| 30 |
setMethod( |
|
| 31 |
f = "graph_create", |
|
| 32 |
signature = c(object = "matrix"), |
|
| 33 |
definition = function(object, type = c("interval", "stratigraphy"),
|
|
| 34 |
direction = c("above", "below"),
|
|
| 35 |
verbose = getOption("aion.verbose"), ...) {
|
|
| 36 |
## Validation |
|
| 37 | 6x |
arkhe::assert_package("igraph")
|
| 38 | 6x |
arkhe::assert_type(object, "character") |
| 39 | 6x |
arkhe::assert_dim(object, c(nrow(object), 2L)) |
| 40 | 6x |
type <- match.arg(type, several.ok = FALSE) |
| 41 | 6x |
direction <- match.arg(direction, several.ok = FALSE) |
| 42 | ||
| 43 |
## Remove singletons |
|
| 44 | 6x |
object <- arkhe::discard_rows(object, f = anyNA, verbose = verbose) |
| 45 | ||
| 46 |
## Graph type |
|
| 47 | 3x |
if (identical(type, "interval")) directed <- FALSE |
| 48 | 3x |
if (identical(type, "stratigraphy")) directed <- TRUE |
| 49 | ||
| 50 |
## Switch relations, if needed |
|
| 51 |
## (does not matter if type == "interval") |
|
| 52 | 6x |
if (identical(direction, "below")) {
|
| 53 | 1x |
object <- object[, c(2, 1)] |
| 54 |
} |
|
| 55 | ||
| 56 |
## Reorder |
|
| 57 | 6x |
object <- object[order(object[, 1], object[, 2]), ] |
| 58 | ||
| 59 |
## Create graph |
|
| 60 | 6x |
graph <- igraph::graph_from_edgelist(el = object, directed = directed) |
| 61 | ||
| 62 |
## Check |
|
| 63 | 3x |
if (identical(type, "interval")) assert_graph_chordal(graph) |
| 64 | 3x |
if (identical(type, "stratigraphy")) assert_graph_dag(graph) |
| 65 | ||
| 66 | 6x |
graph |
| 67 |
} |
|
| 68 |
) |
|
| 69 | ||
| 70 |
#' @export |
|
| 71 |
#' @rdname graph_create |
|
| 72 |
#' @aliases graph_create,TimeIntervals-method |
|
| 73 |
setMethod( |
|
| 74 |
f = "graph_create", |
|
| 75 |
signature = c(object = "TimeIntervals"), |
|
| 76 |
definition = function(object, type = c("interval", "stratigraphy"),
|
|
| 77 |
verbose = getOption("aion.verbose"), ...) {
|
|
| 78 |
## Validation |
|
| 79 | 2x |
type <- match.arg(type, several.ok = FALSE) |
| 80 | ||
| 81 |
## Detect relations |
|
| 82 | 2x |
rel <- switch( |
| 83 | 2x |
type, |
| 84 | 2x |
interval = rbind(overlaps(object), finishes(object), contains(object), |
| 85 | 2x |
starts(object), equals(object)), |
| 86 | 2x |
stratigraphy = rbind(preceded_by(object), met_by(object)) |
| 87 |
) |
|
| 88 | ||
| 89 | 2x |
methods::callGeneric(rel, type = type, direction = "above", |
| 90 | 2x |
verbose = verbose, ...) |
| 91 |
} |
|
| 92 |
) |
|
| 93 | ||
| 94 |
# Prune ======================================================================== |
|
| 95 |
#' @export |
|
| 96 |
#' @rdname graph_prune |
|
| 97 |
#' @aliases graph_prune,igraph-method |
|
| 98 |
setMethod( |
|
| 99 |
f = "graph_prune", |
|
| 100 |
signature = c(object = "igraph"), |
|
| 101 |
definition = function(object, reduce = TRUE, |
|
| 102 |
remove_multiple = TRUE, remove_loops = TRUE, ...) {
|
|
| 103 | ||
| 104 |
## Transitive reduction |
|
| 105 | 1x |
if (isTRUE(reduce) && isTRUE(igraph::is_dag(object))) {
|
| 106 | 1x |
arkhe::assert_package("relations")
|
| 107 | ||
| 108 | 1x |
edges <- as.matrix(object, matrix.type = c("edgelist"))
|
| 109 | 1x |
endo <- relations::endorelation( |
| 110 |
# domain = lapply(unique(as.character(edges)), sets::as.set), |
|
| 111 | 1x |
graph = as.data.frame(edges) |
| 112 |
) |
|
| 113 | 1x |
red <- relations::transitive_reduction(endo) |
| 114 | 1x |
mat <- relations::relation_incidence(red) |
| 115 | 1x |
object <- igraph::graph_from_adjacency_matrix(mat, mode = "directed") |
| 116 |
} |
|
| 117 | ||
| 118 |
## Remove multiple edges and loop edges |
|
| 119 | 1x |
if (isTRUE(remove_multiple) || isTRUE(remove_loops)) {
|
| 120 | 1x |
object <- igraph::simplify( |
| 121 | 1x |
object, |
| 122 | 1x |
remove.multiple = remove_multiple, |
| 123 | 1x |
remove.loops = remove_loops |
| 124 |
) |
|
| 125 |
} |
|
| 126 | ||
| 127 | 1x |
object |
| 128 |
} |
|
| 129 |
) |
|
| 130 | ||
| 131 |
# Check ======================================================================== |
|
| 132 |
## Check if DAG |
|
| 133 |
assert_graph_dag <- function(x, must_fail = FALSE) {
|
|
| 134 | 5x |
is_dag <- igraph::is_dag(x) |
| 135 | 5x |
if (!isTRUE(is_dag)) {
|
| 136 | 2x |
msg <- tr_("This is not a stratigraphic graph!")
|
| 137 | 2x |
do <- if (isTRUE(must_fail)) stop else warning |
| 138 | 2x |
do(msg, "\n", tr_("This is not a directed acyclic graph."), call. = FALSE)
|
| 139 |
} |
|
| 140 | 4x |
invisible(x) |
| 141 |
} |
|
| 142 | ||
| 143 |
## Check that there are no cycles with more than three nodes |
|
| 144 |
assert_graph_chordal <- function(x, must_fail = FALSE) {
|
|
| 145 | 3x |
is_chordal <- igraph::is_chordal(x)$chordal |
| 146 | 3x |
if (!isTRUE(is_chordal)) {
|
| 147 | 1x |
msg <- tr_("This is not an interval graph!")
|
| 148 | 1x |
do <- if (isTRUE(must_fail)) stop else warning |
| 149 | 1x |
do(msg, "\n", tr_("This is not a chordal graph."), call. = FALSE)
|
| 150 |
} |
|
| 151 | 3x |
invisible(x) |
| 152 |
} |
| 1 |
# SUBSET |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Extract ====================================================================== |
|
| 6 |
## [ --------------------------------------------------------------------------- |
|
| 7 |
#' @export |
|
| 8 |
#' @rdname subset |
|
| 9 |
#' @aliases [,RataDie-method |
|
| 10 |
setMethod( |
|
| 11 |
f = "[", |
|
| 12 |
signature = c(x = "RataDie"), |
|
| 13 |
function(x, i) {
|
|
| 14 | 320x |
z <- methods::callNextMethod() # Method for `numeric` |
| 15 | 320x |
methods::initialize(x, z) |
| 16 |
} |
|
| 17 |
) |
|
| 18 | ||
| 19 |
#' @export |
|
| 20 |
#' @rdname subset |
|
| 21 |
#' @aliases [,TimeIntervals-method |
|
| 22 |
setMethod( |
|
| 23 |
f = "[", |
|
| 24 |
signature = c(x = "TimeIntervals"), |
|
| 25 |
function(x, i) {
|
|
| 26 | ! |
id <- x@.Id[i] |
| 27 | ! |
start <- x@.Start[i] |
| 28 | ! |
end <- x@.End[i] |
| 29 | ! |
methods::initialize(x, .Id = id, .Start = start, .End = end) |
| 30 |
} |
|
| 31 |
) |
|
| 32 | ||
| 33 |
#' @export |
|
| 34 |
#' @rdname subset |
|
| 35 |
#' @aliases [,TimeSeries-method |
|
| 36 |
setMethod( |
|
| 37 |
f = "[", |
|
| 38 |
signature = c(x = "TimeSeries"), |
|
| 39 |
function(x, i, j, k, drop = FALSE) {
|
|
| 40 | 77x |
z <- x@.Data |
| 41 | 77x |
time <- x@.Time |
| 42 | ||
| 43 | 77x |
z <- z[i, j, k, drop = drop] |
| 44 | 42x |
if (isTRUE(drop)) return(z) |
| 45 | ||
| 46 | 35x |
if (!missing(i)) {
|
| 47 | ! |
if (is.character(i)) i <- match(i, dimnames(x)[1L]) |
| 48 | 4x |
time <- time[i] |
| 49 |
} |
|
| 50 | ||
| 51 | 35x |
methods::initialize(x, z, .Time = time) |
| 52 |
} |
|
| 53 |
) |
|
| 54 | ||
| 55 |
# Window ======================================================================= |
|
| 56 |
#' @export |
|
| 57 |
#' @method window TimeSeries |
|
| 58 |
window.TimeSeries <- function(x, start = NULL, end = NULL, ...) {
|
|
| 59 | 1x |
if (is.null(start)) start <- start(x) |
| 60 | 1x |
if (is.null(end)) end <- end(x) |
| 61 | 3x |
years <- time(x) |
| 62 | ||
| 63 | 3x |
i <- which(years >= start & years <= end) |
| 64 | 3x |
x[i, , , drop = FALSE] |
| 65 |
} |
|
| 66 | ||
| 67 |
#' @export |
|
| 68 |
#' @rdname window |
|
| 69 |
#' @aliases window,TimeSeries-method |
|
| 70 |
setMethod("window", "TimeSeries", window.TimeSeries)
|
| 1 |
# PLOT |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Plot ========================================================================= |
|
| 6 |
#' @export |
|
| 7 |
#' @method plot TimeIntervals |
|
| 8 |
plot.TimeIntervals <- function(x, calendar = get_calendar(), groups = NULL, |
|
| 9 |
sort = TRUE, decreasing = FALSE, |
|
| 10 |
xlab = NULL, ylab = NULL, |
|
| 11 |
main = NULL, sub = NULL, |
|
| 12 |
ann = graphics::par("ann"), axes = TRUE,
|
|
| 13 |
frame.plot = axes, |
|
| 14 |
panel.first = NULL, panel.last = NULL, ...) {
|
|
| 15 |
## Save calendar for further use, e.g. year_axis() |
|
| 16 | 4x |
assign("last_calendar", value = function(...) calendar, envir = the)
|
| 17 | ||
| 18 |
## Get data |
|
| 19 | 4x |
lab <- labels(x) |
| 20 | 4x |
int <- as.data.frame(x, calendar = calendar) |
| 21 | 4x |
k <- nrow(int) |
| 22 | 4x |
if (is.null(groups)) groups <- rep("", k)
|
| 23 | 4x |
arkhe::assert_length(groups, k) |
| 24 | ||
| 25 |
## Graphical parameters |
|
| 26 | 4x |
dots <- list(...) |
| 27 | 4x |
col <- make_par(dots, "col", k) |
| 28 | 4x |
lwd <- make_par(dots, "lwd", k) |
| 29 | 4x |
lty <- make_par(dots, "lty", k) |
| 30 | ||
| 31 |
## Sort and split |
|
| 32 | 4x |
if (sort) {
|
| 33 | 4x |
i <- order(groups, start(x), end(x), decreasing = decreasing) |
| 34 |
} else {
|
|
| 35 | ! |
i <- order(groups, decreasing = decreasing) |
| 36 |
} |
|
| 37 | 4x |
int <- int[i, , drop = FALSE] |
| 38 | 4x |
lab <- lab[i] |
| 39 | 4x |
f <- factor(x = lab, levels = unique(lab), ordered = TRUE) |
| 40 | 4x |
int <- split(x = int, f = f) |
| 41 | 4x |
col <- split(x = col[i], f = f) |
| 42 | 4x |
lwd <- split(x = lwd[i], f = f) |
| 43 | 4x |
lty <- split(x = lty[i], f = f) |
| 44 | 4x |
n <- length(int) |
| 45 | ||
| 46 |
## Open new window |
|
| 47 | 4x |
grDevices::dev.hold() |
| 48 | 4x |
on.exit(grDevices::dev.flush(), add = TRUE) |
| 49 | 4x |
graphics::plot.new() |
| 50 | ||
| 51 |
## Set plotting coordinates |
|
| 52 | 4x |
xlim <- xlim(x, calendar = calendar, finite = TRUE) |
| 53 | 4x |
ylim <- c(1, n) |
| 54 | 4x |
graphics::plot.window(xlim = xlim, ylim = ylim) |
| 55 | ||
| 56 |
## Evaluate pre-plot expressions |
|
| 57 | 4x |
panel.first |
| 58 | ||
| 59 |
## Plot |
|
| 60 | 4x |
for (i in seq_len(n)) {
|
| 61 | 48x |
x0 <- int[[i]]$start |
| 62 | 48x |
x1 <- int[[i]]$end |
| 63 | ||
| 64 |
## Fix infinite boundaries |
|
| 65 | 48x |
x0[is.infinite(x0)] <- graphics::par("usr")[[1L]]
|
| 66 | 48x |
x1[is.infinite(x1)] <- graphics::par("usr")[[2L]]
|
| 67 | ||
| 68 |
## Draw segments |
|
| 69 | 48x |
graphics::segments(x0 = x0, x1 = x1, y0 = i, y1 = i, |
| 70 | 48x |
col = col[[i]], lty = lty[[i]], lwd = lwd[[i]], lend = 1) |
| 71 |
} |
|
| 72 | ||
| 73 |
## Evaluate post-plot and pre-axis expressions |
|
| 74 | 4x |
panel.last |
| 75 | ||
| 76 |
## Construct Axis |
|
| 77 | 4x |
if (axes) {
|
| 78 | 4x |
year_axis(side = 1, format = TRUE, calendar = calendar) |
| 79 | 4x |
graphics::axis(side = 2, at = seq_len(n), labels = names(int), |
| 80 | 4x |
lty = 0, las = 1) |
| 81 |
} |
|
| 82 | ||
| 83 |
## Plot frame |
|
| 84 | 4x |
if (frame.plot) {
|
| 85 | 4x |
graphics::box() |
| 86 |
} |
|
| 87 | ||
| 88 |
## Add annotation |
|
| 89 | 4x |
if (ann) {
|
| 90 | 4x |
if (is.null(calendar)) {
|
| 91 | 1x |
cal_lab <- expression(italic("rata die"))
|
| 92 |
} else {
|
|
| 93 | 3x |
cal_lab <- format(calendar) |
| 94 |
} |
|
| 95 | 4x |
xlab <- xlab %||% cal_lab |
| 96 | 4x |
graphics::title(main = main, sub = sub, xlab = xlab, ylab = ylab) |
| 97 |
} |
|
| 98 | ||
| 99 | 4x |
invisible(x) |
| 100 |
} |
|
| 101 | ||
| 102 |
#' @export |
|
| 103 |
#' @rdname plot |
|
| 104 |
#' @aliases plot,TimeIntervals,missing-method |
|
| 105 |
setMethod("plot", c(x = "TimeIntervals", y = "missing"), plot.TimeIntervals)
|
|
| 106 | ||
| 107 |
#' @export |
|
| 108 |
#' @method plot TimeSeries |
|
| 109 |
plot.TimeSeries <- function(x, facet = c("multiple", "single"),
|
|
| 110 |
calendar = get_calendar(), |
|
| 111 |
panel = graphics::lines, flip = FALSE, ncol = NULL, |
|
| 112 |
xlab = NULL, ylab = NULL, |
|
| 113 |
main = NULL, sub = NULL, |
|
| 114 |
ann = graphics::par("ann"), axes = TRUE,
|
|
| 115 |
frame.plot = axes, |
|
| 116 |
panel.first = NULL, panel.last = NULL, ...) {
|
|
| 117 |
## Validation |
|
| 118 | 9x |
facet <- match.arg(facet, several.ok = FALSE) |
| 119 | ||
| 120 |
## Save calendar for further use, e.g. year_axis() |
|
| 121 | 9x |
assign("last_calendar", value = function(...) calendar, envir = the)
|
| 122 | ||
| 123 | 9x |
n <- dim(x)[2L] |
| 124 | ||
| 125 | 9x |
if (facet == "multiple" && n > 1) {
|
| 126 | 5x |
.plot_multiple(x, calendar = calendar, panel = panel, y_flip = flip, |
| 127 | 5x |
n_col = ncol, xlab = xlab, ylab = ylab, |
| 128 | 5x |
main = main, sub = sub, ann = ann, axes = axes, |
| 129 | 5x |
frame.plot = frame.plot, panel.first = panel.first, |
| 130 | 5x |
panel.last = panel.last, ...) |
| 131 |
} else {
|
|
| 132 | 4x |
.plot_single(x, calendar = calendar, panel = panel, |
| 133 | 4x |
xlab = xlab, ylab = ylab, |
| 134 | 4x |
main = main, sub = sub, |
| 135 | 4x |
ann = ann, axes = axes, |
| 136 | 4x |
frame.plot = frame.plot, panel.first = panel.first, |
| 137 | 4x |
panel.last = panel.last, ...) |
| 138 |
} |
|
| 139 | ||
| 140 | 9x |
invisible(x) |
| 141 |
} |
|
| 142 | ||
| 143 |
#' @export |
|
| 144 |
#' @rdname plot |
|
| 145 |
#' @aliases plot,TimeSeries,missing-method |
|
| 146 |
setMethod("plot", c(x = "TimeSeries", y = "missing"), plot.TimeSeries)
|
|
| 147 | ||
| 148 |
#' Single Panel Plot |
|
| 149 |
#' |
|
| 150 |
#' @param x A [`TimeSeries-class`] object. |
|
| 151 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 152 |
#' (see [calendar()]). |
|
| 153 |
#' @param panel A [`function`] in the form `function(x, y, ...)` |
|
| 154 |
#' which gives the action to be carried out in each panel of the display. |
|
| 155 |
#' The default is [graphics::lines()]. |
|
| 156 |
#' @param xlim,ylim A length-two [`numeric`] vector specifying the the x and y |
|
| 157 |
#' limits. |
|
| 158 |
#' @param main A [`character`] string giving a main title for the plot. |
|
| 159 |
#' @param sub A [`character`] string giving a subtitle for the plot. |
|
| 160 |
#' @param ann A [`logical`] scalar: should the default annotation (title and x |
|
| 161 |
#' and y axis labels) appear on the plot? |
|
| 162 |
#' @param axes A [`logical`] scalar: should axes be drawn on the plot? |
|
| 163 |
#' @param frame.plot A [`logical`] scalar: should a box be drawn around the |
|
| 164 |
#' plot? |
|
| 165 |
#' @param panel.first An an `expression` to be evaluated after the plot axes are |
|
| 166 |
#' set up but before any plotting takes place. This can be useful for drawing |
|
| 167 |
#' background grids. |
|
| 168 |
#' @param panel.last An `expression` to be evaluated after plotting has taken |
|
| 169 |
#' place but before the axes, title and box are added. |
|
| 170 |
#' @param ... Further parameters to be passed to `panel` |
|
| 171 |
#' (e.g. [graphical parameters][graphics::par]). |
|
| 172 |
#' @return |
|
| 173 |
#' Called for its side-effects: it results in a graphic being displayed. |
|
| 174 |
#' Invisibly returns `x`. |
|
| 175 |
#' @keywords internal |
|
| 176 |
#' @noRd |
|
| 177 |
.plot_single <- function(x, calendar, panel = graphics::lines, |
|
| 178 |
xlab = NULL, ylab = NULL, |
|
| 179 |
xlim = NULL, ylim = NULL, |
|
| 180 |
main = NULL, sub = NULL, |
|
| 181 |
ann = graphics::par("ann"), axes = TRUE,
|
|
| 182 |
frame.plot = axes, |
|
| 183 |
panel.first = NULL, panel.last = NULL, ...) {
|
|
| 184 | 34x |
n_series <- dim(x)[2L] |
| 185 | 34x |
n_dim <- dim(x)[3L] |
| 186 | ||
| 187 |
## Graphical parameters |
|
| 188 | 34x |
dots <- list(...) |
| 189 | 34x |
col <- make_par(dots, "col", n = n_dim) |
| 190 | 34x |
bg <- make_par(dots, "bg", n = n_dim) |
| 191 | 34x |
pch <- make_par(dots, "pch", n = n_dim) |
| 192 | 34x |
cex <- make_par(dots, "cex", n = n_dim) |
| 193 | 34x |
lwd <- make_par(dots, "lwd", n = n_dim) |
| 194 | 34x |
lty <- make_par(dots, "lty", n = n_dim) |
| 195 | ||
| 196 |
## Open new window |
|
| 197 | 34x |
grDevices::dev.hold() |
| 198 | 34x |
on.exit(grDevices::dev.flush(), add = TRUE) |
| 199 | 34x |
graphics::plot.new() |
| 200 | ||
| 201 |
## Set plotting coordinates |
|
| 202 | 34x |
years <- time(x, calendar = calendar) |
| 203 | 34x |
xlim <- xlim %||% xlim(x, calendar = calendar) |
| 204 | 34x |
ylim <- ylim %||% range(x, na.rm = TRUE) |
| 205 | 34x |
graphics::plot.window(xlim = xlim, ylim = ylim) |
| 206 | ||
| 207 |
## Evaluate pre-plot expressions |
|
| 208 | 34x |
panel.first |
| 209 | ||
| 210 |
## Plot |
|
| 211 | 34x |
for (j in seq_len(n_series)) {
|
| 212 | 39x |
for (k in seq_len(n_dim)) {
|
| 213 | 39x |
params <- list(col = col[k], bg = bg[k], pch = pch[k], |
| 214 | 39x |
cex = cex[k], lwd = lwd[k], lty = lty[k]) |
| 215 | 39x |
dots <- utils::modifyList(dots, params) |
| 216 | 39x |
args <- c(list(x = years, y = x[, j = j, k = k, drop = TRUE]), dots) |
| 217 | 39x |
do.call(panel, args) |
| 218 |
} |
|
| 219 |
} |
|
| 220 | ||
| 221 |
## Evaluate post-plot and pre-axis expressions |
|
| 222 | 34x |
panel.last |
| 223 | ||
| 224 |
## Construct Axis |
|
| 225 | 34x |
if (axes) {
|
| 226 | 1x |
year_axis(side = 1, format = TRUE, calendar = calendar) |
| 227 | 1x |
graphics::axis(side = 2, las = 1) |
| 228 |
} |
|
| 229 | ||
| 230 |
## Plot frame |
|
| 231 | 34x |
if (frame.plot) {
|
| 232 | 31x |
graphics::box() |
| 233 |
} |
|
| 234 | ||
| 235 |
## Add annotation |
|
| 236 | 34x |
if (ann) {
|
| 237 | 4x |
if (is.null(calendar)) {
|
| 238 | ! |
cal_lab <- expression(italic("rata die"))
|
| 239 |
} else {
|
|
| 240 | 4x |
cal_lab <- format(calendar) |
| 241 |
} |
|
| 242 | 4x |
xlab <- xlab %||% cal_lab |
| 243 | 4x |
graphics::title(main = main, sub = sub, xlab = xlab, ylab = ylab) |
| 244 |
} |
|
| 245 | ||
| 246 | 34x |
invisible(x) |
| 247 |
} |
|
| 248 | ||
| 249 |
#' Multiple Panels Plot |
|
| 250 |
#' |
|
| 251 |
#' @param x A [`TimeSeries-class`] object. |
|
| 252 |
#' @param calendar A [`TimeScale-class`] object specifying the target calendar |
|
| 253 |
#' (see [calendar()]). |
|
| 254 |
#' @param panel A [`function`] in the form `function(x, y, ...)` |
|
| 255 |
#' which gives the action to be carried out in each panel of the display. |
|
| 256 |
#' The default is [graphics::lines()]. |
|
| 257 |
#' @param y_flip A [`logical`] scalar: should the y-axis (ticks and numbering) |
|
| 258 |
#' be flipped from side 2 (left) to 4 (right) from series to series? |
|
| 259 |
#' @param y_fixed A [`logical`] scalar: should the y-scale be shared across |
|
| 260 |
#' all series? |
|
| 261 |
#' @param ncol An [`integer`] specifying the number of columns to use. |
|
| 262 |
#' Defaults to 1 for up to 4 series, otherwise to 2. |
|
| 263 |
#' @param main A [`character`] string giving a main title for the plot. |
|
| 264 |
#' @param sub A [`character`] string giving a subtitle for the plot. |
|
| 265 |
#' @param ann A [`logical`] scalar: should the default annotation (title and x |
|
| 266 |
#' and y axis labels) appear on the plot? |
|
| 267 |
#' @param axes A [`logical`] scalar: should axes be drawn on the plot? |
|
| 268 |
#' @param frame.plot A [`logical`] scalar: should a box be drawn around the |
|
| 269 |
#' plot? |
|
| 270 |
#' @param panel.first An an `expression` to be evaluated after the plot axes are |
|
| 271 |
#' set up but before any plotting takes place. This can be useful for drawing |
|
| 272 |
#' background grids. |
|
| 273 |
#' @param panel.last An `expression` to be evaluated after plotting has taken |
|
| 274 |
#' place but before the axes, title and box are added. |
|
| 275 |
#' @param ... Further parameters to be passed to `panel` |
|
| 276 |
#' (e.g. [graphical parameters][graphics::par]). |
|
| 277 |
#' @return |
|
| 278 |
#' Called for its side-effects: it results in a graphic being displayed. |
|
| 279 |
#' Invisibly returns `x`. |
|
| 280 |
#' @keywords internal |
|
| 281 |
#' @noRd |
|
| 282 |
.plot_multiple <- function(x, calendar, panel = graphics::lines, |
|
| 283 |
y_flip = TRUE, y_fixed = FALSE, n_col = NULL, |
|
| 284 |
xlab = NULL, ylab = NULL, |
|
| 285 |
main = NULL, sub = NULL, |
|
| 286 |
ann = graphics::par("ann"), axes = TRUE,
|
|
| 287 |
frame.plot = axes, |
|
| 288 |
panel.first = NULL, panel.last = NULL, ...) {
|
|
| 289 | ||
| 290 | 5x |
panel <- match.fun(panel) |
| 291 | 5x |
n <- dim(x)[2L] |
| 292 | 5x |
m <- dim(x)[3L] |
| 293 | 5x |
n_seq <- seq_len(n) |
| 294 | 5x |
m_seq <- seq_len(m) |
| 295 | 4x |
if (is.null(n_col)) n_col <- if (n > 4) 2 else 1 |
| 296 | 5x |
n_row <- ceiling(n / n_col) |
| 297 | ||
| 298 |
## Graphical parameters |
|
| 299 |
## Save and restore |
|
| 300 | 5x |
old_par <- graphics::par( |
| 301 | 5x |
mar = c(0, 5.1, 0, if (y_flip) 5.1 else 2.1), |
| 302 | 5x |
oma = c(6, 0, 5, 0), |
| 303 | 5x |
mfcol = c(n_row, n_col) |
| 304 |
) |
|
| 305 | 5x |
on.exit(graphics::par(old_par)) |
| 306 | ||
| 307 | 5x |
dots <- list(...) |
| 308 | 5x |
cex.lab <- make_par(dots, "cex.lab") |
| 309 | 5x |
col.lab <- make_par(dots, "col.lab") |
| 310 | 5x |
font.lab <- make_par(dots, "font.lab") |
| 311 | 5x |
cex.axis <- make_par(dots, "cex.axis") |
| 312 | 5x |
col.axis <- make_par(dots, "col.axis") |
| 313 | 5x |
font.axis <- make_par(dots, "font.axis") |
| 314 | 5x |
cex.main <- make_par(dots, "cex.main") |
| 315 | 5x |
font.main <- make_par(dots, "font.main") |
| 316 | 5x |
col.main <- make_par(dots, "col.main") |
| 317 | ||
| 318 | 5x |
years <- time(x, calendar = calendar) |
| 319 | 5x |
xlim <- xlim(x, calendar = calendar) |
| 320 | 5x |
ylim <- if (y_fixed) range(x, na.rm = TRUE) else NULL |
| 321 | 5x |
ylabs <- ylab %||% labels(x) %||% paste("Series", n_seq, sep = " ")
|
| 322 | 5x |
for (j in n_seq) {
|
| 323 |
## Plot |
|
| 324 | 30x |
xj <- x[, j, , drop = FALSE] |
| 325 | 30x |
.plot_single(xj, calendar = calendar, panel = panel, |
| 326 | 30x |
xlim = xlim, ylim = ylim, |
| 327 | 30x |
main = NULL, sub = NULL, ann = FALSE, axes = FALSE, |
| 328 | 30x |
frame.plot = frame.plot, |
| 329 | 30x |
panel.first = panel.first, panel.last = panel.last, ...) |
| 330 | ||
| 331 |
## Construct Axis |
|
| 332 | 30x |
xaxt <- make_par(dots, "xaxt") |
| 333 | 30x |
yaxt <- make_par(dots, "yaxt") |
| 334 | 30x |
do_x <- (j %% n_row == 0 || j == n) |
| 335 | 30x |
y_side <- if (j %% 2 || !y_flip) 2 else 4 |
| 336 | 30x |
if (axes) {
|
| 337 | 30x |
if (do_x && xaxt != "n") {
|
| 338 | 9x |
year_axis(side = 1, format = TRUE, calendar = calendar, |
| 339 | 9x |
xpd = NA, cex.axis = cex.axis, |
| 340 | 9x |
col.axis = col.axis, font.axis = font.axis) |
| 341 |
} |
|
| 342 | 30x |
if (yaxt != "n") {
|
| 343 | 30x |
graphics::axis(side = y_side, xpd = NA, cex.axis = cex.axis, |
| 344 | 30x |
col.axis = col.axis, font.axis = font.axis, las = 1) |
| 345 |
} |
|
| 346 |
} |
|
| 347 | ||
| 348 |
## Add annotation |
|
| 349 | 30x |
if (ann) {
|
| 350 | 30x |
if (do_x) {
|
| 351 | 9x |
cal_lab <- if (is.null(calendar)) expression(italic("rata die")) else format(calendar)
|
| 352 | 9x |
xlab <- xlab %||% cal_lab |
| 353 | 9x |
graphics::mtext(xlab, side = 1, line = 3, cex = cex.lab, col = col.lab, |
| 354 | 9x |
font = font.lab) |
| 355 |
} |
|
| 356 | 30x |
graphics::mtext(ylabs[[j]], side = y_side, line = 3, cex = cex.lab, |
| 357 | 30x |
col = col.lab, font = font.lab) |
| 358 |
} |
|
| 359 |
} |
|
| 360 | ||
| 361 |
## Add annotation |
|
| 362 | 5x |
if (ann) {
|
| 363 | 5x |
graphics::par(mfcol = c(1, 1)) |
| 364 | 5x |
graphics::mtext(main, side = 3, line = 3, cex = cex.main, font = font.main, |
| 365 | 5x |
col = col.main) |
| 366 |
} |
|
| 367 | ||
| 368 | 5x |
invisible(x) |
| 369 |
} |
|
| 370 | ||
| 371 |
#' Compute x Limits |
|
| 372 |
#' |
|
| 373 |
#' Computes x limits for a time series according to a given calendar. |
|
| 374 |
#' This ensures that the x axis is always in chronological order. |
|
| 375 |
#' @param x A [`TimeSeries-class`] object. |
|
| 376 |
#' @param calendar A [`TimeScale-class`] object. |
|
| 377 |
#' @param finite A [`logical`] scalar: should non-finite elements be omitted? |
|
| 378 |
#' @return A length-two [`numeric`] vector. |
|
| 379 |
#' @keywords internal |
|
| 380 |
#' @noRd |
|
| 381 |
xlim <- function(x, calendar, finite = FALSE) {
|
|
| 382 | 9x |
if (methods::is(x, "TimeSeries")) x <- time(x, calendar = NULL) |
| 383 | 4x |
if (methods::is(x, "TimeIntervals")) x <- c(start(x, calendar = NULL), end(x, calendar = NULL)) |
| 384 | 13x |
x <- range(x, finite = finite) |
| 385 | 2x |
if (is.null(calendar)) return(x) |
| 386 | 11x |
as_year(x, calendar = calendar) |
| 387 |
} |
|
| 388 | ||
| 389 |
# Image ======================================================================== |
|
| 390 |
#' @export |
|
| 391 |
#' @method image TimeSeries |
|
| 392 |
image.TimeSeries <- function(x, calendar = get_calendar(), k = 1, ...) {
|
|
| 393 |
## Save calendar for further use, e.g. year_axis() |
|
| 394 | 1x |
assign("last_calendar", value = function(...) calendar, envir = the)
|
| 395 | ||
| 396 |
## Get data |
|
| 397 | 1x |
n <- seq_len(NCOL(x)) |
| 398 | 1x |
samples <- labels(x) %||% paste0("S1", n)
|
| 399 | 1x |
years <- time(x, calendar = NULL) |
| 400 | ||
| 401 |
## Graphical parameters |
|
| 402 | 1x |
cex.axis <- list(...)$cex.axis %||% graphics::par("cex.axis")
|
| 403 | 1x |
col.axis <- list(...)$col.axis %||% graphics::par("col.axis")
|
| 404 | 1x |
font.axis <- list(...)$font.axis %||% graphics::par("font.axis")
|
| 405 | ||
| 406 |
## Save and restore |
|
| 407 | 1x |
mar <- graphics::par("mar")
|
| 408 | 1x |
mar[2] <- inch2line(samples, cex = cex.axis) + 0.5 |
| 409 | 1x |
old_par <- graphics::par(mar = mar) |
| 410 | 1x |
on.exit(graphics::par(old_par)) |
| 411 | ||
| 412 |
## Plot |
|
| 413 | 1x |
z <- x[, , k = k, drop = TRUE] |
| 414 | 1x |
graphics::image(x = years, y = n, z = z, |
| 415 | 1x |
xlab = format(calendar), ylab = "", |
| 416 | 1x |
xaxt = "n", yaxt = "n", ...) |
| 417 | ||
| 418 |
## Construct axes |
|
| 419 | 1x |
at <- as_fixed(graphics::axTicks(side = 1)) |
| 420 | 1x |
at <- pretty(at, calendar = calendar) |
| 421 | 1x |
lab <- format(at, label = FALSE, calendar = calendar) |
| 422 | 1x |
graphics::axis(side = 1, at = at, labels = lab) |
| 423 | 1x |
graphics::axis(side = 2, at = n, labels = samples, |
| 424 | 1x |
cex.axis = cex.axis, las = 1, |
| 425 | 1x |
col.axis = col.axis, font.axis = font.axis) |
| 426 | ||
| 427 | 1x |
invisible(x) |
| 428 |
} |
|
| 429 | ||
| 430 |
#' @export |
|
| 431 |
#' @rdname image |
|
| 432 |
#' @aliases image,TimeSeries-method |
|
| 433 |
setMethod("image", c(x = "TimeSeries"), image.TimeSeries)
|
| 1 |
# FORMAT |
|
| 2 | ||
| 3 |
# Format ======================================================================= |
|
| 4 |
#' @export |
|
| 5 |
#' @method format TimeIntervals |
|
| 6 |
format.TimeIntervals <- function(x, calendar = get_calendar(), ...) {
|
|
| 7 | 1x |
debut <- start(x, calendar = calendar) |
| 8 | 1x |
fin <- end(x, calendar = calendar) |
| 9 | ||
| 10 | 1x |
msg <- sprintf("[%g, %g]", debut, fin)
|
| 11 | 1x |
trimws(msg) |
| 12 |
} |
|
| 13 | ||
| 14 |
#' @export |
|
| 15 |
#' @rdname format |
|
| 16 |
setMethod("format", "TimeIntervals", format.TimeIntervals)
|
|
| 17 | ||
| 18 |
#' @export |
|
| 19 |
#' @method format TimeScale |
|
| 20 |
format.TimeScale <- function(x, ...) {
|
|
| 21 | 19x |
msg <- sprintf("%s %s", calendar_unit(x), calendar_label(x))
|
| 22 | 19x |
trimws(msg) |
| 23 |
} |
|
| 24 | ||
| 25 |
#' @export |
|
| 26 |
#' @rdname format |
|
| 27 |
setMethod("format", "TimeScale", format.TimeScale)
|
|
| 28 | ||
| 29 |
#' @export |
|
| 30 |
#' @method format RataDie |
|
| 31 |
format.RataDie <- function(x, prefix = c("a", "ka", "Ma", "Ga"), label = TRUE,
|
|
| 32 |
calendar = get_calendar(), ...) {
|
|
| 33 | ! |
if (is.null(calendar)) return(format(as.numeric(x))) |
| 34 | 22x |
y <- as_year(x, calendar = calendar) |
| 35 | ||
| 36 |
## Scale |
|
| 37 | 22x |
if (isTRUE(prefix)) {
|
| 38 | 12x |
power <- 10^floor(log10(abs(mean(y, na.rm = TRUE)))) |
| 39 | 12x |
if (prefix < 10^4) prefix <- "a" |
| 40 | 1x |
if (power >= 10^4 && power < 10^6) prefix <- "ka" |
| 41 | ! |
if (power >= 10^6 && power < 10^9) prefix <- "Ma" |
| 42 | ! |
if (power >= 10^9) prefix <- "Ga" |
| 43 |
} |
|
| 44 | 22x |
prefix <- match.arg(prefix, several.ok = FALSE) |
| 45 | 22x |
power <- switch (prefix, ka = 10^3, Ma = 10^6, Ga = 10^9, 1) |
| 46 | ||
| 47 | 22x |
prefix <- if (power > 1) sprintf(" %s", prefix) else ""
|
| 48 | 22x |
label <- if (isTRUE(label)) sprintf(" %s", calendar_label(calendar)) else ""
|
| 49 | 22x |
trimws(sprintf("%g%s%s", y / power, prefix, label))
|
| 50 |
} |
|
| 51 | ||
| 52 |
#' @export |
|
| 53 |
#' @rdname format |
|
| 54 |
setMethod("format", "RataDie", format.RataDie)
|
| 1 |
# JULINA CALENDAR |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Fixed from Julian ============================================================ |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname fixed |
|
| 8 |
#' @aliases fixed,numeric,missing,missing,JulianCalendar-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "fixed", |
|
| 11 |
signature = c(year = "numeric", month = "missing", day = "missing", calendar = "JulianCalendar"), |
|
| 12 |
definition = function(year, calendar, scale = 1) {
|
|
| 13 |
## Rescale to years (if not already) |
|
| 14 | 6x |
year <- year * scale |
| 15 | ||
| 16 | 6x |
rd <- fixed(year, 01, 01, calendar = calendar) |
| 17 | ||
| 18 | 5x |
is_leap <- which(is_julian_leap_year(year)) |
| 19 | 5x |
rd[is_leap] <- ceiling(rd[is_leap]) # WHY ??? |
| 20 | 5x |
rd |
| 21 |
} |
|
| 22 |
) |
|
| 23 | ||
| 24 |
#' @export |
|
| 25 |
#' @rdname fixed |
|
| 26 |
#' @aliases fixed,numeric,numeric,numeric,JulianCalendar-method |
|
| 27 |
setMethod( |
|
| 28 |
f = "fixed", |
|
| 29 |
signature = c(year = "numeric", month = "numeric", day = "numeric", calendar = "JulianCalendar"), |
|
| 30 |
definition = function(year, month, day, calendar) {
|
|
| 31 |
## Validation |
|
| 32 | 36x |
if (any(year == 0)) {
|
| 33 | 1x |
stop(tr_("There is no year zero in the Julian calendar."), call. = FALSE)
|
| 34 |
} |
|
| 35 | ||
| 36 |
## Correct for 28- or 29-day Feb |
|
| 37 | 35x |
correction <- rep(-2, length(year)) |
| 38 | 35x |
correction[which(is_julian_leap_year(year))] <- -1 |
| 39 | 35x |
correction[month <= 2] <- 0 |
| 40 | ||
| 41 |
## There is no year 0 on the Julian calendar |
|
| 42 | 35x |
year[year < 0] <- year[year < 0] + 1 |
| 43 | ||
| 44 | 35x |
rd <- calendar_fixed(calendar) - 1 + # Days before start of calendar |
| 45 | 35x |
365 * (year - 1) + # Ordinary days since epoch |
| 46 | 35x |
(year - 1) %/% 4 + # Leap days since epoch |
| 47 | 35x |
(367 * month - 362) %/% 12 + # Days in prior months this year assuming 30-day Feb |
| 48 | 35x |
correction + # Correct for 28- or 29-day Feb |
| 49 | 35x |
day # Days so far this month. |
| 50 | ||
| 51 |
## Fix infinite values |
|
| 52 | 35x |
rd[is.infinite(year)] <- year[is.infinite(year)] |
| 53 | ||
| 54 | 35x |
.RataDie(rd) |
| 55 |
} |
|
| 56 |
) |
|
| 57 | ||
| 58 |
# Julian from fixed ============================================================ |
|
| 59 |
#' @export |
|
| 60 |
#' @rdname as_year |
|
| 61 |
#' @aliases as_year,numeric,JulianCalendar-method |
|
| 62 |
setMethod( |
|
| 63 |
f = "as_year", |
|
| 64 |
signature = c(object = "numeric", calendar = "JulianCalendar"), |
|
| 65 |
definition = function(object, calendar, decimal = FALSE, ...) {
|
|
| 66 | 21x |
d0 <- object - calendar_fixed(calendar) |
| 67 | 21x |
year <- (4 * d0 + 1464) %/% 1461 |
| 68 | ||
| 69 |
## There is no year 0 on the Julian calendar |
|
| 70 | 21x |
year[year <= 0] <- year[year <= 0] - 1 |
| 71 | ||
| 72 | 21x |
if (isTRUE(decimal)) {
|
| 73 |
## Year length in days |
|
| 74 | 8x |
start <- fixed(year, 01, 01, calendar = calendar) |
| 75 | 8x |
end <- fixed(year, 12, 31, calendar = calendar) |
| 76 | 8x |
total <- end - start + 1 |
| 77 | ||
| 78 |
## Elapsed time |
|
| 79 | 8x |
sofar <- object - start |
| 80 | ||
| 81 | 8x |
year <- year + sofar / total |
| 82 |
} |
|
| 83 | ||
| 84 |
## Fix infinite values |
|
| 85 | 21x |
year[is.infinite(object)] <- object[is.infinite(object)] |
| 86 | ||
| 87 | 21x |
unclass(year) |
| 88 |
} |
|
| 89 |
) |
|
| 90 | ||
| 91 |
#' @export |
|
| 92 |
#' @rdname as_date |
|
| 93 |
#' @aliases as_date,numeric,JulianCalendar-method |
|
| 94 |
setMethod( |
|
| 95 |
f = "as_date", |
|
| 96 |
signature = c(object = "numeric", calendar = "JulianCalendar"), |
|
| 97 |
definition = function(object, calendar) {
|
|
| 98 | 3x |
year <- as_year(object, calendar = calendar, decimal = FALSE) |
| 99 | 3x |
prior_days <- object - fixed(year, 01, 01, calendar = calendar) |
| 100 | ||
| 101 | 3x |
correction <- rep(2, length(object)) |
| 102 | 3x |
correction[object < fixed(year, 03, 01, calendar = calendar)] <- 0 |
| 103 | 3x |
correction[is_julian_leap_year(year)] <- 1 |
| 104 | ||
| 105 | 3x |
month <- (12 * (prior_days + correction) + 373) %/% 367 |
| 106 | 3x |
day <- object - fixed(year, month, 01, calendar = calendar) + 1 |
| 107 | ||
| 108 | 3x |
data.frame( |
| 109 | 3x |
year = unclass(year), |
| 110 | 3x |
month = unclass(month), |
| 111 | 3x |
day = unclass(day) |
| 112 |
) |
|
| 113 |
} |
|
| 114 |
) |
|
| 115 | ||
| 116 |
# Era ========================================================================== |
|
| 117 |
#' @export |
|
| 118 |
#' @rdname fixed_julian |
|
| 119 |
fixed_from_julian <- function(year, month, day) {
|
|
| 120 | ! |
if (missing(month) || missing(day)) fixed(year, calendar = J()) |
| 121 | 1x |
else fixed(year, month, day, calendar = J()) |
| 122 |
} |
|
| 123 | ||
| 124 |
#' @export |
|
| 125 |
#' @rdname fixed_julian |
|
| 126 |
fixed_to_julian <- function(object) {
|
|
| 127 | 1x |
as_year(object, calendar = J()) |
| 128 |
} |
| 1 |
# TEMPORAL RELATIONS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Precede ====================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname relations |
|
| 8 |
#' @aliases precedes,TimeIntervals-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "precedes", |
|
| 11 |
signature = c(x = "TimeIntervals"), |
|
| 12 |
definition = function(x, ...) {
|
|
| 13 | 1x |
.relation( |
| 14 | 1x |
x = start(x, calendar = NULL), |
| 15 | 1x |
y = end(x, calendar = NULL), |
| 16 | 1x |
f = .precedes, |
| 17 | 1x |
labels = labels(x), |
| 18 |
... |
|
| 19 |
) |
|
| 20 |
} |
|
| 21 |
) |
|
| 22 | ||
| 23 |
.precedes <- function(xmin, xmax, ymin, ymax) {
|
|
| 24 | 1x |
xmin < ymin & xmax < ymin |
| 25 |
} |
|
| 26 | ||
| 27 |
#' @export |
|
| 28 |
#' @rdname relations |
|
| 29 |
#' @aliases preceded_by,TimeIntervals,missing-method |
|
| 30 |
setMethod( |
|
| 31 |
f = "preceded_by", |
|
| 32 |
signature = c(x = "TimeIntervals"), |
|
| 33 |
definition = function(x, ...) {
|
|
| 34 | 1x |
.relation( |
| 35 | 1x |
x = start(x, calendar = NULL), |
| 36 | 1x |
y = end(x, calendar = NULL), |
| 37 | 1x |
f = .preceded_by, |
| 38 | 1x |
labels = labels(x), |
| 39 |
... |
|
| 40 |
) |
|
| 41 |
} |
|
| 42 |
) |
|
| 43 | ||
| 44 |
.preceded_by <- function(xmin, xmax, ymin, ymax) {
|
|
| 45 | 1x |
xmin > ymax |
| 46 |
} |
|
| 47 | ||
| 48 |
# Meet ========================================================================= |
|
| 49 |
#' @export |
|
| 50 |
#' @rdname relations |
|
| 51 |
#' @aliases meets,TimeIntervals-method |
|
| 52 |
setMethod( |
|
| 53 |
f = "meets", |
|
| 54 |
signature = c(x = "TimeIntervals"), |
|
| 55 |
definition = function(x, ...) {
|
|
| 56 | ! |
.relation( |
| 57 | ! |
x = start(x, calendar = NULL), |
| 58 | ! |
y = end(x, calendar = NULL), |
| 59 | ! |
f = .meets, |
| 60 | ! |
labels = labels(x), |
| 61 |
... |
|
| 62 |
) |
|
| 63 |
} |
|
| 64 |
) |
|
| 65 | ||
| 66 |
.meets <- function(xmin, xmax, ymin, ymax) {
|
|
| 67 | ! |
xmin < ymin & xmax == ymin |
| 68 |
} |
|
| 69 | ||
| 70 |
#' @export |
|
| 71 |
#' @rdname relations |
|
| 72 |
#' @aliases met_by,TimeIntervals,missing-method |
|
| 73 |
setMethod( |
|
| 74 |
f = "met_by", |
|
| 75 |
signature = c(x = "TimeIntervals"), |
|
| 76 |
definition = function(x, ...) {
|
|
| 77 | 1x |
.relation( |
| 78 | 1x |
x = start(x, calendar = NULL), |
| 79 | 1x |
y = end(x, calendar = NULL), |
| 80 | 1x |
f = .met_by, |
| 81 | 1x |
labels = labels(x), |
| 82 |
... |
|
| 83 |
) |
|
| 84 |
} |
|
| 85 |
) |
|
| 86 | ||
| 87 |
.met_by <- function(xmin, xmax, ymin, ymax) {
|
|
| 88 | 1x |
xmin == ymax |
| 89 |
} |
|
| 90 | ||
| 91 |
# Overlap ====================================================================== |
|
| 92 |
#' @export |
|
| 93 |
#' @rdname relations |
|
| 94 |
#' @aliases overlaps,TimeIntervals-method |
|
| 95 |
setMethod( |
|
| 96 |
f = "overlaps", |
|
| 97 |
signature = c(x = "TimeIntervals"), |
|
| 98 |
definition = function(x, ...) {
|
|
| 99 | 2x |
.relation( |
| 100 | 2x |
x = start(x, calendar = NULL), |
| 101 | 2x |
y = end(x, calendar = NULL), |
| 102 | 2x |
f = .overlaps, |
| 103 | 2x |
labels = labels(x), |
| 104 |
... |
|
| 105 |
) |
|
| 106 |
} |
|
| 107 |
) |
|
| 108 | ||
| 109 |
.overlaps <- function(xmin, xmax, ymin, ymax) {
|
|
| 110 | 2x |
xmin < ymin & xmax > ymin & xmax < ymax |
| 111 |
} |
|
| 112 | ||
| 113 |
#' @export |
|
| 114 |
#' @rdname relations |
|
| 115 |
#' @aliases overlapped_by,TimeIntervals,missing-method |
|
| 116 |
setMethod( |
|
| 117 |
f = "overlapped_by", |
|
| 118 |
signature = c(x = "TimeIntervals"), |
|
| 119 |
definition = function(x, ...) {
|
|
| 120 | ! |
.relation( |
| 121 | ! |
x = start(x, calendar = NULL), |
| 122 | ! |
y = end(x, calendar = NULL), |
| 123 | ! |
f = .overlapped_by, |
| 124 | ! |
labels = labels(x), |
| 125 |
... |
|
| 126 |
) |
|
| 127 |
} |
|
| 128 |
) |
|
| 129 | ||
| 130 |
.overlapped_by <- function(xmin, xmax, ymin, ymax) {
|
|
| 131 | ! |
xmin > ymin & xmin < ymax & xmax > ymax |
| 132 |
} |
|
| 133 | ||
| 134 |
# Finish ======================================================================= |
|
| 135 |
#' @export |
|
| 136 |
#' @rdname relations |
|
| 137 |
#' @aliases finishes,TimeIntervals,missing-method |
|
| 138 |
setMethod( |
|
| 139 |
f = "finishes", |
|
| 140 |
signature = c(x = "TimeIntervals"), |
|
| 141 |
definition = function(x, ...) {
|
|
| 142 | 1x |
.relation( |
| 143 | 1x |
x = start(x, calendar = NULL), |
| 144 | 1x |
y = end(x, calendar = NULL), |
| 145 | 1x |
f = .finishes, |
| 146 | 1x |
labels = labels(x), |
| 147 |
... |
|
| 148 |
) |
|
| 149 |
} |
|
| 150 |
) |
|
| 151 | ||
| 152 |
.finishes <- function(xmin, xmax, ymin, ymax) {
|
|
| 153 | 1x |
xmin > ymin & xmax == ymax |
| 154 |
} |
|
| 155 | ||
| 156 |
#' @export |
|
| 157 |
#' @rdname relations |
|
| 158 |
#' @aliases finished_by,TimeIntervals-method |
|
| 159 |
setMethod( |
|
| 160 |
f = "finished_by", |
|
| 161 |
signature = c(x = "TimeIntervals"), |
|
| 162 |
definition = function(x, ...) {
|
|
| 163 | ! |
.relation( |
| 164 | ! |
x = start(x, calendar = NULL), |
| 165 | ! |
y = end(x, calendar = NULL), |
| 166 | ! |
f = .finished_by, |
| 167 | ! |
labels = labels(x), |
| 168 |
... |
|
| 169 |
) |
|
| 170 |
} |
|
| 171 |
) |
|
| 172 | ||
| 173 |
.finished_by <- function(xmin, xmax, ymin, ymax) {
|
|
| 174 | ! |
xmin < ymin & xmax == ymax |
| 175 |
} |
|
| 176 | ||
| 177 |
# Contain ====================================================================== |
|
| 178 |
#' @export |
|
| 179 |
#' @rdname relations |
|
| 180 |
#' @aliases contains,TimeIntervals-method |
|
| 181 |
setMethod( |
|
| 182 |
f = "contains", |
|
| 183 |
signature = c(x = "TimeIntervals"), |
|
| 184 |
definition = function(x, ...) {
|
|
| 185 | 2x |
.relation( |
| 186 | 2x |
x = start(x, calendar = NULL), |
| 187 | 2x |
y = end(x, calendar = NULL), |
| 188 | 2x |
f = .contains, |
| 189 | 2x |
labels = labels(x), |
| 190 |
... |
|
| 191 |
) |
|
| 192 |
} |
|
| 193 |
) |
|
| 194 | ||
| 195 |
.contains <- function(xmin, xmax, ymin, ymax) {
|
|
| 196 | 2x |
xmin < ymin & xmax > ymax |
| 197 |
} |
|
| 198 | ||
| 199 |
#' @export |
|
| 200 |
#' @rdname relations |
|
| 201 |
#' @aliases during,TimeIntervals,missing-method |
|
| 202 |
setMethod( |
|
| 203 |
f = "during", |
|
| 204 |
signature = c(x = "TimeIntervals"), |
|
| 205 |
definition = function(x, ...) {
|
|
| 206 | ! |
.relation( |
| 207 | ! |
x = start(x, calendar = NULL), |
| 208 | ! |
y = end(x, calendar = NULL), |
| 209 | ! |
f = .during, |
| 210 | ! |
labels = labels(x), |
| 211 |
... |
|
| 212 |
) |
|
| 213 |
} |
|
| 214 |
) |
|
| 215 | ||
| 216 |
.during <- function(xmin, xmax, ymin, ymax) {
|
|
| 217 | ! |
xmin > ymin & xmax < ymax |
| 218 |
} |
|
| 219 | ||
| 220 |
# Start ======================================================================== |
|
| 221 |
#' @export |
|
| 222 |
#' @rdname relations |
|
| 223 |
#' @aliases starts,TimeIntervals,missing-method |
|
| 224 |
setMethod( |
|
| 225 |
f = "starts", |
|
| 226 |
signature = c(x = "TimeIntervals"), |
|
| 227 |
definition = function(x, ...) {
|
|
| 228 | 1x |
.relation( |
| 229 | 1x |
x = start(x, calendar = NULL), |
| 230 | 1x |
y = end(x, calendar = NULL), |
| 231 | 1x |
f = .starts, |
| 232 | 1x |
labels = labels(x), |
| 233 |
... |
|
| 234 |
) |
|
| 235 |
} |
|
| 236 |
) |
|
| 237 | ||
| 238 |
.starts <- function(xmin, xmax, ymin, ymax) {
|
|
| 239 | 1x |
xmin == ymin & xmax < ymax |
| 240 |
} |
|
| 241 | ||
| 242 |
#' @export |
|
| 243 |
#' @rdname relations |
|
| 244 |
#' @aliases started_by,TimeIntervals,missing-method |
|
| 245 |
setMethod( |
|
| 246 |
f = "started_by", |
|
| 247 |
signature = c(x = "TimeIntervals"), |
|
| 248 |
definition = function(x, ...) {
|
|
| 249 | ! |
.relation( |
| 250 | ! |
x = start(x, calendar = NULL), |
| 251 | ! |
y = end(x, calendar = NULL), |
| 252 | ! |
f = .started_by, |
| 253 | ! |
labels = labels(x), |
| 254 |
... |
|
| 255 |
) |
|
| 256 |
} |
|
| 257 |
) |
|
| 258 | ||
| 259 |
.started_by <- function(xmin, xmax, ymin, ymax) {
|
|
| 260 | ! |
xmin == ymin & xmax > ymax |
| 261 |
} |
|
| 262 | ||
| 263 |
# Equal ======================================================================== |
|
| 264 |
#' @export |
|
| 265 |
#' @rdname relations |
|
| 266 |
#' @aliases equals,TimeIntervals,missing-method |
|
| 267 |
setMethod( |
|
| 268 |
f = "equals", |
|
| 269 |
signature = c(x = "TimeIntervals"), |
|
| 270 |
definition = function(x, ...) {
|
|
| 271 | 1x |
.relation( |
| 272 | 1x |
x = start(x, calendar = NULL), |
| 273 | 1x |
y = end(x, calendar = NULL), |
| 274 | 1x |
f = .equals, |
| 275 | 1x |
labels = labels(x), |
| 276 |
... |
|
| 277 |
) |
|
| 278 |
} |
|
| 279 |
) |
|
| 280 | ||
| 281 |
.equals <- function(xmin, xmax, ymin, ymax) {
|
|
| 282 | 1x |
xmin == ymin & xmax == ymax |
| 283 |
} |
|
| 284 | ||
| 285 |
# Helpers ====================================================================== |
|
| 286 |
.relation <- function(x, y, f, labels = NULL, use_names = TRUE) {
|
|
| 287 | 10x |
n <- length(x) |
| 288 | 10x |
arkhe::assert_function(f) |
| 289 | 10x |
arkhe::assert_length(y, n) |
| 290 | 10x |
assert_ordered(x, y) |
| 291 | ||
| 292 | 10x |
labels <- labels %||% names(x) %||% names(y) |
| 293 | ! |
if (!isTRUE(use_names)) labels <- seq_along(labels) |
| 294 | ||
| 295 | 10x |
el <- seq_len(n) |
| 296 | 10x |
comb <- cbind( |
| 297 | 10x |
utils::combn(el, m = 2, simplify = TRUE), |
| 298 | 10x |
utils::combn(rev(el), m = 2, simplify = TRUE) |
| 299 |
) |
|
| 300 | 10x |
xmin <- x[comb[1, ]] |
| 301 | 10x |
xmax <- y[comb[1, ]] |
| 302 | 10x |
ymin <- x[comb[2, ]] |
| 303 | 10x |
ymax <- y[comb[2, ]] |
| 304 | ||
| 305 | 10x |
mtx <- matrix( |
| 306 | 10x |
data = c(labels[comb[1, ]], labels[comb[2, ]]), |
| 307 | 10x |
ncol = 2 |
| 308 |
) |
|
| 309 | ||
| 310 | 10x |
rel <- f(xmin, xmax, ymin, ymax) |
| 311 | 10x |
mtx <- mtx[rel, , drop = FALSE] |
| 312 | 10x |
mtx <- mtx[order(mtx[, 1], mtx[, 2]), ] |
| 313 | 10x |
mtx |
| 314 |
} |
| 1 |
# SHOW |
|
| 2 | ||
| 3 |
# Show ========================================================================= |
|
| 4 |
setMethod( |
|
| 5 |
f = "show", |
|
| 6 |
signature = "TimeScale", |
|
| 7 |
definition = function(object) {
|
|
| 8 | ! |
cal_name <- calendar_name(object) |
| 9 | ! |
cal_label <- calendar_label(object) |
| 10 | ! |
has_name <- length(cal_name) == 1 && cal_name != "" |
| 11 | ! |
has_label <- length(cal_label) == 1 && cal_label != "" |
| 12 | ||
| 13 | ! |
era <- "" |
| 14 | ! |
if (has_name && has_label) {
|
| 15 | ! |
era <- sprintf("%s (%s): ", cal_name, cal_label)
|
| 16 |
} |
|
| 17 | ||
| 18 | ! |
if (calendar_direction(object) > 0) {
|
| 19 | ! |
msg <- tr_("%s%s counted forwards from %g")
|
| 20 |
} else {
|
|
| 21 | ! |
msg <- tr_("%s%s counted backwards from %g")
|
| 22 |
} |
|
| 23 | ! |
msg <- sprintf(msg, era, calendar_unit(object), calendar_epoch(object)) |
| 24 | ! |
cat(trimws(msg), sep = "\n") |
| 25 |
} |
|
| 26 |
) |
|
| 27 | ||
| 28 |
setMethod( |
|
| 29 |
f = "show", |
|
| 30 |
signature = "RataDie", |
|
| 31 |
definition = function(object) {
|
|
| 32 | ! |
msg <- tr_("Rata die: number of days since 01-01-01 (Gregorian)")
|
| 33 | ! |
cat(msg, sep = "\n") |
| 34 | ! |
methods::callGeneric(object@.Data) |
| 35 |
} |
|
| 36 |
) |
|
| 37 | ||
| 38 |
setMethod( |
|
| 39 |
f = "show", |
|
| 40 |
signature = "TimeSeries", |
|
| 41 |
definition = function(object) {
|
|
| 42 | ! |
n <- dim(object) |
| 43 | ! |
k <- n[[2]] + n[[3]] - 1 |
| 44 | ! |
start <- format(as_fixed(start(object))) |
| 45 | ! |
end <- format(as_fixed(end(object))) |
| 46 | ! |
msg <- ngettext(k, "%d x %d x %d time series observed between %s and %s", |
| 47 | ! |
"%d x %d x %d time series observed between %s and %s") |
| 48 | ! |
msg <- sprintf(msg, n[[1L]], n[[2L]], n[[3L]], start, end) |
| 49 | ! |
cat(msg, sep = "\n") |
| 50 |
} |
|
| 51 |
) |
|
| 52 | ||
| 53 |
setMethod( |
|
| 54 |
f = "show", |
|
| 55 |
signature = "TimeIntervals", |
|
| 56 |
definition = function(object) {
|
|
| 57 | ! |
n <- length(object) |
| 58 | ! |
start <- format(as_fixed(min(start(object)))) |
| 59 | ! |
end <- format(as_fixed(max(end(object)))) |
| 60 | ! |
msg <- ngettext(n, "%d time interval observed between %s and %s", |
| 61 | ! |
"%d time intervals observed between %s and %s") |
| 62 | ! |
msg <- sprintf(msg, n, start, end) |
| 63 | ! |
cat(msg, sep = "\n") |
| 64 |
} |
|
| 65 |
) |
| 1 |
# TIME SERIES |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# array ======================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname series |
|
| 8 |
#' @aliases series,array,RataDie,missing-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "series", |
|
| 11 |
signature = c(object = "array", time = "RataDie", calendar = "missing"), |
|
| 12 |
definition = function(object, time, names = NULL) {
|
|
| 13 |
## Validation |
|
| 14 | 19x |
arkhe::assert_length(time, NROW(object)) |
| 15 | ||
| 16 |
## Set the names of the series |
|
| 17 | 19x |
n <- dim(object)[2L] |
| 18 | 19x |
if (!is.null(names)) {
|
| 19 | 2x |
arkhe::assert_length(names, n) |
| 20 | 2x |
dimnames(object)[[2L]] <- names |
| 21 |
} |
|
| 22 | 19x |
if (is.null(dimnames(object)[[2L]])) {
|
| 23 | 14x |
dimnames(object)[[2L]] <- paste0("S", seq_len(n))
|
| 24 |
} |
|
| 25 | ||
| 26 |
## Chronological order |
|
| 27 | 19x |
i <- order(time, decreasing = FALSE) |
| 28 | 19x |
time <- time[i] |
| 29 | 19x |
object <- object[i, , , drop = FALSE] |
| 30 | ||
| 31 | 19x |
.TimeSeries(object, .Time = time) |
| 32 |
} |
|
| 33 |
) |
|
| 34 | ||
| 35 |
#' @export |
|
| 36 |
#' @rdname series |
|
| 37 |
#' @aliases series,array,numeric,TimeScale-method |
|
| 38 |
setMethod( |
|
| 39 |
f = "series", |
|
| 40 |
signature = c(object = "array", time = "numeric", calendar = "TimeScale"), |
|
| 41 |
definition = function(object, time, calendar, scale = 1, names = NULL) {
|
|
| 42 | 10x |
if (methods::is(time, "RataDie")) {
|
| 43 | 1x |
msg <- tr_("%s is already expressed in rata die: %s is ignored.")
|
| 44 | 1x |
warning(sprintf(msg, sQuote("time"), sQuote("calendar")), call. = FALSE)
|
| 45 |
} else {
|
|
| 46 | 9x |
time <- fixed(time, calendar = calendar, scale = scale) |
| 47 |
} |
|
| 48 | 10x |
methods::callGeneric(object = object, time = time, names = names) |
| 49 |
} |
|
| 50 |
) |
|
| 51 | ||
| 52 |
# matrix ======================================================================= |
|
| 53 |
#' @export |
|
| 54 |
#' @rdname series |
|
| 55 |
#' @aliases series,matrix,numeric,TimeScale-method |
|
| 56 |
setMethod( |
|
| 57 |
f = "series", |
|
| 58 |
signature = c(object = "matrix", time = "numeric", calendar = "TimeScale"), |
|
| 59 |
definition = function(object, time, calendar, scale = 1, names = NULL) {
|
|
| 60 | 9x |
x <- array(object, dim = c(dim(object), 1)) |
| 61 | 9x |
rownames(x) <- rownames(object) |
| 62 | 9x |
colnames(x) <- colnames(object) |
| 63 | 9x |
methods::callGeneric(object = x, time = time, calendar = calendar, |
| 64 | 9x |
scale = scale, names = names) |
| 65 |
} |
|
| 66 |
) |
|
| 67 | ||
| 68 |
#' @export |
|
| 69 |
#' @rdname series |
|
| 70 |
#' @aliases series,matrix,RataDie,missing-method |
|
| 71 |
setMethod( |
|
| 72 |
f = "series", |
|
| 73 |
signature = c(object = "matrix", time = "RataDie", calendar = "missing"), |
|
| 74 |
definition = function(object, time, names = NULL) {
|
|
| 75 | 4x |
x <- array(object, dim = c(dim(object), 1)) |
| 76 | 4x |
colnames(x) <- colnames(object) |
| 77 | 4x |
methods::callGeneric(object = x, time = time, names = names) |
| 78 |
} |
|
| 79 |
) |
|
| 80 | ||
| 81 |
# numeric ====================================================================== |
|
| 82 |
#' @export |
|
| 83 |
#' @rdname series |
|
| 84 |
#' @aliases series,numeric,numeric,TimeScale-method |
|
| 85 |
setMethod( |
|
| 86 |
f = "series", |
|
| 87 |
signature = c(object = "numeric", time = "numeric", calendar = "TimeScale"), |
|
| 88 |
definition = function(object, time, calendar, scale = 1, names = NULL) {
|
|
| 89 | 1x |
object <- array(data = object, dim = c(length(object), 1, 1)) |
| 90 | 1x |
methods::callGeneric(object = object, time = time, calendar = calendar, |
| 91 | 1x |
scale = scale, names = names) |
| 92 |
} |
|
| 93 |
) |
|
| 94 | ||
| 95 |
#' @export |
|
| 96 |
#' @rdname series |
|
| 97 |
#' @aliases series,numeric,RataDie,missing-method |
|
| 98 |
setMethod( |
|
| 99 |
f = "series", |
|
| 100 |
signature = c(object = "numeric", time = "RataDie", calendar = "missing"), |
|
| 101 |
definition = function(object, time, names = NULL) {
|
|
| 102 | 5x |
object <- array(data = object, dim = c(length(object), 1, 1)) |
| 103 | 5x |
methods::callGeneric(object = object, time = time, names = names) |
| 104 |
} |
|
| 105 |
) |
|
| 106 | ||
| 107 |
# data.frame =================================================================== |
|
| 108 |
#' @export |
|
| 109 |
#' @rdname series |
|
| 110 |
#' @aliases series,data.frame,numeric,TimeScale-method |
|
| 111 |
setMethod( |
|
| 112 |
f = "series", |
|
| 113 |
signature = c(object = "data.frame", time = "numeric", calendar = "TimeScale"), |
|
| 114 |
definition = function(object, time, calendar, scale = 1, names = NULL) {
|
|
| 115 | 1x |
object <- data.matrix(object) |
| 116 | 1x |
methods::callGeneric(object = object, time = time, calendar = calendar, |
| 117 | 1x |
scale = scale, names = names) |
| 118 |
} |
|
| 119 |
) |
|
| 120 | ||
| 121 |
#' @export |
|
| 122 |
#' @rdname series |
|
| 123 |
#' @aliases series,data.frame,RataDie,missing-method |
|
| 124 |
setMethod( |
|
| 125 |
f = "series", |
|
| 126 |
signature = c(object = "data.frame", time = "RataDie", calendar = "missing"), |
|
| 127 |
definition = function(object, time, names = NULL) {
|
|
| 128 | 1x |
object <- data.matrix(object) |
| 129 | 1x |
methods::callGeneric(object = object, time = time, names = names) |
| 130 |
} |
|
| 131 |
) |
| 1 |
# MUTATORS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# Getters ====================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @method labels TimeSeries |
|
| 8 | 6x |
labels.TimeSeries <- function(object, ...) colnames(object) |
| 9 | ||
| 10 |
#' @rdname labels |
|
| 11 |
#' @aliases labels,TimeSeries-method |
|
| 12 |
setMethod("labels", "TimeSeries", labels.TimeSeries)
|
|
| 13 | ||
| 14 |
#' @export |
|
| 15 |
#' @method labels TimeIntervals |
|
| 16 | 24x |
labels.TimeIntervals <- function(object, ...) object@.Id |
| 17 | ||
| 18 |
#' @rdname labels |
|
| 19 |
#' @aliases labels,TimeIntervals-method |
|
| 20 |
setMethod("labels", "TimeIntervals", labels.TimeIntervals)
|
|
| 21 | ||
| 22 |
#' @export |
|
| 23 |
#' @method names TimeIntervals |
|
| 24 | 2x |
names.TimeIntervals <- function(x) x@.Id |
| 25 | ||
| 26 |
#' @rdname names |
|
| 27 |
#' @aliases names,TimeIntervals-method |
|
| 28 |
setMethod("names", "TimeIntervals", names.TimeIntervals)
|
|
| 29 | ||
| 30 |
#' @export |
|
| 31 |
#' @method length TimeIntervals |
|
| 32 | 6x |
length.TimeIntervals <- function(x) length(x@.Id) |
| 33 | ||
| 34 |
#' @rdname length |
|
| 35 |
#' @aliases length,TimeIntervals-method |
|
| 36 |
setMethod("length", "TimeIntervals", length.TimeIntervals)
|
|
| 37 | ||
| 38 |
# Setters ====================================================================== |
|
| 39 |
#' @export |
|
| 40 |
#' @method `names<-` TimeIntervals |
|
| 41 |
`names<-.TimeIntervals` <- function(x, value) {
|
|
| 42 | 1x |
if (is.null(value)) value <- paste0("I", seq_len(length(x)))
|
| 43 | 4x |
x@.Id <- as.character(value) |
| 44 | 4x |
validObject(x) |
| 45 | 3x |
x |
| 46 |
} |
|
| 47 | ||
| 48 |
#' @rdname names |
|
| 49 |
#' @aliases names<-,TimeIntervals-method |
|
| 50 |
setMethod("names<-", "TimeIntervals", `names<-.TimeIntervals`)
|
| 1 |
# TIME INTERVALS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname intervals |
|
| 7 |
#' @aliases intervals,RataDie,RataDie,missing-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "intervals", |
|
| 10 |
signature = c(start = "RataDie", end = "RataDie", calendar = "missing"), |
|
| 11 |
definition = function(start, end, names = NULL) {
|
|
| 12 | 9x |
n <- length(start) |
| 13 | 9x |
arkhe::assert_length(end, n) |
| 14 | ||
| 15 |
## Set the names |
|
| 16 | 9x |
if (is.null(names)) {
|
| 17 | 7x |
names <- paste0("I", seq_len(n))
|
| 18 |
} else {
|
|
| 19 | 2x |
names <- as.character(names) |
| 20 |
} |
|
| 21 | 9x |
arkhe::assert_length(names, n) |
| 22 | ||
| 23 | 9x |
.TimeIntervals(.Id = names, .Start = start, .End = end) |
| 24 |
} |
|
| 25 |
) |
|
| 26 | ||
| 27 |
#' @export |
|
| 28 |
#' @rdname intervals |
|
| 29 |
#' @aliases intervals,numeric,numeric,TimeScale-method |
|
| 30 |
setMethod( |
|
| 31 |
f = "intervals", |
|
| 32 |
signature = c(start = "numeric", end = "numeric", calendar = "TimeScale"), |
|
| 33 |
definition = function(start, end, calendar, scale = 1, names = NULL) {
|
|
| 34 |
## Start |
|
| 35 | 8x |
if (methods::is(start, "RataDie")) {
|
| 36 | 1x |
msg <- "%s is already expressed in rata die: %s is ignored." |
| 37 | 1x |
warning(sprintf(msg, sQuote("start"), sQuote("calendar")), call. = FALSE)
|
| 38 |
} else {
|
|
| 39 | 7x |
start <- fixed(start, calendar = calendar, scale = scale) |
| 40 |
} |
|
| 41 | ||
| 42 |
## End |
|
| 43 | 8x |
if (methods::is(end, "RataDie")) {
|
| 44 | 1x |
msg <- tr_("%s is already expressed in rata die: %s is ignored.")
|
| 45 | 1x |
warning(sprintf(msg, sQuote("end"), sQuote("calendar")), call. = FALSE)
|
| 46 |
} else {
|
|
| 47 | 7x |
end <- fixed(end, calendar = calendar, scale = scale) |
| 48 |
} |
|
| 49 | ||
| 50 | 8x |
names <- names %||% names(start) %||% names(end) |
| 51 | 8x |
methods::callGeneric(start = start, end = end, names = names) |
| 52 |
} |
|
| 53 |
) |
| 1 |
# OVERLAP |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname overlap |
|
| 7 |
#' @aliases overlap,TimeIntervals-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "overlap", |
|
| 10 |
signature = "TimeIntervals", |
|
| 11 |
definition = function(x, calendar = NULL, aggregate = TRUE) {
|
|
| 12 | 4x |
labels <- labels(x) |
| 13 | 4x |
lower <- start(x, calendar = calendar) * calendar_direction(calendar) |
| 14 | 4x |
upper <- end(x, calendar = calendar) * calendar_direction(calendar) |
| 15 | 4x |
m <- length(x) |
| 16 | ||
| 17 |
## Compute overlap |
|
| 18 | 4x |
index <- utils::combn( |
| 19 | 4x |
x = seq_len(m), |
| 20 | 4x |
m = 2, |
| 21 | 4x |
FUN = function(x) max(0, min(upper[x]) - max(lower[x]) + 1) |
| 22 |
) |
|
| 23 | ||
| 24 |
## Matrix of results |
|
| 25 | 4x |
mtx <- matrix(data = upper - lower, nrow = m, ncol = m, dimnames = list(labels, labels)) |
| 26 | 4x |
mtx[lower.tri(mtx, diag = FALSE)] <- index |
| 27 | 4x |
mtx <- t(mtx) |
| 28 | 4x |
mtx[lower.tri(mtx, diag = FALSE)] <- index |
| 29 | ||
| 30 |
## Aggregate in case of disjoint intervals referring to the same event |
|
| 31 | 4x |
if (isTRUE(aggregate)) {
|
| 32 | 4x |
mtx <- t(rowsum(mtx, group = labels, reorder = FALSE)) |
| 33 | 4x |
mtx <- rowsum(mtx, group = labels, reorder = FALSE) |
| 34 |
} |
|
| 35 | ||
| 36 | 4x |
mtx |
| 37 |
} |
|
| 38 |
) |
| 1 |
# TIME |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @method start TimeSeries |
|
| 7 |
start.TimeSeries <- function(x, calendar = NULL, ...) {
|
|
| 8 | 11x |
z <- min(x@.Time) |
| 9 | 7x |
if (is.null(calendar)) return(z) |
| 10 | 4x |
as_year(z, calendar = calendar, decimal = TRUE) |
| 11 |
} |
|
| 12 | ||
| 13 |
#' @export |
|
| 14 |
#' @rdname start |
|
| 15 |
#' @aliases start,TimeSeries-method |
|
| 16 |
setMethod("start", "TimeSeries", start.TimeSeries)
|
|
| 17 | ||
| 18 |
#' @export |
|
| 19 |
#' @method start TimeIntervals |
|
| 20 |
start.TimeIntervals <- function(x, calendar = NULL, ...) {
|
|
| 21 | 32x |
z <- x@.Start |
| 22 | 19x |
if (is.null(calendar)) return(z) |
| 23 | 13x |
as_year(z, calendar = calendar, decimal = TRUE) |
| 24 |
} |
|
| 25 | ||
| 26 |
#' @export |
|
| 27 |
#' @rdname start |
|
| 28 |
#' @aliases start,TimeIntervals-method |
|
| 29 |
setMethod("start", "TimeIntervals", start.TimeIntervals)
|
|
| 30 | ||
| 31 |
#' @export |
|
| 32 |
#' @method end TimeSeries |
|
| 33 |
end.TimeSeries <- function(x, calendar = NULL, ...) {
|
|
| 34 | 11x |
z <- max(x@.Time) |
| 35 | 7x |
if (is.null(calendar)) return(z) |
| 36 | 4x |
as_year(z, calendar = calendar, decimal = TRUE) |
| 37 |
} |
|
| 38 | ||
| 39 |
#' @export |
|
| 40 |
#' @rdname start |
|
| 41 |
#' @aliases end,TimeSeries-method |
|
| 42 |
setMethod("end", "TimeSeries", end.TimeSeries)
|
|
| 43 | ||
| 44 |
#' @export |
|
| 45 |
#' @method end TimeIntervals |
|
| 46 |
end.TimeIntervals <- function(x, calendar = NULL, ...) {
|
|
| 47 | 32x |
z <- x@.End |
| 48 | 19x |
if (is.null(calendar)) return(z) |
| 49 | 13x |
as_year(z, calendar = calendar, decimal = TRUE) |
| 50 |
} |
|
| 51 | ||
| 52 |
#' @export |
|
| 53 |
#' @rdname start |
|
| 54 |
#' @aliases end,TimeIntervals-method |
|
| 55 |
setMethod("end", "TimeIntervals", end.TimeIntervals)
|
|
| 56 | ||
| 57 |
#' @export |
|
| 58 |
#' @method time TimeSeries |
|
| 59 |
time.TimeSeries <- function(x, calendar = NULL, ...) {
|
|
| 60 | 60x |
z <- x@.Time |
| 61 | 25x |
if (is.null(calendar)) return(z) |
| 62 | 35x |
as_year(z, calendar = calendar, decimal = TRUE) |
| 63 |
} |
|
| 64 | ||
| 65 |
#' @export |
|
| 66 |
#' @rdname time |
|
| 67 |
#' @aliases time,TimeSeries-method |
|
| 68 |
setMethod("time", "TimeSeries", time.TimeSeries)
|
|
| 69 | ||
| 70 |
#' @export |
|
| 71 |
#' @method frequency TimeSeries |
|
| 72 |
frequency.TimeSeries <- function(x, ...) {
|
|
| 73 | 1x |
mean(abs(1 / diff(time(x)))) |
| 74 |
} |
|
| 75 | ||
| 76 |
#' @export |
|
| 77 |
#' @rdname time |
|
| 78 |
#' @aliases frequency,TimeSeries-method |
|
| 79 |
setMethod("frequency", "TimeSeries", frequency.TimeSeries)
|
| 1 |
# OPERATORS |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# "+", "-", "*", "^", "%%", "%/%", "/" |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname arithmetic |
|
| 8 |
#' @aliases Arith,RataDie,RataDie-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "Arith", |
|
| 11 |
signature = c(e1 = "RataDie", e2 = "RataDie"), |
|
| 12 |
definition = function(e1, e2) {
|
|
| 13 | 400x |
z <- methods::callGeneric(e1@.Data, e2@.Data) |
| 14 |
switch( |
|
| 15 | 400x |
.Generic[[1]], |
| 16 | 2x |
`+` = return(.RataDie(z)), |
| 17 | 267x |
`-` = return(.RataDie(z)), |
| 18 | 131x |
return(z) |
| 19 |
) |
|
| 20 |
} |
|
| 21 |
) |
|
| 22 | ||
| 23 |
#' @export |
|
| 24 |
#' @rdname arithmetic |
|
| 25 |
#' @aliases Arith,numeric,RataDie-method |
|
| 26 |
setMethod( |
|
| 27 |
f = "Arith", |
|
| 28 |
signature = c(e1 = "numeric", e2 = "RataDie"), |
|
| 29 |
definition = function(e1, e2) {
|
|
| 30 | 54x |
z <- methods::callGeneric(e1, e2@.Data) |
| 31 |
switch( |
|
| 32 | 54x |
.Generic[[1]], |
| 33 | 1x |
`+` = return(.RataDie(z)), |
| 34 | 19x |
`-` = return(.RataDie(z)), |
| 35 | 33x |
`*` = return(.RataDie(z)), |
| 36 | 1x |
return(z) |
| 37 |
) |
|
| 38 |
} |
|
| 39 |
) |
|
| 40 | ||
| 41 |
#' @export |
|
| 42 |
#' @rdname arithmetic |
|
| 43 |
#' @aliases Arith,RataDie,numeric-method |
|
| 44 |
setMethod( |
|
| 45 |
f = "Arith", |
|
| 46 |
signature = c(e1 = "RataDie", e2 = "numeric"), |
|
| 47 |
definition = function(e1, e2) {
|
|
| 48 | 623x |
z <- methods::callGeneric(e1@.Data, e2) |
| 49 |
switch( |
|
| 50 | 623x |
.Generic[[1]], |
| 51 | 188x |
`+` = return(.RataDie(z)), |
| 52 | 148x |
`-` = return(.RataDie(z)), |
| 53 | 1x |
`*` = return(.RataDie(z)), |
| 54 | 1x |
`/` = return(.RataDie(z)), |
| 55 | 285x |
return(z) |
| 56 |
) |
|
| 57 |
} |
|
| 58 |
) |
| 1 |
# SPAN |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname span |
|
| 7 |
#' @aliases span,TimeSeries-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "span", |
|
| 10 |
signature = c(x = "TimeSeries"), |
|
| 11 |
definition = function(x, calendar = NULL) {
|
|
| 12 | 4x |
z <- end(x, calendar = calendar) - start(x, calendar = calendar) |
| 13 | 4x |
unclass(z) * calendar_direction(calendar) |
| 14 |
} |
|
| 15 |
) |
|
| 16 | ||
| 17 |
#' @export |
|
| 18 |
#' @rdname span |
|
| 19 |
#' @aliases span,TimeIntervals-method |
|
| 20 |
setMethod( |
|
| 21 |
f = "span", |
|
| 22 |
signature = c(x = "TimeIntervals"), |
|
| 23 |
definition = function(x, calendar = NULL) {
|
|
| 24 | 4x |
z <- end(x, calendar = calendar) - start(x, calendar = calendar) |
| 25 | 4x |
unclass(z) * calendar_direction(calendar) |
| 26 |
} |
|
| 27 |
) |
| 1 |
# CONVERT |
|
| 2 |
#' @include AllGenerics.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
#' @export |
|
| 6 |
#' @rdname convert |
|
| 7 |
#' @aliases convert,character,character-method |
|
| 8 |
setMethod( |
|
| 9 |
f = "convert", |
|
| 10 |
signature = c(from = "character", to = "character"), |
|
| 11 |
definition = function(from, to) {
|
|
| 12 | 2x |
methods::callGeneric(from = calendar(from), to = calendar(to)) |
| 13 |
} |
|
| 14 |
) |
|
| 15 | ||
| 16 |
#' @export |
|
| 17 |
#' @rdname convert |
|
| 18 |
#' @aliases convert,TimeScale,TimeScale-method |
|
| 19 |
setMethod( |
|
| 20 |
f = "convert", |
|
| 21 |
signature = c(from = "TimeScale", to = "TimeScale"), |
|
| 22 |
definition = function(from, to) {
|
|
| 23 |
## TODO: validation |
|
| 24 | ||
| 25 | 2x |
fun <- function(x) {
|
| 26 | 2x |
a <- fixed(x, month = 01, day = 01, calendar = from) |
| 27 | 2x |
b <- as_year(a, calendar = to, decimal = TRUE) |
| 28 | 2x |
return(b) |
| 29 |
} |
|
| 30 | ||
| 31 | 2x |
return(fun) |
| 32 |
} |
|
| 33 |
) |
| 1 |
# COERCION |
|
| 2 |
#' @include AllGenerics.R AllClasses.R |
|
| 3 |
NULL |
|
| 4 | ||
| 5 |
# To RataDie =================================================================== |
|
| 6 |
#' @export |
|
| 7 |
#' @rdname as_fixed |
|
| 8 |
#' @aliases as_fixed,numeric-method |
|
| 9 |
setMethod( |
|
| 10 |
f = "as_fixed", |
|
| 11 |
signature = "numeric", |
|
| 12 | 5x |
definition = function(from) .RataDie(from) |
| 13 |
) |
|
| 14 | ||
| 15 |
# To data.frame ================================================================ |
|
| 16 |
#' @export |
|
| 17 |
#' @method as.data.frame TimeSeries |
|
| 18 |
as.data.frame.TimeSeries <- function(x, ..., calendar = NULL) {
|
|
| 19 |
## Build a long data frame |
|
| 20 | 1x |
z <- as.data.frame.table(x, base = list("T", "S", LETTERS))
|
| 21 | ||
| 22 |
## Add sampling times |
|
| 23 | 1x |
z[[1]] <- time(x, calendar = calendar) |
| 24 | ||
| 25 |
## Fix colnames |
|
| 26 | 1x |
colnames(z) <- c("time", "series", "variable", "value")
|
| 27 | ||
| 28 | 1x |
z |
| 29 |
} |
|
| 30 | ||
| 31 |
#' @export |
|
| 32 |
#' @describeIn as.data.frame Returns a long [`data.frame`] with the following columns: |
|
| 33 |
#' \describe{
|
|
| 34 |
#' \item{`time`}{The (decimal) years at which the time series was sampled.}
|
|
| 35 |
#' \item{`series`}{The name of the time series.}
|
|
| 36 |
#' \item{`variable`}{The name of the variables.}
|
|
| 37 |
#' \item{`value`}{The observed value.}
|
|
| 38 |
#' } |
|
| 39 |
#' @aliases as.data.frame,TimeSeries-method |
|
| 40 |
setMethod("as.data.frame", "TimeSeries", as.data.frame.TimeSeries)
|
|
| 41 | ||
| 42 |
#' @export |
|
| 43 |
#' @method as.data.frame TimeIntervals |
|
| 44 |
as.data.frame.TimeIntervals <- function(x, ..., calendar = NULL) {
|
|
| 45 |
## Build a data frame |
|
| 46 | 4x |
data.frame( |
| 47 | 4x |
label = labels(x), |
| 48 | 4x |
start = start(x, calendar = calendar), |
| 49 | 4x |
end = end(x, calendar = calendar) |
| 50 |
) |
|
| 51 |
} |
|
| 52 | ||
| 53 |
#' @export |
|
| 54 |
#' @describeIn as.data.frame Returns a [`data.frame`] with the following columns: |
|
| 55 |
#' \describe{
|
|
| 56 |
#' \item{`label`}{The name of the intervals.}
|
|
| 57 |
#' \item{`start`}{The start time of the intervals, in (decimal) years.}
|
|
| 58 |
#' \item{`end`}{The end time of the intervals, in (decimal) years.}
|
|
| 59 |
#' } |
|
| 60 |
#' @aliases as.data.frame,TimeIntervals-method |
|
| 61 |
setMethod("as.data.frame", "TimeIntervals", as.data.frame.TimeIntervals)
|
| 1 |
# HELPERS |
|
| 2 | ||
| 3 |
## https://michaelchirico.github.io/potools/articles/developers.html |
|
| 4 |
tr_ <- function(...) {
|
|
| 5 | 316x |
enc2utf8(gettext(paste0(...), domain = "R-aion")) |
| 6 |
} |
|
| 7 | ||
| 8 |
make_par <- function(params, x, n = 1) {
|
|
| 9 | 321x |
p <- params[[x]] %||% graphics::par()[[x]] |
| 10 | 12x |
if (length(p) == 1 && n > 1) p <- rep(p, length.out = n) |
| 11 | 321x |
p |
| 12 |
} |
|
| 13 | ||
| 14 |
#' Plotting Dimensions of Character Strings |
|
| 15 |
#' |
|
| 16 |
#' Convert string length in inch to number of (margin) lines. |
|
| 17 |
#' @param x A [`character`] vector of string whose length is to be calculated. |
|
| 18 |
#' @param ... Further parameter to be passed to [graphics::strwidth()]`, such as |
|
| 19 |
#' `cex`. |
|
| 20 |
#' @return |
|
| 21 |
#' A [`numeric`] vector (maximum string width in units of margin lines). |
|
| 22 |
#' @note For internal use only. |
|
| 23 |
#' @family graphic tools |
|
| 24 |
#' @keywords internal |
|
| 25 |
#' @noRd |
|
| 26 |
inch2line <- function(x, ...) {
|
|
| 27 | 1x |
(max(graphics::strwidth(x, units = "inch", ...)) / |
| 28 | 1x |
graphics::par("cin")[2] + graphics::par("mgp")[2]) * graphics::par("cex")
|
| 29 |
} |