diff --git a/DESCRIPTION b/DESCRIPTION index 6d3e38ac..d37a5630 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: xts Type: Package Title: eXtensible Time Series -Version: 0.13.2.2 +Version: 0.14.1 Authors@R: c( person(given=c("Jeffrey","A."), family="Ryan", role=c("aut","cph")), person(given=c("Joshua","M."), family="Ulrich", role=c("cre","aut"), email="josh.m.ulrich@gmail.com"), @@ -17,3 +17,5 @@ Description: Provide for uniform handling of R's different time-based data class License: GPL (>= 2) URL: https://joshuaulrich.github.io/xts/, https://github.com/joshuaulrich/xts BugReports: https://github.com/joshuaulrich/xts/issues +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index d7bd2b5c..38557a0a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -161,7 +161,6 @@ export(axTicksByTime) export(plot.xts) export(addLegend) export(addEventLines) -# export(addPoints) export(addSeries) export(addPanel) export(addPolygon) @@ -172,16 +171,10 @@ S3method(print, replot_xts) S3method(plot, replot_xts) S3method(str, replot_xts) -#export(lines.xts) -#S3method(lines,xts) -#S3method(points,xts) - -#export(Lag.xts, Next.xts) #, Diff.xts) export(lag.xts) export(diff.xts) export(merge.xts) -#export(mergeXts) S3method(all.equal, xts) S3method(split, xts) S3method(lag,xts) @@ -208,7 +201,6 @@ importFrom(zoo,'index<-') importFrom(zoo,'time<-') importFrom(zoo, na.locf) importFrom(zoo, as.zoo) -#importFrom(zoo, lagts) importFrom(zoo, rollapply) importFrom(zoo, na.approx) importFrom(zoo, na.fill) @@ -275,7 +267,6 @@ S3method(cumsum, xts) S3method(cumprod, xts) S3method(cummin, xts) S3method(cummax, xts) -#S3method(lagts,xts) S3method(rollapply, xts) # list specific methods @@ -286,7 +277,6 @@ S3method(as.xts, ts) S3method(as.ts, xts) # zoo specific methods -#importFrom(zoo,as.zoo) # now in zoo S3method(as.xts,zoo) if (getRversion() >= "3.6.0" && utils::packageVersion("zoo") < "1.8.5") { # xts:::as.zoo.xts was copied to zoo:::as.zoo.xts in zoo 1.8-5 @@ -302,7 +292,6 @@ S3method(as.xts,matrix) S3method(as.matrix,xts) # environment specific methods -#S3method(as.xts,environment) S3method(as.environment,xts) # timeSeries (package:timeSeries) specific methods @@ -327,5 +316,3 @@ S3method(as.xts,yearqtr) # timeDate specific methods S3method(as.xts,timeDate) ## currently unexported functions that _may_ be exported at some point - -#export(startof,endof,firstof,lastof) diff --git a/NEWS.md b/NEWS.md index 47a76e0c..1febb416 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,24 @@ +# xts 0.14.0 (2024-06-05) + +* `addEventLines()` and `addLegend()` now draw on multiple panels when `on` is + a vector. Thanks to Ethan Smith for the report. + ([#420](https://github.com/joshuaulrich/xts/issues/420)) + +* Replace `SET_TYPEOF()` in merge.c because it will error when it tries to + convert a REAL to an INTEGER. Thanks to Kurt Hornik for the report! + ([#419](https://github.com/joshuaulrich/xts/issues/419)) + +* Fix crash when 'j' is not an integer and in [0, 1) (e.g. `j = 0.1`). Also + throw a warning when 'j' is not an integer. + ([#413](https://github.com/joshuaulrich/xts/issues/413)) + ([#415](https://github.com/joshuaulrich/xts/issues/415)) + +* Fix plot header when `layout()` is used to draw multiple plots on a single + device. Thanks to Dirk Eddelbuettel for the report and testing! + ([#412](https://github.com/joshuaulrich/xts/issues/412)) + +* Fix plot legend location when the y-axis is log scale. + ([#407](https://github.com/joshuaulrich/xts/issues/407)) # xts 0.13.2 (2024-01-21) diff --git a/R/Date.R b/R/Date.R index bad3d6b8..a0f44316 100644 --- a/R/Date.R +++ b/R/Date.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,7 @@ # along with this program. If not, see . +#' @rdname as.xts `as.xts.Date` <- function(x,...) { xts(x=NULL,order.by=x,...) } diff --git a/R/Math.xts.R b/R/Math.xts.R index d612837b..1e02837a 100644 --- a/R/Math.xts.R +++ b/R/Math.xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -64,4 +64,4 @@ sd.xts <- function(x,na.rm=FALSE) { x<-as.numeric(x) sd(x,na.rm=na.rm) } else apply(x,2,sd,na.rm=na.rm) -} \ No newline at end of file +} diff --git a/R/OHLC.R b/R/OHLC.R index 1d731ffd..b76fe9bd 100644 --- a/R/OHLC.R +++ b/R/OHLC.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/Ops.xts.R b/R/Ops.xts.R index 96c05f0d..e299fdfc 100644 --- a/R/Ops.xts.R +++ b/R/Ops.xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/POSIX.R b/R/POSIX.R index 5f4eb418..d80e82ed 100644 --- a/R/POSIX.R +++ b/R/POSIX.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,7 @@ # along with this program. If not, see . +#' @rdname as.xts as.xts.POSIXt <- function(x, ...) { xts(NULL, order.by=x) diff --git a/R/adj.time.R b/R/adj.time.R index 4cbba723..d97af98a 100644 --- a/R/adj.time.R +++ b/R/adj.time.R @@ -19,6 +19,7 @@ # along with this program. If not, see . +#' @rdname align.time adj.time <- function(x, ...) { tr <- match.call(expand.dots=FALSE)$... diff --git a/R/align.time.R b/R/align.time.R index 204255ee..8c4e6168 100644 --- a/R/align.time.R +++ b/R/align.time.R @@ -19,10 +19,43 @@ # along with this program. If not, see . +#' Align seconds, minutes, and hours to beginning of next period. +#' +#' Change timestamps to the start of the next period, specified in multiples of +#' seconds. +#' +#' This function is an S3 generic. The result is to round up to the next period +#' determined by 'n modulo x'. +#' +#' @param x Object containing timestamps to align. +#' @param n Number of seconds to adjust by. +#' @param \dots Additional arguments. See details. +#' +#' @return A new object with the same class as `x`. +#' +#' @author Jeffrey A. Ryan with input from Brian Peterson +#' +#' @seealso [`to.period()`] +#' +#' @keywords chron manip ts misc +#' @examples +#' +#' x <- Sys.time() + 1:1000 +#' +#' # every 10 seconds +#' align.time(x, 10) +#' +#' # align to next whole minute +#' align.time(x, 60) +#' +#' # align to next whole 10 min interval +#' align.time(x, 10 * 60) +#' align.time <- function(x, ...) { UseMethod("align.time") } +#' @rdname align.time align.time.xts <- function(x, n=60, ...) { if(n <= 0) stop("'n' must be positive") .xts(x, .index(x) + (n-.index(x) %% n), tzone=tzone(x), tclass=tclass(x)) @@ -38,6 +71,7 @@ align.time.POSIXlt <- function(x, n=60, ...) { as.POSIXlt(align.time(as.POSIXct(x),n=n,...)) } +#' @rdname align.time shift.time <- function(x, n=60, ...) { UseMethod("shift.time") } @@ -46,9 +80,12 @@ shift.time.xts <- function(x, n=60, ...) { .xts(x, .index(x) + n, tzone=tzone(x), tclass=tclass(x)) } -is.index.unique <- is.time.unique <- function(x) { +#' @rdname make.index.unique +is.index.unique <- function(x) { UseMethod("is.time.unique") } +#' @rdname make.index.unique +is.time.unique <- is.index.unique is.time.unique.xts <- function(x) { isOrdered(.index(x), strictly=TRUE) @@ -58,10 +95,54 @@ is.time.unique.zoo <- function(x) { isOrdered(index(x), strictly=TRUE) } -make.index.unique <- make.time.unique <- function(x, eps=0.000001, drop=FALSE, fromLast=FALSE, ...) { +#' Force Time Values To Be Unique +#' +#' A generic function to force sorted time vectors to be unique. Useful for +#' high-frequency time-series where original time-stamps may have identical +#' values. For the case of xts objects, the default `eps` is set to ten +#' microseconds. In practice this advances each subsequent identical time by +#' `eps` over the previous (possibly also advanced) value. +#' +#' The returned time-series object will have new time-stamps so that +#' `isOrdered(.index(x))` evaluates to `TRUE`. +#' +#' @param x An xts object, or POSIXct vector. +#' @param eps A value to add to force uniqueness. +#' @param drop Should duplicates be dropped instead of adjusted by `eps`? +#' @param fromLast When `drop = TRUE`, `fromLast` controls which duplicated +#' times are dropped. When `fromLast = FALSE`, the earliest observation with +#' an identical timestamp is kept and subsequent observations are dropped. +#' @param \dots Unused. +#' +#' @return A modified version of `x` with unique timestamps. +#' +#' @note Incoming values must be pre-sorted, and no check is done to make sure +#' that this is the case. \sQuote{integer} index value will be coerced to +#' \sQuote{double} when `drop = FALSE`. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`align.time()`] +#' +#' @rdname make.index.unique +#' @keywords ts +#' @examples +#' +#' ds <- options(digits.secs=6) # so we can see the change +#' +#' x <- xts(1:10, as.POSIXct("2011-01-21") + c(1,1,1,2:8)/1e3) +#' x +#' make.index.unique(x) +#' +#' options(ds) +#' +make.index.unique <- function(x, eps=0.000001, drop=FALSE, fromLast=FALSE, ...) { UseMethod("make.index.unique") } +#' @rdname make.index.unique +make.time.unique <- make.index.unique + make.index.unique.xts <- function(x, eps=0.000001, drop=FALSE, fromLast=FALSE, ...) { if( !drop) { .Call(C_make_index_unique, x, eps) diff --git a/R/as.environment.xts.R b/R/as.environment.xts.R index 30531025..8dbe7542 100644 --- a/R/as.environment.xts.R +++ b/R/as.environment.xts.R @@ -18,7 +18,36 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . - +#' Coerce an xts Object to an Environment by Column +#' +#' Method to automatically convert an xts object to an environment containing +#' vectors representing each column of the original xts object. The name of +#' each object in the resulting environment corresponds to the name of the +#' column of the xts object. +#' +#' @param x An xts object. +#' +#' @return An environment containing `ncol(x)` vectors extracted by +#' column from `x`. +#' +#' @note Environments do not preserve (or have knowledge) of column order and +#' cannot be subset by an integer index. +#' +#' @author Jeffrey A. Ryan +#' +#' @keywords manip +#' @examples +#' +#' x <- xts(1:10, Sys.Date()+1:10) +#' colnames(x) <- "X" +#' y <- xts(1:10, Sys.Date()+1:10) +#' colnames(x) <- "Y" +#' xy <- cbind(x,y) +#' colnames(xy) +#' e <- as.environment(xy) # currently using xts-style positive k +#' ls(xy) +#' ls.str(xy) +#' as.environment.xts <- function(x) { e <- new.env() lapply(1:NCOL(x), function(.) assign(colnames(x)[.], x[,.],envir=e)) diff --git a/R/as.numeric.R b/R/as.numeric.R index b1e3816e..2b3f4fc0 100644 --- a/R/as.numeric.R +++ b/R/as.numeric.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/axTicksByTime.R b/R/axTicksByTime.R index 16aadf83..14028205 100644 --- a/R/axTicksByTime.R +++ b/R/axTicksByTime.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,48 @@ # along with this program. If not, see . +#' Compute x-Axis Tickmark Locations by Time +#' +#' Compute x-axis tickmarks like [`axTicks()`] in base but with respect to +#' time. This function is written for internal use, and documented for those +#' wishing to use it for customized plots. +#' +#' The default `ticks.on = "auto"` uses heuristics to compute sensible tick +#' locations. Use a combination of `ticks.on` and `k` to create tick locations +#' at specific intervals. For example, `ticks.on = "days"` and `k = 7` will +#' create tick marks every 7 days. +#' +#' When `format.labels` is a character string the possible values are the same +#' as those listed in the Details section of [`strptime()`]. +#' +#' @param x An object indexed by time or a vector of times/dates. +#' @param ticks.on Time unit for tick locations. +#' @param k Frequency of tick locations. +#' @param labels Should a labeled vector be returned? +#' @param format.labels Either a logical value specifying whether labels should +#' be formatted, or a character string specifying the format to use. +#' @param ends Should the ends be adjusted? +#' @param gt Lower bound on number of tick locations. +#' @param lt Upper bound on number of tick locations. +#' +#' @return A numeric vector of index element locations where tick marks should +#' be drawn. These are *locations* (e.g. 1, 2, 3, ...), *not* the +#' index timestamps. +#' +#' If possible, the result will be named using formatted values from the index +#' timestamps. The names will be used for the tick mark labels. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`endpoints()`] +#' @keywords utilities +#' @examples +#' +#' data(sample_matrix) +#' axTicksByTime(as.xts(sample_matrix),'auto') +#' axTicksByTime(as.xts(sample_matrix),'weeks') +#' axTicksByTime(as.xts(sample_matrix),'months',7) +#' axTicksByTime <- function(x, ticks.on = "auto", k = 1, labels = TRUE, format.labels = TRUE, ends = TRUE, gt = 2, lt = 30) diff --git a/R/bind.R b/R/bind.R index 3e8cec9f..4e85cbef 100644 --- a/R/bind.R +++ b/R/bind.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,63 +19,61 @@ # along with this program. If not, see . -cbind.xts <- function(..., all=TRUE, fill=NA, suffixes=NULL) { -# mc <- match.call(call=sys.call(sys.parent())) -# mc[[1]] <- as.name("merge.xts") -# eval(mc) - merge.xts(..., all=all, fill=fill, suffixes=suffixes) -} -# # convert the call to a list to better manipulate it -# mc <- as.list(match.call(call=sys.call(-1))) -# -# # remove deparse.level arg if called via cbind 'generic' -# if(as.character(mc[[1]]) == "cbind") -# mc <- mc[-2] -# -# # check if any default args are missing from the call, -# # and add them to the call with the cbind defaults -# if(missing(all)) mc <- c(mc,all=all) -# if(missing(fill)) mc <- c(mc,fill=fill) -# if(missing(suffixes)) mc <- c(mc,suffixes=suffixes) -# -# # replace the call to cbind.xts with merge.xts -# mc[[1]] <- as.name('merge.xts') -# -# # convert the list into a call and evaluate it -# mc <- as.call(mc) -# eval(mc) -#} -# sc <- sys.call(sys.parent()) -# mc <- gsub('cbind|cbind.xts','merge.xts',deparse(match.call(call=sc))) -# return(eval(parse(text=mc))) -# dots <- mc$... -# length.args <- sum(.External("number_of_cols",...,PACKAGE="xts")) -# if(is.null(suffixes)) -# suffixes <- all.vars(match.call(call=sc), unique=FALSE)[1:length.args] -# -# if( length(suffixes) != length.args ) { -# warning("length of suffixes and does not match number of merged objects") -# suffixes <- rep(suffixes, length.out=length.args) -# } -# -# merge.xts(..., all=all, fill=fill, suffixes=suffixes) -# -# dat <- list(...) -# x <- dat[[1]]; dat <- dat[-1] -# while( length(dat) > 0 ) { -# y <- dat[[1]] -# if( length(dat) > 0 ) -# dat <- dat[-1] -# x <- merge.xts(x, y, all=TRUE, fill=NA, suffixes=NULL, retclass="xts") -# } -# x -#} - +#' @rdname rbind.xts `c.xts` <- function(...) { .External(C_rbindXts, dup=FALSE, ...) } + +#' Concatenate Two or More xts Objects by Row +#' +#' Concatenate or bind by row two or more xts objects along a time-based index. +#' All objects must have the same number of columns and be xts objects or +#' coercible to xts. +#' +#' Duplicate index values are supported. When one or more input has the same +#' index value, the duplicated index values in the result are in the same order +#' the objects are passed to `rbind()`. See examples. +#' +#' `c()` is an alias for `rbind()` for xts objects. +#' +#' See [`merge.xts()`] for traditional merge operations. +#' +#' @param \dots Objects to bind by row. +#' @param deparse.level Not implemented. +#' +#' @return An xts object with one row per row for each object concatenated. +#' +#' @note `rbind()` is a '.Primitive' function in \R, which means method dispatch +#' occurs at the C-level, and may not be consistent with normal S3 method +#' dispatch (see [`rbind()`] for details). Call `rbind.xts()` directly to +#' avoid potential dispatch ambiguity. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`merge.xts()`] [`rbind()`] +#' +#' @keywords utilities +#' @examples +#' +#' x <- xts(1:10, Sys.Date()+1:10) +#' str(x) +#' +#' merge(x,x) +#' rbind(x,x) +#' rbind(x[1:5],x[6:10]) +#' +#' c(x,x) +#' +#' # this also works on non-unique index values +#' x <- xts(rep(1,5), Sys.Date()+c(1,2,2,2,3)) +#' y <- xts(rep(2,3), Sys.Date()+c(1,2,3)) +#' +#' # overlapping indexes are appended +#' rbind(x,y) +#' rbind(y,x) +#' rbind.xts <- function(..., deparse.level=1) { .External(C_rbindXts, dup=FALSE, ...) diff --git a/R/coredata.xts.R b/R/coredata.xts.R index ecb41d2b..6932dee0 100644 --- a/R/coredata.xts.R +++ b/R/coredata.xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,50 @@ # along with this program. If not, see . +#' Extract/Replace Core Data of an xts Object +#' +#' Mechanism to extract and replace the core data of an xts object. +#' +#' Extract coredata of an xts object - removing all attributes except +#' `dim` and `dimnames` and returning a matrix object with rownames +#' converted from the index of the xts object. +#' +#' The rownames of the result use the format specified by `tformat(x)` when +#' `fmt = TRUE`. When `fmt` is a character string to be passed to `format()`. +#' See [`strptime()`] for valid format strings. Setting `fmt = FALSE` will +#' return the row names by simply coercing the index class to a character +#' string in the default manner. +#' +#' `xcoredata()` is the complement to `coredata()`. It returns all of the +#' attributes normally removed by `coredata()`. Its purpose, along with the +#' the replacement function `xcoredata<-` is primarily for developers using +#' \pkg{xts}' [`try.xts()`] and [`reclass()`] functionality inside functions +#' so the functions can take any time series class as an input and return the +#' same time series class. +#' +#' @param x An xts object. +#' @param fmt Should the rownames be formated using `tformat()`? Alternatively +#' a date/time string to be passed to `format()`. See details. +#' @param value Non-core attributes to assign. +#' @param \dots Unused. +#' +#' @return Returns either a matrix object for coredata, or a list of named +#' attributes. +#' +#' The replacement functions are called for their side-effects. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`coredata()`][zoo::zoo], [`xtsAttributes()`] +#' +#' @keywords utilities +#' @examples +#' +#' data(sample_matrix) +#' x <- as.xts(sample_matrix, myattr=100) +#' coredata(x) +#' xcoredata(x) +#' coredata.xts <- function(x, fmt=FALSE, ...) { x.attr <- attributes(x) @@ -70,12 +114,13 @@ function(x,...) { original.attr } - +#' @rdname coredata.xts `xcoredata` <- function(x,...) { UseMethod('xcoredata') } +#' @rdname coredata.xts `xcoredata<-` <- function(x,value) { UseMethod('xcoredata<-') } @@ -92,6 +137,42 @@ function(x,...) { } } + +#' Extract and Replace xts Attributes +#' +#' Extract and replace non-core xts attributes. +#' +#' This function allows users to assign custom attributes to the xts objects, +#' without altering core xts attributes (i.e. tclass, tzone, and tformat). +#' +#' [`attributes()`] returns all attributes, including core attributes of the +#' xts class. +#' +#' @param x An xts object. +#' @param user Should user-defined attributes be returned? The default of +#' `NULL` returns all xts attributes. +#' @param value A list of new `name = value` attributes. +#' +#' @return A named list of user-defined attributes. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`attributes()`] +#' +#' @keywords utilities +#' @examples +#' +#' x <- xts(matrix(1:(9*6),nc=6), +#' order.by=as.Date(13000,origin="1970-01-01")+1:9, +#' a1='my attribute') +#' +#' xtsAttributes(x) +#' xtsAttributes(x) <- list(a2=2020) +#' +#' xtsAttributes(x) +#' xtsAttributes(x) <- list(a1=NULL) +#' xtsAttributes(x) +#' `xtsAttributes` <- function(x, user=NULL) { # get all additional attributes not standard to xts object @@ -119,6 +200,7 @@ function(x, user=NULL) { xa } +#' @rdname xtsAttributes `xtsAttributes<-` <- function(x,value) { UseMethod('xtsAttributes<-') diff --git a/R/data.frame.R b/R/data.frame.R index ac445543..a6a7e8f7 100644 --- a/R/data.frame.R +++ b/R/data.frame.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -26,6 +26,7 @@ function(x,...) { data.frame(x,...) } +#' @rdname as.xts `as.xts.data.frame` <- function(x, order.by, diff --git a/R/dimnames.R b/R/dimnames.R index 14840da6..d2999137 100644 --- a/R/dimnames.R +++ b/R/dimnames.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -22,6 +22,42 @@ # dimnames will return the actual dimnames of the xts object # dimnames<-.xts will force the rownames to always be NULL + +#' Dimnames of an xts Object +#' +#' Get or set dimnames of an xts object. +#' +#' For efficienty, xts objects do not have rownames (unlike zoo objects). +#' Attempts to set rownames on an xts object will silently set them to `NULL`. +#' This is done for internal compatibility reasons, as well as to provide +#' consistency in performance regardless of object use. +#' +#' @param x An xts object. +#' @param value A two element list. See Details. +#' +#' @return A list or character string containing coerced row names and/or +#' actual column names. +#' +#' Attempts to set rownames on xts objects via rownames or dimnames will +#' silently fail. +#' +#' @note Unlike zoo, all xts objects have dimensions. xts objects cannot be +#' plain vectors. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`xts()`] +#' +#' @keywords misc +#' @examples +#' +#' x <- xts(1:10, Sys.Date()+1:10) +#' dimnames(x) +#' rownames(x) +#' rownames(x) <- 1:10 +#' rownames(x) +#' str(x) +#' `dimnames.xts` <- function(x) { #list(NULL, colnames(unclass(x))) @@ -29,6 +65,7 @@ function(x) { #list(as.character(index(x)), colnames(unclass(x))) } +#' @rdname dimnames.xts `dimnames<-.xts` <- function(x, value) { .Call(C_xts_set_dimnames, x, value) diff --git a/R/endpoints.R b/R/endpoints.R index bf76c133..3d316f4b 100644 --- a/R/endpoints.R +++ b/R/endpoints.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,49 @@ # along with this program. If not, see . +#' Locate Endpoints by Time +#' +#' Extract index locations for an xts object that correspond to the *last* +#' observation in each period specified by `on` and `k`. +#' +#' `endpoints()` returns a numeric vector that always begins with zero and ends +#' with the number of observations in `x`. +#' +#' Periods are always based on the distance from the UNIX epoch (midnight +#' 1970-01-01 UTC), *not the first observation in `x`*. See the examples. +#' +#' Valid values for the `on` argument are: \dQuote{us} (microseconds), +#' \dQuote{microseconds}, \dQuote{ms} (milliseconds), \dQuote{milliseconds}, +#' \dQuote{secs} (seconds), \dQuote{seconds}, \dQuote{mins} (minutes), +#' \dQuote{minutes}, \dQuote{hours}, \dQuote{days}, \dQuote{weeks}, +#' \dQuote{months}, \dQuote{quarters}, and \dQuote{years}. +#' +#' @param x An xts object. +#' @param on A character string specifying the period. +#' @param k The number of periods each endpoint should cover. +#' +#' @return A numeric vector of beginning with 0 and ending with the number of +#' of observations in `x`. +#' +#' @author Jeffrey A. Ryan +#' @keywords utilities +#' @examples +#' +#' data(sample_matrix) +#' +#' endpoints(sample_matrix) +#' endpoints(sample_matrix, "weeks") +#' +#' ### example of how periods are based on the UNIX epoch, +#' ### *not* the first observation of the data series +#' x <- xts(1:38, yearmon(seq(2018 - 1/12, 2021, 1/12))) +#' # endpoints for the end of every other year +#' ep <- endpoints(x, "years", k = 2) +#' # Dec-2017 is the end of the *first* year in the data. But when you start from +#' # Jan-1970 and use every second year end as your endpoints, the endpoints are +#' # always December of every odd year. +#' x[ep, ] +#' endpoints <- function(x,on='months',k=1) { @@ -117,11 +160,41 @@ function(x,by='months', k=1) { endpoints(x,on=by, k=k)[-1] } + +#' Create a POSIXct Object +#' +#' Easily create of time stamps corresponding to the first or last observation +#' in a specified time period. +#' +#' This is a wrapper to [`ISOdatetime()`] with defaults corresponding to the +#' first or last possible time in a given period. +#' +#' @param year,month,day Numeric values to specify a day. +#' @param hour,min,sec Numeric vaues to specify time within a day. +#' @param tz Timezone used for conversion. +#' +#' @return An POSIXct object. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`ISOdatetime()`] +#' +#' @keywords utilities +#' @examples +#' +#' firstof(2000) +#' firstof(2005,01,01) +#' +#' lastof(2007) +#' lastof(2007,10) +#' `firstof` <- function(year=1970,month=1,day=1,hour=0,min=0,sec=0,tz="") { ISOdatetime(year,month,day,hour,min,sec,tz) } +#' @param subsec Number of sub-seconds. +#' @rdname firstof lastof <- function (year = 1970, month = 12, diff --git a/R/fillIndex.R b/R/fillIndex.R deleted file mode 100644 index 563860c7..00000000 --- a/R/fillIndex.R +++ /dev/null @@ -1,30 +0,0 @@ -# -# xts: eXtensible time-series -# -# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com -# -# Contributions from Joshua M. Ulrich -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -`fillIndex` <- -function(x) { - p <- periodicity(x) - xx <- xts(matrix(rep(NA,NCOL(x)),nrow=1), - seq(start(x),end(x),by=p$units)) - xx[index(xx) %in% index(x)] <- x - colnames(xx) <- colnames(x) - xx -} diff --git a/R/first.R b/R/first.R index a4810181..5399e1f6 100644 --- a/R/first.R +++ b/R/first.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,12 +19,72 @@ # along with this program. If not, see . +#' Return First or Last n Elements of A Data Object +#' +#' Generic functions to return the first or last elements or rows of a vector +#' or two-dimensional data object. +#' +#' A more advanced subsetting is available for zoo objects with indexes +#' inheriting from POSIXt or Date classes. +#' +#' Quickly and easily extract the first or last `n` observations of an object. +#' When `n` is a number, these functions are similar to [`head()`] and +#' [`tail()`], but only return the *first* or *last* observation by default. +#' +#' `n` can be a character string if `x` is an xts object or coerceable to xts. +#' It must be of the form \sQuote{n period}, where 'n' is a numeric value +#' (1 if not provided) describing the number of periods to return. Valid +#' periods are: secs, seconds, mins, minutes, hours, days, weeks, months, +#' quarters, and years. +#' +#' The 'period' portion can be any frequency greater than or equal to the +#' frequency of the object's time index. For example, `first(x, "2 months")` +#' will return the first 2 months of data even if `x` is hourly frequency. +#' Attempts to set 'period' to a frequency less than the object's frequency +#' will throw an error. +#' +#' `n` may be positive or negative, whether it's a number or character string. +#' When `n` is positive, the functions return the obvious result. For example, +#' `first(x, "1 month")` returns the first month's data. When `n` is negative, +#' all data *except* first month's is returned. +#' +#' Requesting more data than is in `x` will throw a warning and simply return +#' `x`. +#' +#' @param x An object. +#' @param n Number of observations to return. +#' @param keep Should removed values be kept as an attribute on the result? +#' @param \dots Arguments passed to other methods. +#' +#' @return A subset of elements/rows of the original data. +#' +#' @author Jeffrey A. Ryan +#' +#' @keywords utilities +#' @examples +#' +#' first(1:100) +#' last(1:100) +#' +#' data(LakeHuron) +#' first(LakeHuron,10) +#' last(LakeHuron) +#' +#' x <- xts(1:100, Sys.Date()+1:100) +#' first(x, 10) +#' first(x, '1 day') +#' first(x, '4 days') +#' first(x, 'month') +#' last(x, '2 months') +#' last(x, '6 weeks') +#' `first` <- function(x,...) { UseMethod("first") } +#' @rdname first `first.default` <- function(x,n=1,keep=FALSE,...) { @@ -72,6 +132,7 @@ function(x,n=1,keep=FALSE,...) } } +#' @rdname first `first.xts` <- function(x,n=1,keep=FALSE,...) { diff --git a/R/index.R b/R/index.R index 5d01ae19..80320f49 100644 --- a/R/index.R +++ b/R/index.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,7 +19,176 @@ # along with this program. If not, see . -index.xts <- time.xts <- +#' Get and Replace the Class of an xts Index +#' +#' Functions to get and replace an xts object's index values and it's +#' components. +#' +#' An xts object's index is stored internally as the number of seconds since +#' UNIX epoch in the UTC timezone. The `.index()` and `.index<-` functions get +#' and replace the internal numeric value of the index, respectively. These +#' functions are primarily for internal use, but are exported because they may +#' be useful for users. +#' +#' The replacement method also updates the [`tclass()`] and [`tzone()`] of the +#' index to match the class and timezone of the new index, respectively. The +#' `index()` method converts the internal numeric index to the class specified +#' by the 'tclass' attribute and with the timezone specified by the 'tzone' +#' attribute before returning the index values to the user. +#' +#' The `.indexXXX()` functions below extract time components from the internal +#' time index. They return values like the values of [POSIXlt] components. +#' +#' \describe{ +#' \item{`.indexsec`}{0 - 61: seconds of the minute (local time)} +#' \item{`.indexmin`}{0 - 59: minutes of the hour (local time)} +#' \item{`.indexhour`}{0 - 23: hours of the day (local time)} +#' \item{`.indexDate`}{date as seconds since the epoch (UTC *not local time*} +#' \item{`.indexday`}{date as seconds since the epoch (UTC *not local time*} +#' \item{`.indexwday`}{0 - 6: day of the week (Sunday - Saturday, local time)} +#' \item{`.indexmday`}{1 - 31: day of the month (local time)} +#' \item{`.indexweek`}{weeks since the epoch (UTC *not local time*} +#' \item{`.indexmon`}{0 - 11: month of the year (local time)} +#' \item{`.indexyear`}{years since 1900 (local time)} +#' \item{`.indexyday`}{0 - 365: day of the year (local time, 365 only in leap years)} +#' \item{`.indexisdst`}{1, 0, -1: Daylight Saving Time flag. Positive if +#' Daylight Saving Time is in effect, zero if not, negative if unknown.} +#' } +#' +#' Changes in timezone, index class, and index format internal structure, by +#' \pkg{xts} version: +#' +#' \describe{ +#' \item{Version 0.12.0:}{The `.indexTZ`, `.indexCLASS` and `.indexFORMAT` +#' attributes are no longer stored on xts objects, only on the index itself. +#' \cr\cr +#' The `indexTZ()`, `indexClass()`, and `indexFormat()` functions (and +#' their respective replacement methods) are deprecated in favor of their +#' respective `tzone()`, `tclass()`, and `tformat()` versions. The previous +#' versions throw a warning that they're deprecated, but they will continue +#' to work. They will never be removed or throw an error. Ever. +#' \cr\cr +#' The new versions are careful to look for the old attributes on the xts +#' object, in case they're ever called on an xts object that was created prior +#' to the attributes being added to the index itself. +#' \cr\cr +#' You can set `options(xts.warn.index.missing.tzone = TRUE)` and +#' `options(xts.warn.index.missing.tclass = TRUE)` to identify xts objects +#' that do not have a 'tzone' or 'tclass' attribute on the index, even if +#' there is a 'tzone' or 'tclass' attribute on the xts object itself. The +#' warnings will be thrown when the object is printed. +#' Use `x <- as.xts(x)` to update these objects to the new structure.} +#' +#' \item{Version 0.9.8:}{The index timezone is now set to "UTC" for time classes +#' that do not have any intra-day component (e.g. days, months, quarters). +#' Previously the timezone was blank, which meant "local time" as determined by +#' \R and the OS.} +#' +#' \item{Version 0.9.2:}{There are new get/set methods for the timezone, index +#' class, and index format attributes: `tzone()` and, `tzone<-`, `tclass()` +#' and `tclass<-`, and `tformat()` and `tformat<-`. These new functions are +#' aliases to their `indexTZ()`, `indexClass()`, and `indexFormat()` +#' counterparts.} +#' +#' \item{Version 0.7.5:}{The timezone, index class, and index format were added +#' as attributes to the index itself, as 'tzone', 'tclass', and 'tformat', +#' respectively. This is in order to remove those three attributes from the xts +#' object, so they're only on the index itself. +#' \cr\cr +#' The `indexTZ()`, `indexClass()`, and `indexFormat()` functions (and their +#' respective replacement methods) will continue to work as in prior \pkg{xts} +#' versions. The attributes on the index take priority over their respective +#' counterparts that may be on the xts object.} +#' +#' \item{Versions 0.6.4 and prior:}{Objects track their timezone and index class +#' in their '.indexTZ' and '.indexCLASS' attributes, respectively.} +#' } +#' +#' @param x An xts object. +#' @param value A new time index value. +#' @param \dots Arguments passed to other methods. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`tformat()`] describes how the index values are formatted when +#' printed, [`tclass()`] documents how \pkg{xts} handles the index class, and +#' [`tzone()`] has more information about index timezone settings. +#' +#' @keywords ts utilities +#' @examples +#' +#' x <- timeBasedSeq('2010-01-01/2010-01-01 12:00/H') +#' x <- xts(seq_along(x), x) +#' +#' # the index values, converted to 'tclass' (POSIXct in this case) +#' index(x) +#' class(index(x)) # POSIXct +#' tclass(x) # POSIXct +#' +#' # the internal numeric index +#' .index(x) +#' # add 1 hour (3600 seconds) to the numeric index +#' .index(x) <- index(x) + 3600 +#' index(x) +#' +#' y <- timeBasedSeq('2010-01-01/2010-01-02 12:00') +#' y <- xts(seq_along(y), y) +#' +#' # Select all observations in the first 6 and last 3 minutes of the +#' # 8th and 15th hours on each day +#' y[.indexhour(y) %in% c(8, 15) & .indexmin(y) %in% c(0:5, 57:59)] +#' +#' i <- 0:60000 +#' focal_date <- as.numeric(as.POSIXct("2018-02-01", tz = "UTC")) +#' y <- .xts(i, c(focal_date + i * 15), tz = "UTC", dimnames = list(NULL, "value")) +#' +#' # Select all observations for the first minute of each hour +#' y[.indexmin(y) == 0] +#' +#' # Select all observations on Monday +#' mon <- y[.indexwday(y) == 1] +#' head(mon) +#' tail(mon) +#' unique(weekdays(index(mon))) # check +#' +#' # Disjoint time of day selections +#' +#' # Select all observations between 08:30 and 08:59:59.9999 or between 12:00 and 12:14:59.99999: +#' y[.indexhour(y) == 8 & .indexmin(y) >= 30 | .indexhour(y) == 12 & .indexmin(x) %in% 0:14] +#' +#' ### Compound selections +#' +#' # Select all observations for Wednesdays or Fridays between 9am and 4pm (exclusive of 4pm): +#' y[.indexwday(y) %in% c(3, 5) & (.indexhour(y) %in% c(9:15))] +#' +#' # Select all observations on Monday between 8:59:45 and 09:04:30: +#' +#' y[.indexwday(y) == 1 & (.indexhour(y) == 8 & .indexmin(y) == 59 & .indexsec(y) >= 45 | +#' .indexhour(y) == 9 & +#' (.indexmin(y) < 4 | .indexmin(y) == 4 & .indexsec(y) <= 30))] +#' +#' i <- 0:30000 +#' u <- .xts(i, c(focal_date + i * 1800), tz = "UTC", dimnames = list(NULL, "value")) +#' +#' # Select all observations for January or February: +#' u[.indexmon(u) %in% c(0, 1)] +#' +#' # Select all data for the 28th to 31st of each month, excluding any Fridays: +#' u[.indexmday(u) %in% 28:31 & .indexwday(u) != 5] +#' +#' # Subset by week since origin +#' unique(.indexweek(u)) +#' origin <- xts(1, as.POSIXct("1970-01-01")) +#' unique(.indexweek(origin)) +#' +#' # Select all observations in weeks 2515 to 2517. +#' u2 <- u[.indexweek(u) %in% 2515:2517] +#' head(u2); tail(u2) +#' +#' # Select all observations after 12pm for day 50 and 51 in each year +#' u[.indexyday(u) %in% 50:51 & .indexhour(u) >= 12] +#' +index.xts <- function(x, ...) { value <- tclass(x) if(is.null(value) || !nzchar(value[1L])) { @@ -68,7 +237,8 @@ function(x, ...) { ) } -`time<-.xts` <- `index<-.xts` <- function(x, value) { +#' @rdname index.xts +`index<-.xts` <- function(x, value) { if(length(index(x)) != length(value)) stop('length of index vectors does not match') if( !timeBased(value) ) @@ -104,12 +274,20 @@ function(x, ...) { return(x) } +#' @rdname index.xts +`time<-.xts` <- `index<-.xts` + +#' @rdname index.xts +time.xts <- index.xts + +#' @rdname index.xts `.index` <- function(x, ...) { if(is.list(attr(x, "index"))) { attr(x, 'index')[[1]] } else attr(x, "index") } +#' @rdname index.xts `.index<-` <- function(x, value) { if(timeBased(value)) { if(inherits(value, 'Date')) { @@ -126,47 +304,82 @@ function(x, ...) { return(x) } +#' @rdname index.xts `.indexsec` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$sec } + +#' @rdname index.xts `.indexmin` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$min } + +#' @rdname index.xts `.indexhour` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$hour } + +#' @rdname index.xts `.indexmday` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$mday } + +#' @rdname index.xts `.indexmon` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$mon } + +#' @rdname index.xts `.indexyear` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$year } + +#' @rdname index.xts `.indexwday` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$wday } + +#' @rdname index.xts `.indexbday` <- function(x) { # is business day T/F as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$wday %% 6 > 0 } + +#' @rdname index.xts `.indexyday` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$yday } + +#' @rdname index.xts `.indexisdst` <- function(x) { as.POSIXlt(.POSIXct(.index(x), tz=tzone(x)))$isdst } -`.indexDate` <- `.indexday` <- function(x) { + +#' @rdname index.xts +`.indexDate` <- function(x) { .index(x) %/% 86400L } + +#' @rdname index.xts +`.indexday` <- .indexDate + +#' @rdname index.xts `.indexweek` <- function(x) { (.index(x) + (3 * 86400)) %/% 86400 %/% 7 } + +#' @rdname index.xts `.indexyweek` <- function(x) { ((.index(x) + (3 * 86400)) %/% 86400 %/% 7) - ((startOfYear() * 86400 + (3 * 86400)) %/% 86400 %/% 7)[.indexyear(x) + 1] } +#' @rdname index.xts +`convertIndex` <- +function(x,value) { + tclass(x) <- value + x +} + .update_index_attributes <- function(x) { suppressWarnings({ tclass(x) <- tclass(x) diff --git a/R/irts.R b/R/irts.R index 9952ee8c..1a5fae04 100644 --- a/R/irts.R +++ b/R/irts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -35,6 +35,7 @@ function(x,...) { irts(index(x),xx) } +#' @rdname as.xts `as.xts.irts` <- function(x,order.by,frequency=NULL,...,.RECLASS=FALSE) { if(.RECLASS) { @@ -52,5 +53,3 @@ function(x,order.by,frequency=NULL,...,.RECLASS=FALSE) { } xx } - - diff --git a/R/isOrdered.R b/R/isOrdered.R index c41454cc..df05393e 100644 --- a/R/isOrdered.R +++ b/R/isOrdered.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,38 @@ # along with this program. If not, see . +#' Check If A Vector Is Ordered +#' +#' Check if a vector is strictly increasing, strictly decreasing, not +#' decreasing, or not increasing. +#' +#' Designed for internal use with \pkg{xts}, this provides highly optimized +#' tests for ordering. +#' +#' @param x A numeric vector. +#' @param increasing Test for increasing (`TRUE`) or decreasing (`FALSE`) values? +#' @param strictly When `TRUE`, vectors with duplicate values are *not* +#' considered ordered. +#' +#' @return A logical scalar indicating whether or not `x` is ordered. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`is.unsorted()`] +#' +#' @keywords misc +#' @examples +#' +#' # strictly increasing +#' isOrdered(1:10, increasing=TRUE) +#' isOrdered(1:10, increasing=FALSE) +#' isOrdered(c(1,1:10), increasing=TRUE) +#' isOrdered(c(1,1:10), increasing=TRUE, strictly=FALSE) +#' +#' # decreasing +#' isOrdered(10:1, increasing=TRUE) +#' isOrdered(10:1, increasing=FALSE) +#' `isOrdered` <- function(x, increasing=TRUE, strictly=TRUE) { # x must be of type double or integer. Checked in the C code. if(is.character(x)) diff --git a/R/lag.xts.R b/R/lag.xts.R index 01586dac..e441d0ce 100644 --- a/R/lag.xts.R +++ b/R/lag.xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,53 +19,7 @@ # along with this program. If not, see . -`Lag.xts` <- function(x, k=1, na.action=na.pass, ...) { - x <- try.xts(x, error=FALSE) - - if(!is.xts(x)) x <- as.matrix(x) - - xx <-sapply(k, - function(k) { - apply(x, 2, - function(x) { - if(k==0) return(as.matrix(x)) - as.matrix(c(rep(NA, k), x[-((length(x) - k + 1):length(x))])) - } - )} - ) - xx <- matrix(as.numeric(xx),nrow=NROW(x)) - colnames(xx) <- c(paste(colnames(x)[(rep(1:NCOL(x),length(k)))], - 'lag', - rep(k, each=NCOL(x)), - sep = ".")) - as.function(na.action)(reclass(xx,x)) -} - - -`Next.xts` <- function(x, k=1, na.action=na.pass, ...) { - x <- try.xts(x, error=FALSE) - - if(!is.xts(x)) x <- as.matrix(x) - - xx <-sapply(k, - function(k) { - apply(x, 2, - function(x) { - if(k==0) return(as.matrix(x)) - as.matrix(c(x[-(1:k)],rep(NA, k))) - } - )} - ) - xx <- matrix(as.numeric(xx),nrow=NROW(x)) - colnames(xx) <- c(paste(colnames(x)[(rep(1:NCOL(x),length(k)))], - 'next', - rep(k, each=NCOL(x)), - sep = ".")) - as.function(na.action)(reclass(xx,x)) - -} - - +#' @rdname diff.xts lag.xts <- function(x, k=1, na.pad=TRUE, ...) { zooCompat <- getOption('xts.compat.zoo.lag') if(is.logical(zooCompat) && zooCompat) { @@ -81,6 +35,7 @@ lag.xts <- function(x, k=1, na.pad=TRUE, ...) { } lagts.xts <- function(x, k=1, na.pad=TRUE, ...) { + # NOTE: not exported if(length(k) > 1) { if(is.null(names(k))) names(k) <- paste("lag",k,sep="") @@ -89,6 +44,59 @@ lagts.xts <- function(x, k=1, na.pad=TRUE, ...) { .Call(C_lag_xts, x, k, na.pad) } +#' Lags and Differences of xts Objects +#' +#' Methods for computing lags and differences on xts objects. This provides +#' similar functionality as the \pkg{zoo} counterparts, but with some different +#' defaults. +#' +#' The primary motivation for these methods was to take advantage of a faster +#' C-level implementation. Another motivation was to make `lag()` behave using +#' standard sign for `k`. Both [`lag.zoo()`] and [`lag.default()`] require a +#' *negative* value for `k` in order to shift a series backward. So `k = 1`, +#' shifts the series *forward* one observation. This is especially confusing +#' because `k = 1` is the default for those functions. When `x` is an xts +#' object, `lag(x, 1)` returns an object where the value at time 't' is the +#' value at time 't-1' in the original object. +#' +#' Another difference is that `na.pad = TRUE` by default, to better reflect the +#' transformation visually and for functions the require positional alignment +#' of data. +#' +#' Set `options(xts.compat.zoo.lag = TRUE)` to use make `lag.xts()` consistent +#' with `lag.zoo()` by reversing the sign of `k` and setting `na.pad = FALSE`. +#' +#' @param x An xts object. +#' @param k Number of periods to shift. +#' @param lag Period to difference over. +#' @param differences Order of differencing. +#' @param arithmetic Should arithmetic or geometric differencing be used? +#' @param log Should (geometric) log differences be returned? +#' @param na.pad Should `NA` be added so the result has the same number of +#' observations as `x`? +#' @param \dots Additional arguments. +#' +#' @return An xts object with the desired lag and/or differencing. +#' +#' @author Jeffrey A. Ryan +#' +#' @references +#' +#' @keywords manip chron +#' @examples +#' +#' x <- xts(1:10, Sys.Date()+1:10) +#' lag(x) # currently using xts-style positive k +#' +#' lag(x, k=2) +#' +#' lag(x, k=-1, na.pad=FALSE) # matches lag.zoo(x, k=1) +#' +#' diff(x) +#' diff(x, lag=1) +#' diff(x, diff=2) +#' diff(diff(x)) +#' diff.xts <- function(x, lag=1, differences=1, arithmetic=TRUE, log=FALSE, na.pad=TRUE, ...) { if(!is.integer(lag) && any(is.na(as.integer(lag)))) diff --git a/R/last.R b/R/last.R index 47ba6a13..b3184b50 100644 --- a/R/last.R +++ b/R/last.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,12 +19,14 @@ # along with this program. If not, see . +#' @rdname first `last` <- function(x,...) { UseMethod("last") } +#' @rdname first `last.default` <- function(x,n=1,keep=FALSE,...) { @@ -72,6 +74,7 @@ function(x,n=1,keep=FALSE,...) } } +#' @rdname first `last.xts` <- function(x,n=1,keep=FALSE,...) { diff --git a/R/list.R b/R/list.R index e1b7842c..d2806482 100644 --- a/R/list.R +++ b/R/list.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/matrix.R b/R/matrix.R index d6bf8ac1..63984e6b 100644 --- a/R/matrix.R +++ b/R/matrix.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -57,6 +57,7 @@ function(x,...) { as.matrix(x,...) } +#' @rdname as.xts `as.xts.matrix` <- function(x,order.by,dateFormat="POSIXct",frequency=NULL,...,.RECLASS=FALSE) { # Should allow 'order.by' to be a vector of dates or a scaler diff --git a/R/merge.R b/R/merge.R index da4ece68..df92c0ac 100644 --- a/R/merge.R +++ b/R/merge.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,85 @@ # along with this program. If not, see . +#' Merge xts Objects +#' +#' Perform merge operations on xts objects by time index. +#' +#' This xts method is compatible with [`merge.zoo()`] but implemented almost +#' entirely in C-level code for efficiency. +#' +#' The function can perform all common database join operations along the time +#' index by setting 'join' to one of the values below. Note that 'left' and +#' 'right' are only implemented for two objects. +#' +#' * outer: full outer (all rows in all objects) +#' * inner: only rows with common indexes in all objects +#' * left: all rows in the first object, and rows from the second object that +#' have the same index as the first object +#' * right: all rows in the second object, and rows from the first object that +#' have the same index as the second object +#' +#' The above join types can also be accomplished by setting 'all' to one of the +#' values below. +#' +#' * outer: `all = TRUE` or `all = c(TRUE, TRUE)` +#' * inner: `all = FALSE` or `all = c(FALSE, FALSE)` +#' * left: `all = c(TRUE, FALSE)` +#' * right: `all = c(FALSE, TRUE)` +#' +#' The result will have the timezone of the leftmost argument if available. Use +#' the 'tzone' argument to override the default behavior. +#' +#' When `retclass = NULL` the joined objects will be split and reassigned +#' silently back to the original environment they are called from. This is for +#' backward compatibility with zoo, but unused by xts. When `retclass = FALSE` +#' the object will be stripped of its class attribute. This is for internal use. +#' +#' See the examples in order to join using an 'all' argument that is the same +#' arguments to join, like you can do with `merge.zoo()`. +#' +#' @param \dots One or more xts objects, or objects coercible to class xts. +#' @param all A logical vector indicating merge type. +#' @param fill Values to be used for missing elements. +#' @param suffixes Suffix to be added to merged column names. +#' @param join Type of database join. One of 'outer', 'inner', 'left', or 'right'. +#' @param retside Which side of the merged object should be returned (2-case only)? +#' @param retclass Either a logical value indicating whether the result should +#' have a 'class' attribute, or the name of the desired class for the result. +#' @param tzone Time zone to use for the merged result. +#' @param drop Not currently used. +#' @param check.names Use [`make.names()`] to ensure column names are vaild \R +#' object names? +#' +#' @return A new xts object containing the appropriate elements of the +#' objects passed in to be merged. +#' +#' @note This is a highly optimized merge, specifically designed for ordered +#' data. The only supported merging is based on the underlying time index. +#' +#' @author Jeffrey A. Ryan +#' +#' @references Merge Join Discussion: +#' +#' +#' @keywords manip utilities +#' @examples +#' +#' (x <- xts(4:10, Sys.Date()+4:10)) +#' (y <- xts(1:6, Sys.Date()+1:6)) +#' +#' merge(x,y) +#' merge(x,y, join='inner') +#' merge(x,y, join='left') +#' merge(x,y, join='right') +#' +#' merge.zoo(zoo(x),zoo(y),zoo(x), all=c(TRUE, FALSE, TRUE)) +#' merge(merge(x,x),y,join='left')[,c(1,3,2)] +#' +#' # zero-width objects (only index values) can be used +#' xi <- xts( , index(x)) +#' merge(y, xi) +#' merge.xts <- function(..., all=TRUE, fill=NA, @@ -147,3 +226,19 @@ merge.xts <- function(..., } else return(x) } + + +#' @rdname merge.xts +cbind.xts <- function(..., all=TRUE, fill=NA, suffixes=NULL) { + merge.xts(..., all=all, fill=fill, suffixes=suffixes) +} + +.merge.xts.scalar <- function(x, length.out, ...) { + if( length.out == 0) + return(vector(storage.mode(x), 0)) + if( length(x) == 1 ) + return(matrix(rep(x, length.out=length.out))) + if( NROW(x) == length.out ) + return(x) + stop("improper length of one or more arguments to merge.xts") +} diff --git a/R/modify.args.R b/R/modify.args.R index af7ef8cc..d9305249 100644 --- a/R/modify.args.R +++ b/R/modify.args.R @@ -58,16 +58,3 @@ modify.args <- function(formals, arglist, ..., dots=FALSE) # return a list (not a pairlist) as.list(.formals) } - -# This is how it is used in quantstrat in applyIndicators() -# # replace default function arguments with indicator$arguments -# .formals <- formals(indicator$name) -# .formals <- modify.args(.formals, indicator$arguments, dots=TRUE) -# # now add arguments from parameters -# .formals <- modify.args(.formals, parameters, dots=TRUE) -# # now add dots -# .formals <- modify.args(.formals, NULL, ..., dots=TRUE) -# # remove ... to avoid matching multiple args -# .formals$`...` <- NULL -# -# tmp_val <- do.call(indicator$name, .formals) diff --git a/R/na.R b/R/na.R index ba815610..ab3b2a4c 100644 --- a/R/na.R +++ b/R/na.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -92,6 +92,43 @@ na.replace <- function(x) { rbind(x,tmp) } + +#' Last Observation Carried Forward +#' +#' \pkg{xts} method replace `NA` with most recent non-NA +#' +#' This is the \pkg{xts} method for the S3 generic `na.locf()`. The primary +#' difference to note is that after the `NA` fill action is carried out, the +#' default it to leave trailing or leading `NA`'s in place. This is different +#' than \pkg{zoo} behavior. +#' +#' @param object An xts object. +#' @param na.rm Logical indicating whether leading/trailing `NA` should be +#' removed. The default is `FALSE` unlike the zoo method. +#' @param fromLast Logical indicating whether observations should be carried +#' backward rather than forward. Default is `FALSE`. +#' @param maxgap Consecutive runs of observations more than 'maxgap' will +#' remain `NA`. See [`na.locf()`][zoo::zoo] for details. +#' @param \dots Unused. +#' +#' @return An object where each `NA` in `object` is replaced by the most recent +#' non-NA prior to it. See [`na.locf()`][zoo::zoo] for details. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`na.locf()`][zoo::zoo] +#' +#' @keywords misc +#' @examples +#' +#' x <- xts(1:10, Sys.Date()+1:10) +#' x[c(1,2,5,9,10)] <- NA +#' +#' x +#' na.locf(x) +#' na.locf(x, fromLast=TRUE) +#' na.locf(x, na.rm=TRUE, fromLast=TRUE) +#' na.locf.xts <- function(object, na.rm=FALSE, fromLast=FALSE, maxgap=Inf, ...) { maxgap <- min(maxgap, NROW(object)) if(length(object) == 0) diff --git a/R/nperiods.R b/R/nperiods.R index 30351d26..c4212006 100644 --- a/R/nperiods.R +++ b/R/nperiods.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,34 +19,84 @@ # along with this program. If not, see . +#' @rdname ndays `nseconds` <- function(x) { length(endpoints(x,on='seconds'))-1 } + +#' @rdname ndays `nminutes` <- function(x) { length(endpoints(x,on='minutes'))-1 } + +#' @rdname ndays `nhours` <- function(x) { length(endpoints(x,on='hours'))-1 } + + +#' Number of Periods in Data +#' +#' Calculate the number of specified periods in a given time series like data +#' object. +#' +#' Essentially a wrapper to `endpoints()` with the appropriate period +#' specified. The result is the number of endpoints found. +#' +#' As a compromise between simplicity and accuracy, the results will always +#' round up to the nearest complete period. Subtract 1 from the result to +#' get the completed periods. +#' +#' For finer grain detail one should call the higher frequency functions. +#' +#' An alternative summary can be found with `periodicity(x)` and +#' `unclass(periodicity(x))`. +#' +#' @param x A time-based object. +#' +#' @return The number of respective periods in `x`. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`endpoints()`] +#' +#' @keywords utilities +#' @examples +#' +#' \dontrun{ +#' getSymbols("QQQQ") +#' +#' ndays(QQQQ) +#' nweeks(QQQQ) +#' } +#' `ndays` <- function(x) { length(endpoints(x,on='days'))-1 } + +#' @rdname ndays `nweeks` <- function(x) { length(endpoints(x,on='weeks'))-1 } + +#' @rdname ndays `nmonths` <- function(x) { length(endpoints(x,on='months'))-1 } + +#' @rdname ndays `nquarters` <- function(x) { length(endpoints(x,on='quarters'))-1 } + +#' @rdname ndays `nyears` <- function(x) { length(endpoints(x,on='years'))-1 diff --git a/R/origin.fix.R b/R/origin.fix.R index 8b3d4c7a..fb1f4058 100644 --- a/R/origin.fix.R +++ b/R/origin.fix.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -43,9 +43,6 @@ as.POSIXct.Date <- function(x, ...) as.Date.POSIXct <- function(x, ...) { as.Date(strftime(x)) -# z <- floor(unclass((x - unclass(as.POSIXct('1970-01-01'))))/86400) -# attr(z, 'tzone') <- NULL -# structure(z, class="Date") } as.POSIXlt.Date <- function(x, ...) @@ -53,21 +50,9 @@ as.POSIXlt.Date <- function(x, ...) as.POSIXlt(as.POSIXct.Date(x)) } -#as.POSIXct.yearmon <- function(x, ...) -#{ -# structure(as.POSIXct("1970-01-01") + unclass(as.Date(x))*86400, -# class=c("POSIXct","POSIXt")) -#} -# -#as.POSIXlt.yearmon <- function(x, ...) -#{ -# as.POSIXlt(xts:::as.POSIXct.yearmon(x)) -#} -# as.POSIXct.dates <- function(x, ...) { # need to implement our own method to correctly handle TZ - #as.POSIXct(as.character(as.POSIXlt(x,tz="GMT"))) structure(as.POSIXct(as.POSIXlt(x, tz="GMT"), tz="GMT"),class=c("POSIXct","POSIXt")) } as.chron.POSIXct <- function(x, ...) diff --git a/R/parse8601.R b/R/parse8601.R index bdca8c4a..b036a943 100644 --- a/R/parse8601.R +++ b/R/parse8601.R @@ -38,10 +38,97 @@ # # Copyright 2009. Jeffrey A. Ryan. All rights reserved. # This is licensed under the GPL version 2 or later +# + +#' Create an ISO8601 string from a time series object +#' +#' This function uses the `start()` and `end()` of a time series object to +#' create an ISO8601 string that spans the time range of the object. +#' +#' This is not exported an therefore not part of the official xts API. +#' +#' @param x A time series object with `start()` and `end()` methods. +#' +#' @return A character vector of length one describing the ISO-style format +#' for the range of a given time series object. +#' +#' @noRd +#' @examples +#' +#' data(sample_matrix) +#' x <- as.xts(sample_matrix) +#' .makeISO8601(x) +#' .makeISO8601 <- function(x) { paste(start(x), end(x), sep = "/") } + +#' Internal ISO 8601:2004(e) Time Parser +#' +#' This function replicates most of the ISO standard for parsing times and +#' time-based ranges in a universally accepted way. The best documentation is +#' the official ISO page as well as the Wikipedia entry for ISO 8601:2004. +#' +#' The basic idea is to create the endpoints of a range, given a string +#' representation. These endpoints are aligned in POSIXct time to the zero +#' second of the day at the beginning, and the 59.9999th second of the 59th +#' minute of the 23rd hour of the final day. +#' +#' For dates prior to the epoch (1970-01-01) the ending time is aligned to the +#' 59.0000 second. This is due to a bug/feature in the \R implementation of +#' `as.POSIXct()` and `mktime0()` at the C-source level. This limits the +#' precision of ranges prior to 1970 to 1 minute granularity with the current +#' \pkg{xts} workaround. +#' +#' Recurring times over multiple days may be specified using the "T" notation. +#' See the examples for details. +#' +#' @param x A character string conforming to the ISO 8601:2004(e) rules. +#' @param start Lower constraint on range. +#' @param end Upper constraint of range +#' @param tz Timezone (tzone) to use internally. +#' +#' @return A two element list with an entry named \sQuote{first.time} and +#' one named \sQuote{last.time}. +#' +#' @note There is no checking done to test for a properly constructed ISO +#' format string. This must be correctly entered by the user. +#' +#' When using durations, it is important to note that the time of the duration +#' specified is not necessarily the same as the realized periods that may be +#' returned when applied to an irregular time series. This is not a bug, it is +#' a standards and implementation gotcha. +#' +#' @author Jeffrey A. Ryan +#' +#' @references \cr +#' +#' +#' @aliases ISO8601 parseISO8601 +#' @rdname parseISO8601 +#' +#' @keywords utilities +#' @examples +#' +#' # the start and end of 2000 +#' .parseISO8601('2000') +#' +#' # the start of 2000 and end of 2001 +#' .parseISO8601('2000/2001') +#' +#' # May 1, 2000 to Dec 31, 2001 +#' .parseISO8601('2000-05/2001') +#' +#' # May 1, 2000 to end of Feb 2001 +#' .parseISO8601('2000-05/2001-02') +#' +#' # Jan 1, 2000 to Feb 29, 2000; note the truncated time on the LHS +#' .parseISO8601('2000-01/02') +#' +#' # 8:30 to 15:00 (used in xts subsetting to extract recurring times) +#' .parseISO8601('T08:30/T15:00') +#' .parseISO8601 <- function(x, start, end, tz="") { # x: character vector of length 1 in ISO8601:2004(e) format # start: optional earliest time diff --git a/R/period.R b/R/period.R index 90b6ba7b..cf9947a6 100644 --- a/R/period.R +++ b/R/period.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,9 +19,28 @@ # along with this program. If not, see . -# optimized periodic apply functions -# -`is.timeBased` <- `timeBased` <- +#' Check if Class is Time-Based +#' +#' Used to verify that the object is one of the known time-based classes in R. +#' Current time-based objects supported are `Date`, `POSIXct`, `chron`, +#' `yearmon`, `yearqtr`, and `timeDate`. +#' +#' @param x Object to test. +#' +#' @return A logical scalar. +#' +#' @author Jeffrey A. Ryan +#' +#' @rdname timeBased +#' @keywords utilities +#' @examples +#' +#' timeBased(Sys.time()) +#' timeBased(Sys.Date()) +#' +#' timeBased(200701) +#' +`is.timeBased` <- function(x) { time.classes <- c("Date", "POSIXt", "chron", "dates", "times", "timeDate", @@ -29,11 +48,60 @@ function(x) { inherits(x, time.classes) } -make.timeBased <- function(x, class='POSIXct', ...) -{ - do.call(class, list(x,...)) -} +#' @rdname timeBased +`timeBased` <- `is.timeBased` + +#' Optimized Calculations By Period +#' +#' Calculate a sum, product, minimum, or maximum for each non-overlapping +#' period specified by `INDEX`. +#' +#' These functions are similar to calling `period.apply()` with the same +#' endpoints and function. There may be slight differences in the results due +#' to numerical accuracy. +#' +#' For xts-coercible objects, an appropriate `INDEX` can be created by a call +#' to `endpoints()`. +#' +#' @param x A univariate data object. +#' @param INDEX A numeric vector of endpoints for each period. +#' +#' @return An xts or zoo object containing the sum, product, minimum, or +#' maximum for each endpoint in `INDEX`. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`endpoints()`], [`period.apply()`] +#' +#' @keywords utilities +#' @rdname period_math +#' @examples +#' +#' x <- c(1, 1, 4, 2, 2, 6, 7, 8, -1, 20) +#' i <- c(0, 3, 5, 8, 10) +#' +#' period.sum(x, i) +#' period.prod(x, i) +#' period.min(x, i) +#' period.max(x, i) +#' +#' data(sample_matrix) +#' y <- sample_matrix[, 1] +#' ep <- endpoints(sample_matrix) +#' +#' period.sum(y, ep) +#' period.sum(as.xts(y), ep) +#' +#' period.prod(y, ep) +#' period.prod(as.xts(y), ep) +#' +#' period.min(y, ep) +#' period.min(as.xts(y), ep) +#' +#' period.max(y, ep) +#' period.max(as.xts(y), ep) +#' `period.sum` <- function(x,INDEX) { if(NCOL(x) > 1) stop("single column data only") @@ -52,6 +120,8 @@ function(x,INDEX) { } tz } + +#' @rdname period_math `period.prod` <- function(x,INDEX) { if(NCOL(x) > 1) stop("single column data only") @@ -70,6 +140,8 @@ function(x,INDEX) { } tz } + +#' @rdname period_math `period.max` <- function(x,INDEX) { if(NCOL(x) > 1) stop("single column data only") @@ -88,6 +160,8 @@ function(x,INDEX) { } tz } + +#' @rdname period_math `period.min` <- function(x,INDEX) { if(NCOL(x) > 1) stop("single column data only") diff --git a/R/period.apply.R b/R/period.apply.R index 031ca44d..ac7eca50 100644 --- a/R/period.apply.R +++ b/R/period.apply.R @@ -42,6 +42,65 @@ function(caller) # RWDataPlyr/R/xts_helperFunctions.R } + +#' Apply Function Over Specified Interval +#' +#' Apply a specified function to data over intervals specified by `INDEX`. The +#' intervals are defined as the observations from `INDEX[k]+1` to `INDEX[k+1]`, +#' for `k = 1:(length(INDEX)-1)`. +#' +#' Similar to the rest of the apply family, `period.apply()` calculates the +#' specified function's value over a subset of data. The primary difference is +#' that `period.apply()` applies the function to non-overlapping intervals of a +#' vector or matrix. +#' +#' Useful for applying functions over an entire data object by any +#' non-overlapping intervals. For example, when `INDEX` is the result of a +#' call to `endpoints()`. +#' +#' `period.apply()` checks that `INDEX` is sorted, unique, starts with 0, and +#' ends with `nrow(x)`. All those conditions are true of vectors returned by +#' `endpoints()`. +#' +#' @param x The data that `FUN` will be applied to. +#' @param INDEX A numeric vector of index breakpoint locations. The vector +#' should begin with 0 and end with `nrow(x)`. +#' @param FUN A function to apply to each interval in `x`. +#' @param \dots Additional arguments for `FUN`. +#' +#' @return An object with `length(INDEX) - 1` observations, assuming `INDEX` +#' starts with 0 and ends with `nrow(x)`. +#' +#' @note When `FUN = mean` the results will contain one column for every +#' column in the input, which is different from other math functions (e.g. +#' `median`, `sum`, `prod`, `sd`, etc.). +#' +#' `FUN = mean` works by column because the default method `stats::mean` +#' previously worked by column for matrices and data.frames. R Core changed the +#' behavior of `mean` to always return one column in order to be consistent +#' with the other math functions. This broke some \pkg{xts} dependencies and +#' `mean.xts()` was created to maintain the original behavior. +#' +#' Using `FUN = mean` will print a message that describes this inconsistency. +#' To avoid the message and confusion, use `FUN = colMeans` to calculate means +#' by column and use `FUN = function(x) mean` to calculate one mean for all the +#' data. Set `options(xts.message.period.apply.mean = FALSE)` to suppress this +#' message. +#' +#' @author Jeffrey A. Ryan, Joshua M. Ulrich +#' +#' @seealso [`endpoints()`] [`apply.monthly()`] +#' +#' @keywords utilities +#' @examples +#' +#' zoo.data <- zoo(rnorm(31)+10,as.Date(13514:13744,origin="1970-01-01")) +#' ep <- endpoints(zoo.data,'weeks') +#' period.apply(zoo.data, INDEX=ep, FUN=function(x) colMeans(x)) +#' period.apply(zoo.data, INDEX=ep, FUN=colMeans) #same +#' +#' period.apply(letters,c(0,5,7,26), paste0) +#' `period.apply` <- function(x, INDEX, FUN, ...) { @@ -73,31 +132,7 @@ function(x, INDEX, FUN, ...) reclass(xx, x[INDEX]) } - -`period.apply.original` <- -function (x, INDEX, FUN, ...) -{ - x <- use.xts(x,error=FALSE) - - if(!is.xts(x)) { - FUN <- match.fun(FUN) - xx <- sapply(1:(length(INDEX) - 1), function(y) { - FUN(x[(INDEX[y] + 1):INDEX[y + 1]], ...) - }) - } else { - FUN <- match.fun(FUN) - new.index <- index(x)[INDEX] - xx <- sapply(1:(length(INDEX) - 1), function(y) { - FUN(x[(INDEX[y] + 1):INDEX[y + 1]], ...) - }) - xx <- xts(xx,new.index) - CLASS(xx) <- CLASS(x) - xtsAttributes(xx) <- xtsAttributes(x) - xx <- reclass(xx) - } - xx -} - +#' @rdname apply.monthly `apply.daily` <- function(x,FUN, ...) { @@ -107,6 +142,8 @@ function(x,FUN, ...) ep <- endpoints(x,'days') period.apply(x,ep,FUN, ...) } + +#' @rdname apply.monthly `apply.weekly` <- function(x,FUN, ...) { @@ -117,6 +154,58 @@ function(x,FUN, ...) period.apply(x,ep,FUN, ...) } + +#' Apply Function over Calendar Periods +#' +#' Apply a specified function to each distinct period in a given time series +#' object. +#' +#' Simple mechanism to apply a function to non-overlapping time periods, e.g. +#' weekly, monthly, etc. Different from rolling functions in that this will +#' subset the data based on the specified time period (implicit in the call), +#' and return a vector of values for each period in the original data. +#' +#' Essentially a wrapper to the \pkg{xts} functions `endpoints()` and +#' `period.apply()`, mainly as a convenience. +#' +#' @param x A time-series object coercible to xts. +#' @param FUN A function to apply to each period. +#' @param \dots Additional arguments to `FUN`. +#' +#' @return A vector of results produced by `FUN`, corresponding to the +#' appropriate periods. +#' +#' @note When `FUN = mean` the results will contain one column for every +#' column in the input, which is different from other math functions (e.g. +#' `median`, `sum`, `prod`, `sd`, etc.). +#' +#' `FUN = mean` works by column because the default method `stats::mean` +#' previously worked by column for matrices and data.frames. R Core changed the +#' behavior of `mean` to always return one column in order to be consistent +#' with the other math functions. This broke some \pkg{xts} dependencies and +#' `mean.xts()` was created to maintain the original behavior. +#' +#' Using `FUN = mean` will print a message that describes this inconsistency. +#' To avoid the message and confusion, use `FUN = colMeans` to calculate means +#' by column and use `FUN = function(x) mean` to calculate one mean for all the +#' data. Set `options(xts.message.period.apply.mean = FALSE)` to suppress this +#' message. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`endpoints()`], [`period.apply()`], [`to.monthly()`] +#' +#' @keywords utilities +#' @examples +#' +#' xts.ts <- xts(rnorm(231),as.Date(13514:13744,origin="1970-01-01")) +#' +#' start(xts.ts) +#' end(xts.ts) +#' +#' apply.monthly(xts.ts,colMeans) +#' apply.monthly(xts.ts,function(x) var(x)) +#' `apply.monthly` <- function(x,FUN, ...) { @@ -127,6 +216,7 @@ function(x,FUN, ...) period.apply(x,ep,FUN, ...) } +#' @rdname apply.monthly `apply.quarterly` <- function(x,FUN, ...) { @@ -137,6 +227,7 @@ function(x,FUN, ...) period.apply(x,ep,FUN, ...) } +#' @rdname apply.monthly `apply.yearly` <- function(x,FUN, ...) { diff --git a/R/periodicity.R b/R/periodicity.R index cb79027b..68bf0189 100644 --- a/R/periodicity.R +++ b/R/periodicity.R @@ -31,6 +31,56 @@ time_frequency <- function(x) { return(res) } + +#' Approximate Series Periodicity +#' +#' Estimate the periodicity of a time-series-like object by calculating the +#' median time between observations in days. +#' +#' A simple wrapper to quickly estimate the periodicity of a given data. +#' Returning an object of type `periodicity`. +#' +#' This calculates the median time difference between observations as a +#' difftime object, the numerical difference, the units of measurement, and the +#' derived scale of the data as a string. +#' +#' The time index currently must be of either a 'Date' or 'POSIXct' class, or +#' or coercible to one of them. +#' +#' The 'scale' component of the result is an estimate of the periodicity of the +#' data in common terms - e.g. 7 day daily data is best described as 'weekly', +#' and would be returned as such. +#' +#' @param x A time-series-like object. +#' @param \dots Unused. +#' +#' @return A 'periodicity' object with the following elements: +#' * the `difftime` object, +#' * frequency: the median time difference between observations +#' * start: the first observation +#' * end: the last observation +#' * units: one of secs, mins, hours, or days +#' * scale: one of seconds, minute, hourly, daily, weekly, monthly, quarterly, or yearly +#' * label: one of second, minute, hour, day, week, month, quarter, year +#' +#' Possible `scale` values are: \sQuote{minute}, \sQuote{hourly}, \sQuote{daily}, +#' \sQuote{weekly}, \sQuote{monthly}, \sQuote{quarterly}, and \sQuote{yearly}. +#' +#' @note This function only attempts to be a *good estimate* for the underlying +#' periodicity. If the series is too short, or has highly irregular periodicity, +#' the return values will not be accurate. That said, it is quite robust and +#' used internally within \pkg{xts}. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`difftime()`] +#' +#' @keywords utilities +#' @examples +#' +#' zoo.ts <- zoo(rnorm(231),as.Date(13514:13744,origin="1970-01-01")) +#' periodicity(zoo.ts) +#' periodicity <- function(x, ...) { if( timeBased(x) ) { if( anyNA(x) ) { @@ -123,52 +173,6 @@ periodicity <- function(x, ...) { class = 'periodicity') } -`periodicity.old` <- -function (x, ...) -{ - if(!is.xts(x)) x <- as.xts(x) - - # convert if necessary to usable format - if(!tclass(x)[[1]] %in% c('Date','POSIXt')) tclass(x) <- "POSIXct" - - # this takes a long time on big data - possibly use some sort of sampling instead??? - p <- median(diff(time(x))) - - if (is.na(p)) - stop("cannot calculate periodicity from one observation") - - p.numeric <- as.numeric(p) - units <- attr(p, "units") - - if (units == "secs") { - scale <- "seconds" - } - if (units == "mins") { - scale <- "minute" - if (p.numeric > 59) - scale <- "hourly" - } - if (units == "hours") { - scale <- "hourly" - } - if (units == "days") { - scale <- "daily" - if (p.numeric > 1) - scale <- "weekly" - if (p.numeric > 7) - scale <- "monthly" - if (p.numeric > 31) - scale <- "quarterly" - if (p.numeric > 91) - scale <- "yearly" - } - - structure(list(difftime = p, frequency = p.numeric, start = index(first(x)), - end = index(last(x)), units = units, scale = scale),class="periodicity") -# class(xx) <- "periodicity" -# xx # used when structure was assigned to xx, useless now, remain until testing is done though -jar -} - `print.periodicity` <- function (x, ...) { diff --git a/R/plot.R b/R/plot.R index 92303af9..ab07ad8f 100644 --- a/R/plot.R +++ b/R/plot.R @@ -213,6 +213,120 @@ isNullOrFalse <- function(x) { # Main plot.xts method. # author: Ross Bennett (adapted from Jeffrey Ryan's chart_Series) + +#' Plotting xts Objects +#' +#' Plotting for xts objects. +#' +#' Possible values for arguments `major.ticks`, `minor.ticks`, and +#' `grid.ticks.on` include \sQuote{auto}, \sQuote{minute}, \sQuote{hours}, +#' \sQuote{days}, \sQuote{weeks}, \sQuote{months}, \sQuote{quarters}, and +#' \sQuote{years}. The default is \sQuote{auto}, which attempts to determine +#' sensible locations from the periodicity and locations of observations. The +#' other values are based on the possible values for the `ticks.on` +#' argument of [`axTicksByTime()`]. +#' +#' @param x A xts object. +#' @param y Not used, always `NULL`. +#' @param \dots Any passthrough arguments for `lines()` and `points()`. +#' @param subset An ISO8601-style subset string. +#' @param panels Character vector of expressions to plot as panels. +#' @param multi.panel Either `TRUE`, `FALSE`, or an integer less than or equal +#' to the number of columns in the data set. When `TRUE`, each column of the +#' data is plotted in a separate panel. When an integer 'n', the data will be +#' plotted in groups of 'n' columns per panel and each group will be plotted +#' in a separate panel. +#' @param col Color palette to use. +#' @param up.col Color for positive bars when `type = "h"`. +#' @param dn.col Color for negative bars when `type = "h"`. +#' @param bg Background color of plotting area, same as in [`par()`]. +#' @param type The type of plot to be drawn, same as in [`plot()`]. +#' @param lty Set the line type, same as in [`par()`]. +#' @param lwd Set the line width, same as in [`par()`]. +#' @param lend Set the line end style, same as in [`par()`]. +#' @param main Main plot title. +#' @param main.timespan Should the timespan of the series be shown in the top +#' right corner of the plot? +#' @param observation.based When `TRUE`, all the observations are equally spaced +#' along the x-axis. When `FALSE` (the default) the observations on the x-axis +#' are spaced based on the time index of the data. +#' @param log Should the y-axis be in log scale? Default `FALSE`. +#' @param ylim The range of the y axis. +#' @param yaxis.same Should 'ylim' be the same for every panel? Default `TRUE`. +#' @param yaxis.left Add y-axis labels to the left side of the plot? +#' @param yaxis.right Add y-axis labels to the right side of the plot? +#' @param yaxis.ticks Desired number of y-axis grid lines. The actual number of +#' grid lines is determined by the `n` argument to [`pretty()`]. +#' @param major.ticks Period specifying locations for major tick marks and labels +#' on the x-axis. See Details for possible values. +#' @param minor.ticks Period specifying locations for minor tick marks on the +#' x-axis. When `NULL`, minor ticks are not drawn. See details for possible +#' values. +#' @param grid.ticks.on Period specifying locations for vertical grid lines. +#' See details for possible values. +#' @param grid.ticks.lwd Line width of the grid. +#' @param grid.ticks.lty Line type of the grid. +#' @param grid.col Color of the grid. +#' @param labels.col Color of the axis labels. +#' @param format.labels Label format to draw lower frequency x-axis ticks and +#' labels passed to [`axTicksByTime()`] +#' @param grid2 Color for secondary x-axis grid. +#' @param legend.loc Places a legend into one of nine locations on the chart: +#' bottomright, bottom, bottomleft, left, topleft, top, topright, right, or +#' center. Default `NULL` does not draw a legend. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' The default, `on = 0`, will add to the active panel. The active panel is +#' defined as the panel on which the most recent action was performed. Note +#' that only the first element of `on` is checked for the default behavior to +#' add to the last active panel. +#' @param extend.xaxis When `TRUE`, extend the x-axis before and/or after the +#' plot's existing time index range, so all of of the time index values of +#' the new series are included in the plot. Default `FALSE`. +#' +#' @author Ross Bennett +#' +#' @seealso [`addSeries()`], [`addPanel()`] +#' +#' @references based on [`chart_Series()`][quantmod::quantmod] in \pkg{quantmod} +#' written by Jeffrey A. Ryan +#' +#' @examples +#' +#' \dontrun{ +#' data(sample_matrix) +#' sample.xts <- as.xts(sample_matrix) +#' +#' # plot the Close +#' plot(sample.xts[,"Close"]) +#' +#' # plot a subset of the data +#' plot(sample.xts[,"Close"], subset = "2007-04-01/2007-06-31") +#' +#' # function to compute simple returns +#' simple.ret <- function(x, col.name){ +#' x[,col.name] / lag(x[,col.name]) - 1 +#' } +#' +#' # plot the close and add a panel with the simple returns +#' plot(sample.xts[,"Close"]) +#' R <- simple.ret(sample.xts, "Close") +#' lines(R, type = "h", on = NA) +#' +#' # add the 50 period simple moving average to panel 1 of the plot +#' library(TTR) +#' lines(SMA(sample.xts[,"Close"], n = 50), on = 1, col = "blue") +#' +#' # add month end points to the chart +#' points(sample.xts[endpoints(sample.xts[,"Close"], on = "months"), "Close"], +#' col = "red", pch = 17, on = 1) +#' +#' # add legend to panel 1 +#' addLegend("topright", on = 1, +#' legend.names = c("Close", "SMA(50)"), +#' lty = c(1, 1), lwd = c(2, 1), +#' col = c("black", "blue", "red")) +#' } +#' plot.xts <- function(x, y=NULL, ..., @@ -513,6 +627,55 @@ plot.xts <- function(x, } # apply a function to the xdata in the xts chob and add a panel with the result + + +#' Add a panel to an existing xts plot +#' +#' Apply a function to the data of an existing xts plot object and plot the +#' result on an existing or new panel. `FUN` should have arguments `x` or `R` +#' for the data of the existing xts plot object to be passed to. All other +#' additional arguments for `FUN` are passed through \dots. +#' +#' @param FUN An xts object to plot. +#' @param main Main title for a new panel if drawn. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' @param type The type of plot to be drawn, same as in [`plot()`]. +#' @param col Color palette to use, set by default to rational choices. +#' @param lty Set the line type, same as in [`par()`]. +#' @param lwd Set the line width, same as in [`par()`]. +#' @param pch The type of plot to be drawn, same as in [`par()`]. +#' @param \dots Additional named arguments passed through to `FUN` and any +#' other graphical passthrough parameters. +#' +#' @seealso [`plot.xts()`], [`addSeries()`] +#' +#' @author Ross Bennett +#' +#' @examples +#' +#' library(xts) +#' data(sample_matrix) +#' sample.xts <- as.xts(sample_matrix) +#' +#' calcReturns <- function(price, method = c("discrete", "log")){ +#' px <- try.xts(price) +#' method <- match.arg(method)[1L] +#' returns <- switch(method, +#' simple = , +#' discrete = px / lag(px) - 1, +#' compound = , +#' log = diff(log(px))) +#' reclass(returns, px) +#' } +#' +#' # plot the Close +#' plot(sample.xts[,"Close"]) +#' # calculate returns +#' addPanel(calcReturns, method = "discrete", type = "h") +#' # Add simple moving average to panel 1 +#' addPanel(rollmean, k = 20, on = 1) +#' addPanel(rollmean, k = 40, col = "blue", on = 1) +#' addPanel <- function(FUN, main="", on=NA, type="l", col=NULL, lty=1, lwd=1, pch=1, ...){ # get the chob and the raw data (i.e. xdata) chob <- current.xts_chob() @@ -545,6 +708,24 @@ addPanel <- function(FUN, main="", on=NA, type="l", col=NULL, lty=1, lwd=1, pch= # Add a time series to an existing xts plot # author: Ross Bennett + + +#' Add a time series to an existing xts plot +#' +#' Add a time series to an existing xts plot +#' +#' @param x An xts object to add to the plot. +#' @param main Main title for a new panel if drawn. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' @param type The type of plot to be drawn, same as in [`plot()`]. +#' @param col Color palette to use, set by default to rational choices. +#' @param lty Set the line type, same as in [`par()`]. +#' @param lwd Set the line width, same as in [`par()`]. +#' @param pch The type of plot to be drawn, same as in [`par()`]. +#' @param \dots Any other passthrough graphical parameters. +#' +#' @author Ross Bennett +#' addSeries <- function(x, main="", on=NA, type="l", col=NULL, lty=1, lwd=1, pch=1, ...){ plot_object <- current.xts_chob() lenv <- plot_object$new_environment() @@ -626,6 +807,9 @@ addSeries <- function(x, main="", on=NA, type="l", col=NULL, lty=1, lwd=1, pch=1 # Add time series of lines to an existing xts plot # author: Ross Bennett + +#' @param pch the plotting character to use, same as in 'par' +#' @rdname plot.xts lines.xts <- function(x, ..., main="", on=0, col=NULL, type="l", lty=1, lwd=1, pch=1){ if(!is.na(on[1])) if(on[1] == 0) on[1] <- current.xts_chob()$get_last_action_panel()$id @@ -635,6 +819,9 @@ lines.xts <- function(x, ..., main="", on=0, col=NULL, type="l", lty=1, lwd=1, p # Add time series of points to an existing xts plot # author: Ross Bennett + +#' @param pch the plotting character to use, same as in 'par' +#' @rdname plot.xts points.xts <- function(x, ..., main="", on=0, col=NULL, pch=1){ if(!is.na(on[1])) if(on[1] == 0) on[1] <- current.xts_chob()$get_last_action_panel()$id @@ -644,6 +831,40 @@ points.xts <- function(x, ..., main="", on=0, col=NULL, pch=1){ # Add vertical lines to an existing xts plot # author: Ross Bennett + + +#' Add vertical lines to an existing xts plot +#' +#' Add vertical lines and labels to an existing xts plot. +#' +#' @param events An xts object of events and their associated labels. It is +#' ensured that the first column of `events` is the event description/label. +#' @param main Main title for a new panel, if drawn. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' The default, `on = 0`, will add to the active panel. The active panel is +#' defined as the panel on which the most recent action was performed. Note +#' that only the first element of `on` is checked for the default behavior to +#' add to the last active panel. +#' @param lty Set the line type, same as in [`par()`]. +#' @param lwd Set the line width, same as in [`par()`]. +#' @param col Color palette to use, set by default to rational choices. +#' @param \dots Any other passthrough parameters to [`text()`] to control how +#' the event labels are drawn. +#' +#' @author Ross Bennett +#' +#' @examples +#' +#' \dontrun{ +#' library(xts) +#' data(sample_matrix) +#' sample.xts <- as.xts(sample_matrix) +#' events <- xts(letters[1:3], +#' as.Date(c("2007-01-12", "2007-04-22", "2007-06-13"))) +#' plot(sample.xts[,4]) +#' addEventLines(events, srt = 90, pos = 2) +#' } +#' addEventLines <- function(events, main="", on=0, lty=1, lwd=1, col=1, ...){ events <- try.xts(events) @@ -663,7 +884,13 @@ addEventLines <- function(events, main="", on=0, lty=1, lwd=1, col=1, ...){ xdata <- x$Env$xdata xsubset <- x$Env$xsubset - ypos <- x$get_panel(on)$ylim[2] * 0.995 + panel <- x$get_active_panel() + if (panel$use_log_yaxis) { + ypos <- log(exp(panel$ylim_render[2]) * 0.995) + } else { + ypos <- panel$ylim_render[2] * 0.995 + } + # we can add points that are not necessarily at the points on the main series subset.range <- paste(format(start(xdata[xsubset]), "%Y%m%d %H:%M:%OS6"), @@ -724,6 +951,28 @@ addEventLines <- function(events, main="", on=0, lty=1, lwd=1, col=1, ...){ # Add legend to an existing xts plot # author: Ross Bennett + + +#' Add Legend +#' +#' Add a legend to an existing panel. +#' +#' @param legend.loc One of nine locations: bottomright, bottom, bottomleft, +#' left, topleft, top, topright, right, or center. +#' @param legend.names Character vector of names for the legend. When `NULL`, +#' the column names of the current plot object are used. +#' @param col Fill colors for the legend. When `NULL`, the colorset of the +#' current plot object data is used. +#' @param ncol Number of columns for the legend. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' The default, `on = 0`, will add to the active panel. The active panel is +#' defined as the panel on which the most recent action was performed. Note +#' that only the first element of `on` is checked for the default behavior to +#' add to the last active panel. +#' @param \dots Any other passthrough parameters to [`legend()`]. +#' +#' @author Ross Bennett +#' addLegend <- function(legend.loc="topright", legend.names=NULL, col=NULL, ncol=1, on=0, ...){ plot_object <- current.xts_chob() @@ -736,7 +985,7 @@ addLegend <- function(legend.loc="topright", legend.names=NULL, col=NULL, ncol=1 if(is.na(on[1])){ yrange <- c(0, 1) } else { - panel <- x$get_panel(on) + panel <- x$get_active_panel() yrange <- panel$ylim_render } # this just gets the data of the main plot @@ -814,6 +1063,43 @@ legend.coords <- function(legend.loc, xrange, yrange) { # Add a polygon to an existing xts plot # author: Ross Bennett + + +#' Add a polygon to an existing xts plot +#' +#' Draw a polygon on an existing xts plot by specifying a time series of y +#' coordinates. The xts index is used for the x coordinates and the first two +#' columns are the upper and lower y coordinates, respectively. +#' +#' @param x An xts object to plot. Must contain 2 columns for the upper and +#' the lower y coordinates for the polygon. The first column is interpreted +#' as upper y coordinates and the second column as the lower y coordinates. +#' @param y `NULL`, not used. +#' @param main Main title for a new panel, if drawn. +#' @param on Panel number to draw on. A new panel will be drawn if `on = NA`. +#' @param col Color palette to use, set by default to rational choices. +#' @param \dots Any other passthrough parameters to [`par()`]. +#' +#' @author Ross Bennett +#' +#' @references Based on code by Dirk Eddelbuettel from +#' +#' +#' @examples +#' +#' \dontrun{ +#' library(xts) +#' data(sample_matrix) +#' x <- as.xts(sample_matrix)[,1] +#' ix <- index(x["2007-02"]) +#' shade <- xts(matrix(rep(range(x), each = length(ix)), ncol = 2), ix) +#' +#' plot(x) +#' +#' # set on = -1 to draw the shaded region *behind* the main series +#' addPolygon(shade, on = -1, col = "lightgrey") +#' } +#' addPolygon <- function(x, y=NULL, main="", on=NA, col=NULL, ...){ # add polygon to xts plot based on http://dirk.eddelbuettel.com/blog/2011/01/16/ @@ -956,7 +1242,8 @@ new.replot_xts <- function(panel=1,asp=1,xlim=c(1,10),ylim=list(structure(c(1,10 if(lim[1L] == 0) { lim <- c(-1, 1) } else { - lim <- lim[1L] * c(1 - const_y_mult, 1 + const_y_mult) + adj <- sign(lim[1L]) * const_y_mult + lim <- lim[1L] * c(1 - adj, 1 + adj) } } @@ -1388,6 +1675,7 @@ new.replot_xts <- function(panel=1,asp=1,xlim=c(1,10),ylim=list(structure(c(1,10 replot_env$get_xlim <- get_xlim replot_env$get_ylim <- get_ylim replot_env$create_ylim <- create_ylim + replot_env$get_active_panel <- get_active_panel replot_env$get_last_action_panel <- get_last_action_panel replot_env$new_environment <- function() { new.env(TRUE, Env) } diff --git a/R/print.R b/R/print.R index dcbdb4dd..8abad481 100644 --- a/R/print.R +++ b/R/print.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -18,6 +18,35 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . + +#' Print An xts Time-Series Object +#' +#' Method for printing an extensible time-series object. +#' +#' @param x An xts object. +#' @param fmt Passed to [`coredata()`] to format the time index. +#' @param \dots Arguments passed to other methods. +#' @param show.rows The number of first and last rows to print if the number of +#' rows is truncated (default 10, or `getOption("xts.print.show.rows")`). +#' @param max.rows The output will contain at most `max.rows` rows before being +#' truncated (default 100, or `getOption("xts.print.max.rows")`). +#' +#' @return Returns `x` invisibly. +#' +#' @author Joshua M. Ulrich +#' +#' @keywords print +#' @examples +#' +#' data(sample_matrix) +#' sample.xts <- as.xts(sample_matrix) +#' +#' # output is truncated and shows first and last 10 observations +#' print(sample.xts) +#' +#' # show the first and last 5 observations +#' print(sample.xts, show.rows = 5) +#' print.xts <- function(x, fmt, diff --git a/R/reclass.R b/R/reclass.R new file mode 100644 index 00000000..c2e4a500 --- /dev/null +++ b/R/reclass.R @@ -0,0 +1,231 @@ +# +# xts: eXtensible time-series +# +# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com +# +# Contributions from Joshua M. Ulrich +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +#' @rdname reclass +#' @aliases use.xts +try.xts <- function(x, ..., error=TRUE) +{ + if(is.xts(x)) { + #attr(x,'.RECLASS') <- FALSE + return(x) + } + + xx <- try(as.xts(x,..., .RECLASS=TRUE),silent=TRUE) + if(inherits(xx,'try-error')) { + if(is.character(error)) { + stop(error) + } else + if(is.function(error)) { + return(error(x, ...)) + } else + if(error) { + stop(gsub('\n','',xx)) + } else { + return(x) + } + } else { + # made positive: now test if needs to be reclassed + structure(xx, .RECLASS=TRUE) + } +} +use.xts <- try.xts + + +#' Convert Objects to xts and Back to Original Class +#' +#' Functions to convert objects of arbitrary classes to xts and then back to +#' the original class, without losing any attributes of the original class. +#' +#' A simple and reliable way to convert many different objects into a uniform +#' format for use within \R. +#' +#' `try.xts()` and `reclass()` are functions that enable external developers +#' access to the reclassing tools within \pkg{xts} to help speed development of +#' time-aware functions, as well as provide a more robust and seemless end-user +#' experience, regardless of the end-user's choice of data-classes. +#' +#' `try.xts()` calls `as.xts()` internally. See [`as.xts()`] for available xts +#' methods and arguments for each coercible class. Since it calls `as.xts()`, +#' you can add custom attributes as `name = value` pairs in the same way. But +#' these custom attributes will not be copied back to the original object when +#' `reclass()` is called. +#' +#' The `error` argument can be a logical value indicating whether an error +#' should be thrown (or fail silently), a character string allowing for custom +#' error error messages, or a function of the form `f(x, ...)` that will be +#' called if the conversion fails. +#' +#' `reclass()` converts an object created by `try.xts()` back to its original +#' class with all the original attributes intact (unless they were changed +#' after the object was converted to xts). The `match.to` argument allows you +#' copy the index attributes ([`tclass`], [`tformat`], and [`tzone`]) and +#' [`xtsAttributes()`] from another xts object to the result. `match.to` must +#' be an xts object with an index value for every observation in `x`. +#' +#' `Reclass()` is designed for top-level use, where it is desirable to have +#' the object returned from an arbitrary function in the same class as the +#' object passed in. Most functions in \R are not designed to return objects +#' matching the original object's class. It attempts to handle conversion and +#' reconversion transparently but it requires the original object must be +#' coercible to xts, the result of the function must have the same number of +#' rows as the input, and the object to be converted/reclassed must be the +#' first argument to the function being wrapped. Note that this function +#' hasn't been tested for robustness. +#' +#' See the accompanying vignette for more details on the above usage. +#' +#' @param x Data object to convert. See details for supported types. +#' @param match.to An xts object whose attributes will be copied to the result. +#' @param error Error handling option. See Details. +#' @param \dots Additional parameters or attributes. +#' +#' @return `try.xts()` returns an xts object when conversion is successful. +#' The `error` argument controls the function's behavior when conversion fails. +#' +#' `Reclass()` and `reclass()` return the object as its original class, as +#' specified by the 'CLASS' attribute. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`as.xts()`] +#' +#' @keywords utilities +#' @examples +#' +#' a <- 1:10 +#' +#' # fails silently, the result is still an integer vector +#' try.xts(a, error = FALSE) +#' +#' # control the result with a function +#' try.xts(a, error = function(x, ...) { "I'm afraid I can't do that." }) +#' +#' z <- zoo(1:10, timeBasedSeq("2020-01-01/2020-01-10")) +#' x <- try.xts(z) # zoo to xts +#' str(x) +#' str(reclass(x)) # reclass back to zoo +#' +`reclass` <- +function(x, match.to, error=FALSE, ...) { + if(!missing(match.to) && is.xts(match.to)) { + if(NROW(x) != length(.index(match.to))) + if(error) { + stop('incompatible match.to attibutes') + } else return(x) + + if(!is.xts(x)) { + x <- .xts(coredata(x), .index(match.to), + tclass = tclass(match.to), + tzone = tzone(match.to), + tformat = tformat(match.to)) + } + attr(x, ".CLASS") <- CLASS(match.to) + xtsAttributes(x) <- xtsAttributes(match.to) + tclass(x) <- tclass(match.to) + tformat(x) <- tformat(match.to) + tzone(x) <- tzone(match.to) + } + oldCLASS <- CLASS(x) + # should this be is.null(oldCLASS)? + if(length(oldCLASS) > 0 && !inherits(oldClass,'xts')) { + if(!is.null(dim(x))) { + if(!is.null(attr(x,'.ROWNAMES'))) { + # rownames<- (i.e. dimnames<-.xts) will not set row names + # force them directly + attr(x, "dimnames")[[1]] <- attr(x,'.ROWNAMES')[1:NROW(x)] + } + } + attr(x,'.ROWNAMES') <- NULL + #if(is.null(attr(x,'.RECLASS')) || attr(x,'.RECLASS')) {#should it be reclassed? + if(isTRUE(attr(x,'.RECLASS'))) {#should it be reclassed? + #attr(x,'.RECLASS') <- NULL + do.call(paste('re',oldCLASS,sep='.'),list(x)) + } else { + #attr(x,'.RECLASS') <- NULL + x + } + } else { + #attr(x,'.RECLASS') <- NULL + x + } +} + +#' @rdname reclass +#' @aliases use.reclass +Reclass <- function(x) { + xx <- match.call() + xxObj <- eval.parent(parse(text=all.vars(xx)[1]), 1) + inObj <- try.xts(xxObj, error=FALSE) + xx <- eval(match.call()[[-1]]) + reclass(xx, inObj) +} +use.reclass <- Reclass + +#' Extract and Set .CLASS Attribute +#' +#' Extraction and replacement functions to access the xts '.CLASS' attribute. +#' The '.CLASS' attribute is used by `reclass()` to transform an xts object +#' back to its original class. +#' +#' This is meant for use in conjunction with `try.xts()` and `reclass()` and is +#' is not intended for daily use. While it's possible to interactively coerce +#' objects to other classes than originally derived from, it's likely to cause +#' unexpected behavior. It is best to use the usual `as.xts()` and other +#' classes' `as` methods. +#' +#' @param x An xts object. +#' @param value The new value to assign to the '.CLASS' attribute. +#' +#' @return Called for its side-effect of changing the '.CLASS' attribute. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`as.xts()`], [`reclass()`] +#' +#' @keywords utilities +`CLASS` <- +function(x) { + cl <- attr(x,'.CLASS') + + if(!is.null(cl)) { + attr(cl, 'class') <- 'CLASS' + return(cl) + } + + return(NULL) +} + +`print.CLASS` <- +function(x,...) { + cat(paste("previous class:",x),"\n") +} + +#' @rdname CLASS +`CLASS<-` <- +function(x,value) { + UseMethod("CLASS<-") +} + +`CLASS<-.xts` <- +function(x,value) { + attr(x,".CLASS") <- value + x +} diff --git a/R/rollapply.xts.R b/R/rollapply.xts.R index 89c5a912..64bcce82 100644 --- a/R/rollapply.xts.R +++ b/R/rollapply.xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -33,19 +33,6 @@ rollapply.xts <- function(data, width, FUN, ..., by=1, by.column=TRUE, # Code taken/adapted from rollapply.zoo from the 'zoo' package -# embedi <- function(n, k, by = 1, ascending = FALSE) { - # n = no of time points, k = number of columns - # by = increment. normally = 1 but if = b calc every b-th point - # ascending If TRUE, points passed in ascending order else descending. - # Note that embed(1:n, k) corresponds to embedi(n, k, by = 1, rev = TRUE) - # e.g. embedi(10, 3) -# s <- seq(1, n-k+1, by) -# lens <- length(s) -# cols <- 1:k -# if(!ascending) cols <- rev(cols) -# matrix(s + rep(cols, rep(lens,k))-1, lens) -# } - # xts doesn't currently have these functions # if(by.column && by == 1 && ascending && length(list(...)) < 1) # switch(deparse(substitute(FUN)), diff --git a/R/sort.xts.R b/R/sort.xts.R deleted file mode 100644 index 4de63ae9..00000000 --- a/R/sort.xts.R +++ /dev/null @@ -1,28 +0,0 @@ -# -# xts: eXtensible time-series -# -# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com -# -# Contributions from Joshua M. Ulrich -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -`sort.xts` <- -function(x, decreasing=FALSE, MARGIN=1, ...) -{ - if(NCOL(x) > 1) { - as.matrix(x)[order(x[,MARGIN],decreasing=decreasing,...),] - } else as.matrix(x)[order(x,decreasing=decreasing,...),] -} diff --git a/R/split.R b/R/split.R index 2359278c..4bf1b8c4 100644 --- a/R/split.R +++ b/R/split.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -18,6 +18,45 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . + +#' Divide into Groups by Time +#' +#' Creates a list of xts objects split along time periods. +#' +#' A quick way to break up a large xts object by standard time periods; e.g. +#' 'months', 'quarters', etc. +#' +#' [`endpoints()`] is used to find the start and end of each period (or +#' k-periods). See that function for valid arguments. +#' +#' The inputs are passed to [`split.zoo()`] when `f` is not a character vector. +#' +#' @param x An xts object. +#' @param f A character vector describing the period to split by. +#' @param drop Ignored by `split.xts()`. +#' @param k Number of periods to aggregate into each split. See details. +#' @param \dots Further arguments passed to other methods. +#' +#' @return A list of xts objects. +#' +#' @note [`aggregate.zoo()`] is more flexible, though not as fast for xts +#' objects. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`endpoints()`], [`split.zoo()`][zoo::zoo], [`aggregate.zoo()`][zoo::zoo] +#' +#' @keywords utilities +#' @examples +#' +#' data(sample_matrix) +#' x <- as.xts(sample_matrix) +#' +#' +#' split(x) +#' split(x, f="weeks") +#' split(x, f="weeks", k=4) +#' split.xts <- function(x, f="months", drop=FALSE, k=1, ...) { if(is.character(f) && length(f) == 1L) { diff --git a/R/start.R b/R/start.R index 7eab3f10..5ba072db 100644 --- a/R/start.R +++ b/R/start.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/startOfYear.R b/R/startOfYear.R index f6dc3ebb..46ba7b5f 100644 --- a/R/startOfYear.R +++ b/R/startOfYear.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/str.R b/R/str.R index a3006fbb..81e1a2f0 100644 --- a/R/str.R +++ b/R/str.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/tclass.R b/R/tclass.R index 2c7132d6..0109e01e 100644 --- a/R/tclass.R +++ b/R/tclass.R @@ -19,23 +19,76 @@ # along with this program. If not, see . -`convertIndex` <- -function(x,value) { - tclass(x) <- value - x -} - +#' Get or Replace the Class of an xts Object's Index +#' +#' Generic functions to get or replace the class of an xts object's index. +#' +#' Internally, an xts object's index is a *numeric* value corresponding to +#' seconds since the epoch in the UTC timezone. The index class is stored as +#' the `tclass` attribute on the internal index. This is used to convert +#' the internal index values to the desired class when the `index` +#' function is called. +#' +#' The `tclass` function retrieves the class of the internal index, and +#' the `tclass<-` function sets it. The specified value for +#' `tclass<-` must be one of the following character strings: +#' `"Date"`, `"POSIXct"`, `"chron"`, `"yearmon"`, +#' `"yearqtr"`, or `"timeDate"`. +#' +#' @param x An xts object. +#' @param value The new index class (see Details for valid values). +#' @param \dots Arguments passed to other methods. +#' +#' @return A vector containing the class of the object's index. +#' +#' @note Both `indexClass` and `indexClass<-` are deprecated in favor +#' of `tclass` and `tclass<-`, respectively. +#' +#' Replacing the `tclass` can *potentially change* the values of the internal +#' index. For example, changing the 'tclass' from POSIXct to Date will +#' truncate the POSIXct value and convert the timezone to UTC (since the Date +#' class doesn't have a timezone). See the examples. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`index()`] has more information on the xts index, [`tformat()`] +#' details how the index values are formatted when printed, and [`tzone()`] +#' has more information about the index timezone settings. +#' +#' The following help pages describe the characteristics of the valid index +#' classes: [`POSIXct()`], [`Date()`], [chron()][chron::chron], +#' [`yearmon()`][zoo::zoo], [`yearqtr()`][zoo::zoo], +#' [`timeDate()`][timeDate::timeDate] +#' +#' @keywords ts utilities +#' @examples +#' +#' x <- timeBasedSeq('2010-01-01/2010-01-02 12:00') +#' x <- xts(seq_along(x), x) +#' +#' y <- timeBasedSeq('2010-01-01/2010-01-03 12:00/H') +#' y <- xts(seq_along(y), y, tzone = "America/New_York") +#' +#' # Changing the tclass *changes* the internal index values +#' head(y) # the index has times +#' head(.index(y)) +#' tclass(y) <- "Date" +#' head(y) # the index prints as a Date +#' head(.index(y)) # the internal index is truncated +#' tclass <- function(x, ...) { UseMethod('tclass') } +#' @rdname tclass tclass.default <- function(x, ...) { attr(x, "tclass") } +#' @rdname tclass tclass.xts <- function(x, ...) { @@ -72,11 +125,13 @@ function(x, ...) return(tclass) } +#' @rdname tclass `tclass<-` <- function(x,value) { UseMethod('tclass<-') } +#' @rdname tclass `tclass<-.default` <- function(x, value) { @@ -87,19 +142,21 @@ function(x, value) x } - +#' @rdname tclass indexClass <- function(x) { .Deprecated("tclass", "xts") tclass(x) } +#' @rdname tclass `indexClass<-` <- function(x, value) { .Deprecated("tclass<-", "xts") `tclass<-`(x, value) } +#' @rdname tclass `tclass<-.xts` <- function(x, value) { if(!is.character(value) && length(value) != 1) diff --git a/R/tformat.R b/R/tformat.R index ec68a0e4..594b42dd 100644 --- a/R/tformat.R +++ b/R/tformat.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,11 +19,55 @@ # along with this program. If not, see . +#' Get or Replace the Format of an xts Object's Index +#' +#' Generic functions to get or replace the format that determines how an xts +#' object's index is printed. +#' +#' Valid values for the `value` argument are the same as specified in the +#' *Details* section of [`strptime()`]. +#' +#' An xts object's `tformat` is `NULL` by default, so the index will be +#' be formatted according to its [`tclass()`] (e.g. Date, POSIXct, timeDate, +#' yearmon, etc.). +#' +#' The `tformat` only changes how the index is *printed* and how the row names +#' are formatted when xts objects are converted to other classes (e.g. matrix +#' or data.frame). It does not affect the internal index in any way. +#' +#' @param x An xts object. +#' @param value New index format string (see [`strptime()`] details for valid +#' values). +#' @param \dots Arguments passed to other methods. +#' +#' @return A vector containing the format for the object's index. +#' +#' @note Both `indexFormat()` and `indexFormat<-` are deprecated in +#' favor of `tformat()` and `tformat<-`, respectively. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`index()`] has more information on the xts index, [`tclass()`] +#' details how \pkg{xts} handles the class of the index, [`tzone()`] has more +#' information about the index timezone settings. +#' +#' @keywords ts utilities +#' @examples +#' +#' x <- timeBasedSeq('2010-01-01/2010-01-02 12:00') +#' x <- xts(seq_along(x), x) +#' +#' # set a custom index format +#' head(x) +#' tformat(x) <- "%Y-%b-%d %H:%M:%OS3" +#' head(x) +#' `tformat` <- function(x, ...) { UseMethod('tformat') } +#' @rdname tformat `tformat<-` <- function(x, value) { UseMethod('tformat<-') @@ -59,12 +103,14 @@ function(x, value) { x } +#' @rdname tformat `indexFormat` <- function(x) { .Deprecated("tformat", "xts") tformat(x) } +#' @rdname tformat `indexFormat<-` <- function(x, value) { .Deprecated("tformat<-", "xts") diff --git a/R/timeBasedRange.R b/R/timeBasedRange.R index 96e4201f..82bda1cf 100644 --- a/R/timeBasedRange.R +++ b/R/timeBasedRange.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,7 @@ # along with this program. If not, see . +#' @rdname timeBasedSeq `timeBasedRange` <- function(x, ...) { # convert unquoted time range to diff --git a/R/timeBasedSeq.R b/R/timeBasedSeq.R index 98f9094d..89fa0c1a 100644 --- a/R/timeBasedSeq.R +++ b/R/timeBasedSeq.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,73 @@ # along with this program. If not, see . +#' Create a Sequence or Range of Times +#' +#' A function to create a vector of time-based objects suitable for indexing an +#' xts object, given a string conforming to the ISO-8601 time and date standard +#' for range-based specification. The resulting series can be of any class +#' supported by xts, including POSIXct, Date, chron, timeDate, yearmon, and +#' yearqtr. +#' +#' `timeBasedRange()` creates a one or two element numeric vector representing +#' the start and end number of seconds since epoch (1970-01-01). For internal +#' use. +#' +#' `timeBasedSeq()` creates sequences of time-based observations using strings +#' formatted according to the ISO-8601 specification. The general format is +#' *from/to/by* or *from::to::by*, where *to* and *by* are optional when the +#' 'length.out' argument is specified. +#' +#' The *from* and *to* elements of the string must be left-specified with +#' respect to the standard *CCYYMMDD HHMMSS* form. All dates/times specified +#' will be set to either the earliest point (from) or the latest (to), to the +#' given the level of specificity. For example, \sQuote{1999} in the *from* +#' field would set the start to the beginning of 1999. \sQuote{1999} in the +#' *to* field would set the end to the end of 1999. +#' +#' The amount of resolution in the result is determined by the resolution of +#' the *from* and *to* component, unless the optional *by* component is +#' specified. +#' +#' For example, `timeBasedSeq("1999/2008")` returns a vector of Dates for +#' January 1st of each year. `timeBasedSeq("199501/1996")` returns a yearmon +#' vector of 24 months in 1995 and 1996. And `timeBasedSeq("19950101/1996")` +#' creates a Date vector for all the days in those two years. +#' +#' The optional *by* field (the third delimited element to the string), will +#' the resolution heuristic described above and will use the specified *by* +#' resolution. The possible values for *by* are: 'Y' (years), 'm' (months), +#' 'd' (days), 'H' (hours), 'M' (minutes), 'S' (seconds). Sub-second +#' resolutions are not supported. +#' +#' @param x An ISO-8601 time-date range string. +#' @param retclass The return class desired. +#' @param length.out Passed to `seq()` internally. +#' @param \dots Unused. +#' +#' @return `timeBasedSeq()` returns a vector of time-based observations. +#' `timeBasedRange()` returns a one or two element numeric vector representing +#' the start and end number of seconds since epoch (1970-01-01). +#' +#' When `retclass = NULL`, the result of `timeBasedSeq()` is a named list +#' containing elements "from", "to", "by" and "length.out". +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`timeBased()`], [`xts()`] +#' +#' @references International Organization for Standardization: ISO 8601 +#' +#' +#' @keywords utilities +#' @examples +#' +#' timeBasedSeq('1999/2008') +#' timeBasedSeq('199901/2008') +#' timeBasedSeq('199901/2008/d') +#' timeBasedSeq('20080101 0830',length=100) # 100 minutes +#' timeBasedSeq('20080101 083000',length=100) # 100 seconds +#' `timeBasedSeq` <- function(x, retclass=NULL, length.out=NULL) { if(!is.character(x)) @@ -111,4 +178,3 @@ function(x, retclass=NULL, length.out=NULL) { do.call(paste('as',convert.to,sep='.'), list(SEQ)) } - diff --git a/R/timeDate.R b/R/timeDate.R index b4b6041f..50d7f671 100644 --- a/R/timeDate.R +++ b/R/timeDate.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,6 +19,7 @@ # along with this program. If not, see . +#' @rdname as.xts as.xts.timeDate <- function(x, ...) { xts(x=NULL, order.by=x) diff --git a/R/timeSeries.R b/R/timeSeries.R index 859f0b25..2eaa32f9 100644 --- a/R/timeSeries.R +++ b/R/timeSeries.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -44,6 +44,7 @@ function(x,...) { documentation=x.attr$documentation,...) } +#' @rdname as.xts `as.xts.timeSeries` <- function(x,dateFormat="POSIXct",FinCenter,recordIDs,title,documentation,..., .RECLASS=FALSE) { @@ -88,5 +89,3 @@ as.timeSeries.xts <- function(x, ...) { timeSeries(data=coredata(x), charvec=as.character(index(x)), ...) } - -`xts.as.timeSeries` <- function(x,...) {} diff --git a/R/toperiod.R b/R/toperiod.R index 7da2d4da..c520bdae 100644 --- a/R/toperiod.R +++ b/R/toperiod.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,17 +19,94 @@ # along with this program. If not, see . -# to.period functionality from quantmod -# -# to.period base function -# to.minutes -# to.hourly -# to.daily -# to.weekly -# to.monthly -# to.quarterly -# to.yearly - +#' Convert time series data to an OHLC series +#' +#' Convert an OHLC or univariate object to a specified periodicity lower than +#' the given data object. For example, convert a daily series to a monthly +#' series, or a monthly series to a yearly one, or a one minute series to an +#' hourly series. +#' +#' The result will contain the open and close for the given period, as well as +#' the maximum and minimum over the new period, reflected in the new high and +#' low, respectively. Aggregate volume will also be calculated if applicable. +#' +#' An easy and reliable way to convert one periodicity of data into any new +#' periodicity. It is important to note that all dates will be aligned to the +#' *end* of each period by default - with the exception of `to.monthly()` and +#' `to.quarterly()`, which use the \pkg{zoo} package's [yearmon][zoo::zoo] and +#' [yearqtr][zoo::zoo] classes, respectively. +#' +#' Valid period character strings include: `"seconds"`, `"minutes"`, `"hours"`, +#' `"days"`, `"weeks"`, `"months"`, `"quarters"`, and `"years"`. These are +#' calculated internally via [`endpoints()`]. See that function's help page for +#' further details. +#' +#' To adjust the final indexing style, it is possible to set `indexAt` to one +#' of the following: \sQuote{yearmon}, \sQuote{yearqtr}, \sQuote{firstof}, +#' \sQuote{lastof}, \sQuote{startof}, or \sQuote{endof}. The final index will +#' then be `yearmon`, `yearqtr`, the first time of the period, the last time +#' of the period, the starting time in the data for that period, or the ending +#' time in the data for that period, respectively. +#' +#' It is also possible to pass a single time series, such as a univariate +#' exchange rate, and return an OHLC object of lower frequency - e.g. the +#' weekly OHLC of the daily series. +#' +#' Setting `drop.time = TRUE` (the default) will convert a series that includes +#' a time component into one with just a date index, since the time component +#' is often of little value in lower frequency series. +#' +#' @param x A univariate or OHLC type time-series object. +#' @param period Period to convert to. See details. +#' @param indexAt Convert final index to new class or date. See details. +#' @param drop.time Remove time component of POSIX datestamp (if any)? +#' @param k Number of sub periods to aggregate on (only for minutes and +#' seconds). +#' @param name Override column names? +#' @param OHLC Should an OHLC object be returned? (only `OHLC = TRUE` +#' currently supported) +#' @param \dots Additional arguments. +#' +#' @return An object of the original type, with new periodicity. +#' +#' @note In order for this function to work properly on OHLC data, it is +#' necessary that the Open, High, Low and Close columns be names as such; +#' including the first letter capitalized and the full spelling found. +#' Internally a call is made to reorder the data into the correct column order, +#' and then a verification step to make sure that this ordering and naming has +#' succeeded. All other data formats must be aggregated with functions such as +#' `aggregate()` and `period.apply()`. +#' +#' This method should work on almost all time-series-like objects. Including +#' \sQuote{timeSeries}, \sQuote{zoo}, \sQuote{ts}, and \sQuote{irts}. It is +#' even likely to work well for other data structures - including +#' \sQuote{data.frames} and \sQuote{matrix} objects. +#' +#' Internally a call to `as.xts()` converts the original `x` into the +#' universal xts format, and then re-converts back to the original type. +#' +#' A special note with respect to \sQuote{ts} objects. As these are strictly +#' regular they may include `NA` values. These are removed before aggregation, +#' though replaced before returning the result. This inevitably leads to many +#' additional `NA` values in the result. Consider using an xts object or +#' converting to xts using `as.xts()`. +#' +#' @author Jeffrey A. Ryan +#' +#' @keywords utilities +#' @aliases to_period +#' @examples +#' +#' data(sample_matrix) +#' +#' samplexts <- as.xts(sample_matrix) +#' +#' to.monthly(samplexts) +#' to.monthly(sample_matrix) +#' +#' str(to.monthly(samplexts)) +#' str(to.monthly(sample_matrix)) +#' to.period <- to_period <- function(x, period='months', k=1, indexAt=NULL, name=NULL, OHLC=TRUE, ...) { if(missing(name)) name <- deparse(substitute(x)) @@ -122,7 +199,7 @@ to.period <- to_period <- function(x, period='months', k=1, indexAt=NULL, name=N reclass(xx,xo) } - +#' @rdname to.period `to.minutes` <- function(x,k,name,...) { @@ -130,42 +207,56 @@ function(x,k,name,...) if(missing(k)) k <- 1 to.period(x,'minutes',k=k,name=name,...) } + +#' @rdname to.period `to.minutes3` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'minutes',k=3,name=name,...) } + +#' @rdname to.period `to.minutes5` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'minutes',k=5,name=name,...) } + +#' @rdname to.period `to.minutes10` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'minutes',k=10,name=name,...) } + +#' @rdname to.period `to.minutes15` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'minutes',k=15,name=name,...) } + +#' @rdname to.period `to.minutes30` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'minutes',k=30,name=name,...) } + +#' @rdname to.period `to.hourly` <- function(x,name,...) { if(missing(name)) name <- deparse(substitute(x)) to.period(x,'hours',name=name,...) } + +#' @rdname to.period `to.daily` <- function(x,drop.time=TRUE,name,...) { @@ -174,6 +265,8 @@ function(x,drop.time=TRUE,name,...) if(drop.time) x <- .drop.time(x) return(x) } + +#' @rdname to.period `to.weekly` <- function(x,drop.time=TRUE,name,...) { @@ -182,6 +275,8 @@ function(x,drop.time=TRUE,name,...) if(drop.time) x <- .drop.time(x) return(x) } + +#' @rdname to.period `to.monthly` <- function(x,indexAt='yearmon',drop.time=TRUE,name,...) { @@ -190,6 +285,8 @@ function(x,indexAt='yearmon',drop.time=TRUE,name,...) if(drop.time) x <- .drop.time(x) return(x) } + +#' @rdname to.period `to.quarterly` <- function(x,indexAt='yearqtr',drop.time=TRUE,name,...) { @@ -198,6 +295,8 @@ function(x,indexAt='yearqtr',drop.time=TRUE,name,...) if(drop.time) x <- .drop.time(x) return(x) } + +#' @rdname to.period `to.yearly` <- function(x,drop.time=TRUE,name,...) { @@ -206,6 +305,7 @@ function(x,drop.time=TRUE,name,...) if(drop.time) x <- .drop.time(x) return(x) } + `.drop.time` <- function(x) { # function to remove HHMMSS portion of time index @@ -229,6 +329,7 @@ function(x) { else reclass(x) # if input wasn't xts, but could be converted } else x # if input wasn't xts, and couldn't be converted } + `by.period` <- function(x, FUN, on=Cl, period="days", k=1, fill=na.locf, ...) { # aggregate 'x' to a higher periodicity, apply 'FUN' to the 'on' columns @@ -243,6 +344,7 @@ function(x, FUN, on=Cl, period="days", k=1, fill=na.locf, ...) { full <- fill(full) # Allow function or value return(full) } + `to.frequency` <- function(x, by, k=1, name=NULL, OHLC=TRUE, ...) { # similar to to.period, but aggregates on something other than time. @@ -259,17 +361,6 @@ function(x, by, k=1, name=NULL, OHLC=TRUE, ...) { warning("missing values removed from data") } -# if(!OHLC) { -# xx <- x[endpoints(x, period, k),] -# } else { -# if(!is.null(indexAt)) { -# index_at <- switch(indexAt, -# "startof" = TRUE, # start time of period -# "endof" = FALSE, # end time of period -# FALSE -# ) -# } else index_at <- FALSE - # make suitable name vector cnames <- c("Open", "High", "Low", "Close") diff --git a/R/ts.R b/R/ts.R index 203f7393..f122d004 100644 --- a/R/ts.R +++ b/R/ts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -21,20 +21,6 @@ # methods for handling ts <--> xts -#`re.ts2` <- -#function(x,...) { -# # attempt to provide a more robust reclass 'ts' method -# na.replace <- function(x) { -# na.removed <- attr(x,'na.action') -# if(class(na.removed) != 'omit') return() -# nrows <- NROW(x) -# xx <- vector('numeric',length=(nrows+length(na.removed))) -# xx[ na.removed,] <- NA -# xx[-na.removed] <- x -# xx -# } -#} - `re.ts` <- function(x,...) { # major issue with quick reclass. Basically fails on data < 1970... @@ -51,6 +37,7 @@ function(x,...) { as.ts(x) } +#' @rdname as.xts `as.xts.ts` <- function(x,dateFormat,...,.RECLASS=FALSE) { x.mat <- structure(as.matrix(x),dimnames=dimnames(x)) diff --git a/R/tzone.R b/R/tzone.R index 767f3490..90a0d00b 100644 --- a/R/tzone.R +++ b/R/tzone.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -18,21 +18,93 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +#' @rdname tzone indexTZ <- function(x, ...) { .Deprecated("tzone", "xts") tzone(x, ...) } + +#' Get or Replace the Timezone of an xts Object's Index +#' +#' Generic functions to get or replace the timezone of an xts object's index. +#' +#' Internally, an xts object's index is a *numeric* value corresponding to +#' seconds since the epoch in the UTC timezone. When an xts object is created, +#' all time index values are converted internally to [`POSIXct()`] +#' (which is also in seconds since the UNIX epoch), using the underlying OS +#' conventions and the \env{TZ} environment variable. The `xts()` function +#' manages timezone information as transparently as possible. +#' +#' The `tzone<-` function *does not* change the internal index values +#' (i.e. the index will remain the same time in the UTC timezone). +#' +#' @param x An xts object. +#' @param value A valid timezone value (see [`OlsonNames()`]). +#' @param \dots Arguments passed to other methods. +#' +#' @return A one element named vector containing the timezone of the object's +#' index. +#' +#' @note Both `indexTZ()` and `indexTZ<-` are deprecated in favor of +#' `tzone()` and `tzone<-`, respectively. +#' +#' Problems may arise when an object that had been created under one timezone +#' are used in a session using another timezone. This isn't usually a issue, +#' but when it is a warning is given upon printing or subsetting. This warning +#' may be suppressed by setting `options(xts_check_TZ = FALSE)`. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`index()`] has more information on the xts index, [`tformat()`] +#' describes how the index values are formatted when printed, and [`tclass()`] +#' provides details how \pkg{xts} handles the class of the index. +#' +#' @keywords ts utilities +#' @examples +#' +#' # Date indexes always have a "UTC" timezone +#' x <- xts(1, Sys.Date()) +#' tzone(x) +#' str(x) +#' print(x) +#' +#' # The default 'tzone' is blank -- your machine's local timezone, +#' # determined by the 'TZ' environment variable. +#' x <- xts(1, Sys.time()) +#' tzone(x) +#' str(x) +#' +#' # now set 'tzone' to different values +#' tzone(x) <- "UTC" +#' str(x) +#' +#' tzone(x) <- "America/Chicago" +#' str(x) +#' +#' y <- timeBasedSeq('2010-01-01/2010-01-03 12:00/H') +#' y <- xts(seq_along(y), y, tzone = "America/New_York") +#' +#' # Changing the tzone does not change the internal index values, but it +#' # does change how the index is printed! +#' head(y) +#' head(.index(y)) +#' tzone(y) <- "Europe/London" +#' head(y) # the index prints with hours, but +#' head(.index(y)) # the internal index is not changed! +#' tzone <- function(x, ...) { UseMethod("tzone") } +#' @rdname tzone `indexTZ<-` <- function(x, value) { .Deprecated("tzone<-", "xts") `tzone<-`(x, value) } +#' @rdname tzone `tzone<-` <- function(x, value) { UseMethod("tzone<-") } diff --git a/R/utils.R b/R/utils.R index 04b7ab96..3a1cd062 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # diff --git a/R/write.xts.R b/R/write.xts.R deleted file mode 100644 index e2a047df..00000000 --- a/R/write.xts.R +++ /dev/null @@ -1,44 +0,0 @@ -# -# xts: eXtensible time-series -# -# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com -# -# Contributions from Joshua M. Ulrich -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -`write.xts` <- -function(x) { - NC <- NCOL(x) - NR <- NROW(x) - DAT <- c(NC,NR) - x <- c(.index(x), as.numeric(x)) - offset <- 0 - for(i in 1:(NC+1)) { - end <- seq(i+offset*NR, length.out=NR)-offset - DAT <- c(DAT, c(x[end[1]], diff(x[end]))) - offset <- offset + 1 - } - DAT -} - -`read.xts` <- -function(x) { - NC <- x[1] - NR <- x[2] - x <- x[-c(1:2)] - .xts(apply(matrix(x[-(1:NR)], ncol=NC),2,cumsum), cumsum(x[1:NR])) -} - diff --git a/R/xts-package.R b/R/xts-package.R new file mode 100644 index 00000000..2f0a5852 --- /dev/null +++ b/R/xts-package.R @@ -0,0 +1,176 @@ +# +# xts: eXtensible time-series +# +# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com +# +# Contributions from Joshua M. Ulrich +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +#' Sample Data Matrix For xts Example and Unit Testing +#' +#' Simulated 180 observations on 4 variables. +#' +#' @usage data(sample_matrix) +#' +#' @format \preformatted{The format is: +#' num [1:180, 1:4] 50.0 50.2 50.4 50.4 50.2 ... +#' - attr(*, "dimnames")=List of 2 +#' ..$ : chr [1:180] "2007-01-02" "2007-01-03" "2007-01-04" "2007-01-05" ... +#' ..$ : chr [1:4] "Open" "High" "Low" "Close" } +#' +#' @rdname sample.data +#' @keywords datasets +#' @examples +#' +#' data(sample_matrix) +#' +"sample_matrix" + + +#' Internal Documentation +#' +#' This help file is to help in development of xts, as well as provide some +#' clarity and insight into its purpose and implementation. +#' +#' Last modified: 2008-08-06 by Jeffrey A. Ryan Version: 0.5-0 and above +#' +#' The \pkg{xts} package xts designed as a drop-in replacement for the very +#' popular \pkg{zoo} package. Most all functionality of zoo has been extended +#' or carries into the xts package. +#' +#' Notable changes in direction include the use of time-based indexing, at +#' first explicitely, now implicitely. +#' +#' An xts object consists of data in the form of a matrix, an index - +#' ordered and increasing, either numeric or integer, and additional attributes +#' for use internally, or for end-user purposes. +#' +#' The current implementation enforces two major rules on the object. One is +#' that the index must be coercible to numeric, by way of `as.POSIXct`. +#' There are defined types that meet this criteria. See `timeBased` for +#' details. +#' +#' The second requirement is that the object cannot have rownames. The +#' motivation from this comes in part from the work Matthew Doyle has done in +#' his data.table class, in the package of the same name. Rownames in must be +#' character vectors, and as such are inefficient in both storage and +#' conversion. By eliminating the rownames, and providing a numeric index of +#' internal type `REAL` or `INTEGER`, it is possible to maintain a +#' connection to standard date and time classes via the POSIXct functions, +#' while at at the same time maximizing efficiencies in data handling. +#' +#' User level functions `index`, as well as conversion to other classes +#' proceeds as if there were rownames. The code for `index` automatically +#' converts time to numeric in both extraction and replacement functionality. +#' This provides a level of abstraction to facilitate internal, and external +#' package use and inter-operability. +#' +#' There is also new work on providing a C-level API to some of the xts +#' functionality to facilitate external package developers to utilize the fast +#' utility routines such as subsetting and merges, without having to call only +#' from . Obviously this places far more burden on the developer to not only +#' understand the internal xts implementation, but also to understand all of +#' what is documented for R-internals (and much that isn't). At present the +#' functions and macros available can be found in the \sQuote{xts.h} file in +#' the src directory. +#' +#' There is no current documentation for this API. The adventure starts here. +#' Future documentation is planned, not implemented. +#' +#' @name xts-internals +#' @author Jeffrey A. Ryan +#' @keywords utilities +NULL + + +#' xts: extensible time-series +#' +#' Extensible time series class and methods, extending and behaving like zoo. +#' +#' Easily convert one of \R's many time-series (and non-time-series) classes to a +#' true time-based object which inherits all of zoo's methods, while allowing +#' for new time-based tools where appropriate. +#' +#' Additionally, one may use \pkg{xts} to create new objects which can contain +#' arbitrary attributes named during creation as name=value pairs. +#' +#' @name xts-package +#' @author Jeffrey A. Ryan and Joshua M. Ulrich +#' +#' Maintainer: Joshua M. Ulrich +#' @seealso [`xts()`], [`as.xts()`], [`reclass()`], [`zoo()`][zoo::zoo] +#' @keywords package +"_PACKAGE" + + +#' xts C API Documentation +#' +#' This help file is to help in development of xts, as well as provide some +#' clarity and insight into its purpose and implementation. +#' +#' By Jeffrey A. Ryan, Dirk Eddelbuettel, and Joshua M. Ulrich Last modified: +#' 2018-05-02 Version: 0.10-3 and above +#' +#' At present the \pkg{xts} API has publicly available interfaces to the +#' following functions (as defined in `xtsAPI.h`): +#' +#' \preformatted{Callable from other R packages: +#' SEXP xtsIsOrdered(SEXP x, SEXP increasing, SEXP strictly) +#' SEXP xtsNaCheck(SEXP x, SEXP check) +#' SEXP xtsTry(SEXP x) +#' SEXP xtsRbind(SEXP x, SEXP y, SEXP dup) +#' SEXP xtsCoredata(SEXP x) +#' SEXP xtsLag(SEXP x, SEXP k, SEXP pad) +#' +#' Internal use functions: +#' SEXP isXts(SEXP x) +#' void copy_xtsAttributes(SEXP x, SEXP y) +#' void copy_xtsCoreAttributes(SEXP x, SEXP y) +#' +#' Internal use macros: +#' xts_ATTRIB(x) +#' xts_COREATTRIB(x) +#' GET_xtsIndex(x) +#' SET_xtsIndex(x,value) +#' GET_xtsIndexFormat(x) +#' SET_xtsIndexFormat(x,value) +#' GET_xtsCLASS(x) +#' SET_xtsCLASS(x,value) +#' +#' Internal use SYMBOLS: +#' xts_IndexSymbol +#' xts_ClassSymbol +#' xts_IndexFormatSymbol +#' +#' Callable from R: +#' SEXP mergeXts(SEXP args) +#' SEXP rbindXts(SEXP args) +#' SEXP tryXts(SEXP x) +#' } +#' +#' @name xtsAPI +#' @author Jeffrey A. Ryan +#' @keywords utilities +#' @examples +#' +#' \dontrun{ +#' # some example code to look at +#' +#' file.show(system.file('api_example/README', package="xts")) +#' file.show(system.file('api_example/src/checkOrder.c', package="xts")) +#' } +#' +NULL diff --git a/R/xts.R b/R/xts.R index 2fdfd552..26025530 100644 --- a/R/xts.R +++ b/R/xts.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,19 +19,6 @@ # along with this program. If not, see . -# xts core functions -# additional methods are in correspondingly named .R files -# current conversions include: -# timeSeries, its, irts, ts, matrix, data.frame, and zoo -# MISSING: tis, fame -# -# this file includes the main xts constructor as well as the reclass -# function. -# -# xts methods (which match foreign conversion methods in other files) -# are also defined below - - # xts() index attribute precedence should be: # 1. .index* value (e.g. .indexTZ) # backward compatibility # 2. t* value (e.g. tzone) # current function to override index attribute @@ -45,6 +32,127 @@ # has always set the tclass to POSIXct by default, whether or not the 'index' # argument already had a tclass attribute. + +#' Create or Test For An xts Time-Series Object +#' +#' Constructor function for creating an extensible time-series object. +#' +#' `xts()` is used to create an xts object from raw data inputs. The xts class +#' inherits from and extends the zoo class, which means most zoo functions can +#' be used on xts objects. +#' +#' The `xts()` constructor is the preferred way to create xts objects. It +#' performs several checks to ensure it returns a well-formed xts object. The +#' `.xts()` constructor is mainly for internal use. It is more efficient then +#' the regular `xts()` constructor because it doesn't perform as many validity +#' checks. Use it with caution. +#' +#' Similar to zoo objects, xts objects must have an ordered index. While zoo +#' indexes cannot contain duplicate values, xts objects have optionally +#' supported duplicate index elements since version 0.5-0. The xts class has +#' one additional requirement: the index must be a time-based class. Currently +#' supported classes include: \sQuote{Date}, \sQuote{POSIXct}, \sQuote{timeDate}, +#' as well as \sQuote{yearmon} and \sQuote{yearqtr} where the index values +#' remain unique. +#' +#' The uniqueness requirement was relaxed in version 0.5-0, but is still +#' enforced by default. Setting `unique = FALSE` skips the uniqueness check and +#' only ensures that the index is ordered via the `isOrdered()` function. +#' +#' As of version 0.10-0, xts no longer allows missing values in the index. This +#' is because many xts functions expect all index values to be finite. The most +#' important of these is `merge.xts()`, which is used ubiquitously. Missing +#' values in the index are usually the result of a date-time conversion error +#' (e.g. incorrect format, non-existent time due to daylight saving time, etc.). +#' Because of how non-finite numbers are represented, a missing timestamp will +#' always be at the end of the index (except if it is `-Inf`, which will be +#' first). +#' +#' Another difference from \pkg{zoo} is that xts object may carry additional +#' attributes that may be desired in individual time-series handling. This +#' includes the ability to augment the objects data with meta-data otherwise +#' not cleanly attachable to a standard zoo object. These attributes may be +#' assigned and extracted via [`xtsAttributes()`] and [`xtsAttributes<-`], +#' respectively. +#' +#' Examples of usage from finance may include the addition of data for keeping +#' track of sources, last-update times, financial instrument descriptions or +#' details, etc. +#' +#' The idea behind \pkg{xts} is to offer the user the ability to utilize a +#' standard zoo object, while providing an mechanism to customize the object's +#' meta-data, as well as create custom methods to handle the object in a manner +#' required by the user. +#' +#' Many xts-specific methods have been written to better handle the unique +#' aspects of xts. These include, subsetting (`[`), `merge()`, `cbind()`, +#' `rbind()`, `c()`, math and logical operations, `lag()`, `diff()`, +#' `coredata()`, `head()`, and `tail()`. There are also xts-specific methods +#' for converting to/from R's different time-series classes. +#' +#' Subsetting via `[` methods offers the ability to specify dates by range, if +#' they are enclosed in quotes. The style borrows from python by creating +#' ranges separated by a double colon \dQuote{"::"} or \dQuote{"/"}. Each side +#' of the range may be left blank, which would then default to the start and +#' end of the data, respectively. To specify a subset of times, it is only +#' required that the time specified be in standard ISO format, with some form +#' of separation between the elements. The time must be *left-filled*, that is +#' to specify a full year one needs only to provide the year, a month requires +#' the full year and the integer of the month requested - e.g. '1999-01'. This +#' format would extend all the way down to seconds - e.g. '1999-01-01 08:35:23'. +#' Leading zeros are not necessary. See the examples for more detail. +#' +#' Users may also extend the xts class to new classes to allow for method +#' overloading. +#' +#' Additional benefits derive from the use of [`as.xts()`] and [`reclass()`], +#' which allow for lossless two-way conversion between common R time-series +#' classes and the xts object structure. See those functions for more detail. +#' +#' @param x An object containing the underlying data. +#' @param order.by A corresponding vector of dates/times of a known time-based +#' class. See Details. +#' @param index A corresponding *numeric* vector specified as seconds since +#' the UNIX epoch (1970-01-01 00:00:00.000). +#' @param frequency Numeric value indicating the frequency of `order.by`. See +#' details. +#' @param unique Can the index only include unique timestamps? Ignored when +#' `check = FALSE`. +#' @param check Must the index be ordered? The index cannot contain duplicates +#' when `check = TRUE` and `unique = TRUE`. +#' @param tclass Time class to use for the index. See [`tclass()`]. +#' @param tzone Time zone of the index (ignored for indices without a time +#' component, e.g. Date, yearmon, yearqtr). See [`tzone()`]. +#' @param \dots Additional attributes to be added. See details. +#' +#' @return An S3 object of class xts. +#' +#' @author Jeffrey A. Ryan and Joshua M. Ulrich +#' +#' @seealso [`as.xts()`], [`index()`], [`tclass()`], [`tformat()`], [`tzone()`], +#' [`xtsAttributes()`] +#' +#' @references \pkg{zoo} +#' +#' @keywords utilities +#' @examples +#' +#' data(sample_matrix) +#' sample.xts <- as.xts(sample_matrix, descr='my new xts object') +#' +#' class(sample.xts) +#' str(sample.xts) +#' +#' head(sample.xts) # attribute 'descr' hidden from view +#' attr(sample.xts,'descr') +#' +#' sample.xts['2007'] # all of 2007 +#' sample.xts['2007-03/'] # March 2007 to the end of the data set +#' sample.xts['2007-03/2007'] # March 2007 to the end of 2007 +#' sample.xts['/'] # the whole data set +#' sample.xts['/2007'] # the beginning of the data through 2007 +#' sample.xts['2007-01-03'] # just the 3rd of January 2007 +#' `xts` <- function(x=NULL, order.by=index(x), @@ -175,6 +283,8 @@ function(x=NULL, x } + +#' @rdname xts `.xts` <- function(x=NULL, index, tclass=c("POSIXct","POSIXt"), tzone=Sys.getenv("TZ"), @@ -284,81 +394,7 @@ function(x=NULL, index, tclass=c("POSIXct","POSIXt"), xx } -`reclass` <- -function(x, match.to, error=FALSE, ...) { - if(!missing(match.to) && is.xts(match.to)) { - if(NROW(x) != length(.index(match.to))) - if(error) { - stop('incompatible match.to attibutes') - } else return(x) - - if(!is.xts(x)) { - x <- .xts(coredata(x), .index(match.to), - tclass = tclass(match.to), - tzone = tzone(match.to), - tformat = tformat(match.to)) - } - attr(x, ".CLASS") <- CLASS(match.to) - xtsAttributes(x) <- xtsAttributes(match.to) - tclass(x) <- tclass(match.to) - tformat(x) <- tformat(match.to) - tzone(x) <- tzone(match.to) - } - oldCLASS <- CLASS(x) - # should this be is.null(oldCLASS)? - if(length(oldCLASS) > 0 && !inherits(oldClass,'xts')) { - if(!is.null(dim(x))) { - if(!is.null(attr(x,'.ROWNAMES'))) { - # rownames<- (i.e. dimnames<-.xts) will not set row names - # force them directly - attr(x, "dimnames")[[1]] <- attr(x,'.ROWNAMES')[1:NROW(x)] - } - } - attr(x,'.ROWNAMES') <- NULL - #if(is.null(attr(x,'.RECLASS')) || attr(x,'.RECLASS')) {#should it be reclassed? - if(isTRUE(attr(x,'.RECLASS'))) {#should it be reclassed? - #attr(x,'.RECLASS') <- NULL - do.call(paste('re',oldCLASS,sep='.'),list(x)) - } else { - #attr(x,'.RECLASS') <- NULL - x - } - } else { - #attr(x,'.RECLASS') <- NULL - x - } -} - -#`reclass` <- reclass2 - -`CLASS` <- -function(x) { - cl <- attr(x,'.CLASS') - - if(!is.null(cl)) { - attr(cl, 'class') <- 'CLASS' - return(cl) - } - - return(NULL) -} - -`print.CLASS` <- -function(x,...) { - cat(paste("previous class:",x),"\n") -} - -`CLASS<-` <- -function(x,value) { - UseMethod("CLASS<-") -} - -`CLASS<-.xts` <- -function(x,value) { - attr(x,".CLASS") <- value - x -} - +#' @rdname xts `is.xts` <- function(x) { inherits(x,'xts') && @@ -366,12 +402,69 @@ function(x) { !is.null(tclass(x)) } + +#' Convert Objects To and From xts +#' +#' Conversion S3 methods to coerce data objects of arbitrary classes to xts +#' and back, without losing any attributes of the original format. +#' +#' A simple and reliable way to convert many different objects into a uniform +#' format for use within \R. +#' +#' `as.xts()` can convert objects of the following classes into an xts object: +#' object: [timeSeries][timeSeries::timeSeries], [ts], [matrix], [data.frame], +#' and [zoo]. `xtsible()` safely checks whether an object can be converted to +#' an xts object. +#' +#' Additional `name = value` pairs may be passed to the function to be added to +#' the new object. A special [`print.xts()`] method ensures the attributes are +#' hidden from view, but will be available via \R's standard `attr()` function, +#' as well as the [`xtsAttributes()`] function. +#' +#' When `.RECLASS = TRUE`, the returned xts object internally preserves all +#' relevant attribute/slot data from the input `x`. This allows for temporary +#' conversion to xts in order to use zoo and xts compatible methods. See +#' [`reclass()`] for details. +#' +#' @param x Data object to convert. See details for supported types. +#' @param dateFormat What class should the dates be converted to? +#' @param FinCenter,recordIDs,title,documentation See [timeSeries][timeSeries::timeSeries] help. +#' @param order.by,frequency See [zoo][zoo::zoo] help. +#' @param \dots Additional parameters or attributes. +#' @param .RECLASS Should the conversion be reversible via [`reclass()`]? +#' +#' @return An S3 object of class xts. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`xts()`], [`reclass()`], [`zoo()`][zoo::zoo] +#' +#' @keywords utilities +#' @examples +#' +#' \dontrun{ +#' # timeSeries +#' library(timeSeries) +#' x <- timeSeries(1:10, 1:10) +#' +#' str(as.xts(x)) +#' str(reclass(as.xts(x))) +#' str(try.xts(x)) +#' str(reclass(try.xts(x))) +#' } +#' `as.xts` <- function(x,...) { UseMethod('as.xts') } -#as.xts.default <- function(x, ...) x +#' @rdname as.xts +xtsible <- function(x) +{ + if(inherits(try(as.xts(x),silent=TRUE),'try-error')) { + FALSE + } else TRUE +} `re.xts` <- function(x,...) { @@ -400,8 +493,3 @@ function(x,...,.RECLASS=FALSE) { } xx } - -`xts.to.xts` <- -function(x,...) { - return(x) -} diff --git a/R/xts.methods.R b/R/xts.methods.R index c6f2878f..a273d8bf 100644 --- a/R/xts.methods.R +++ b/R/xts.methods.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -103,7 +103,155 @@ .Call(C__do_subset_xts, x, i, j, FALSE) } -`.subset.xts` <- `[.xts` <- + +#' Extract Subsets of xts Objects +#' +#' Details on efficient subsetting of xts objects for maximum performance +#' and compatibility. +#' +#' One of the primary motivations and key points of differentiation of xts is +#' the ability to subset rows by specifying ISO-8601 compatible range strings. +#' This allows for natural range-based time queries without requiring prior +#' knowledge of the underlying class used for the time index. +#' +#' When `i` is a character string, it is processed as an ISO-8601 formatted +#' datetime or time range using [`.parseISO8601()`]. A single datetime is +#' parsed from left to to right, according to the following specification: +#' +#' CCYYMMDD HH:MM:SS.ss+ +#' +#' A time range can be specified by two datetimes separated by a forward slash +#' or double-colon. For example: +#' +#' CCYYMMDD HH:MM:SS.ss+/CCYYMMDD HH:MM:SS.ss +#' +#' The ISO8601 time range subsetting uses a custom binary search algorithm to +#' efficiently find the beginning and end of the time range. `i` can also be a +#' vector of ISO8601 time ranges, which enables subsetting by multiple +#' non-contiguous time ranges in one subset call. +#' +#' The above parsing, both for single datetimes and time ranges, will be done +#' on each element when `i` is a character *vector*. This is very inefficient, +#' especially for long vectors. In this case, it's recommened to use `I(i)` so +#' the xts subset function can process the vector more efficiently. Another +#' alternative is to convert `i` to POSIXct before passing it to the subset +#' function. See the examples for an illustration of using `I(i)`. +#' +#' The xts index is stored as POSIXct internally, regardless of the value of +#' its `tclass` attribute. So the fastest time-based subsetting is always when +#' `i` is a POSIXct vector. +#' +#' @param x An xts object. +#' @param i The rows to extract. Can be a numeric vector, time-based vector, or +#' an ISO-8601 style range string (see details). +#' @param j The columns to extract, either a numeric vector of column locations +#' or a character vector of column names. +#' @param drop Should dimension be dropped, if possible? See notes section. +#' @param which.i Logical value that determines whether a subset xts object is +#' returned (the default), or the locations of the matching rows (when +#' `which.i = TRUE`). +#' @param \dots Additional arguments (currently unused). +#' +#' @return An xts object containing the subset of `x`. When `which.i = TRUE`, +#' the corresponding integer locations of the matching rows is returned. +#' +#' @note By design, xts objects always have two dimensions. They cannot be +#' vectors like zoo objects. Therefore `drop = FALSE` by default in order to +#' preserve the xts object's dimensions. This is different from both matrix and +#' zoo, which use `drop = TRUE` by default. Explicitly setting `drop = TRUE` +#' may be needed when performing certain matrix operations. +#' +#' @author Jeffrey A. Ryan +#' +#' @seealso [`xts()`], [`.parseISO8601()`], [`.index()`] +#' +#' @references ISO 8601: Date elements and interchange formats - Information +#' interchange - Representation of dates and time +#' +#' @rdname subset.xts +#' +#' @aliases [.xts subset.xts .subset.xts .subset_xts +#' @keywords utilities +#' @examples +#' +#' x <- xts(1:3, Sys.Date()+1:3) +#' xx <- cbind(x,x) +#' +#' # drop = FALSE for xts, differs from zoo and matrix +#' z <- as.zoo(xx) +#' z/z[,1] +#' +#' m <- as.matrix(xx) +#' m/m[,1] +#' +#' # this will fail with non-conformable arrays (both retain dim) +#' tryCatch( +#' xx/x[,1], +#' error = function(e) print("need to set drop = TRUE") +#' ) +#' +#' # correct way +#' xx/xx[,1,drop = TRUE] +#' +#' # or less efficiently +#' xx/drop(xx[,1]) +#' # likewise +#' xx/coredata(xx)[,1] +#' +#' +#' x <- xts(1:1000, as.Date("2000-01-01")+1:1000) +#' y <- xts(1:1000, as.POSIXct(format(as.Date("2000-01-01")+1:1000))) +#' +#' x.subset <- index(x)[1:20] +#' x[x.subset] # by original index type +#' system.time(x[x.subset]) +#' x[as.character(x.subset)] # by character string. Beware! +#' system.time(x[as.character(x.subset)]) # slow! +#' system.time(x[I(as.character(x.subset))]) # wrapped with I(), faster! +#' +#' x['200001'] # January 2000 +#' x['1999/2000'] # All of 2000 (note there is no need to use the exact start) +#' x['1999/200001'] # January 2000 +#' +#' x['2000/200005'] # 2000-01 to 2000-05 +#' x['2000/2000-04-01'] # through April 01, 2000 +#' y['2000/2000-04-01'] # through April 01, 2000 (using POSIXct series) +#' +#' +#' ### Time of day subsetting +#' +#' i <- 0:60000 +#' focal_date <- as.numeric(as.POSIXct("2018-02-01", tz = "UTC")) +#' x <- .xts(i, c(focal_date + i * 15), tz = "UTC", dimnames = list(NULL, "value")) +#' +#' # Select all observations between 9am and 15:59:59.99999: +#' w1 <- x["T09/T15"] # or x["T9/T15"] +#' head(w1) +#' +#' # timestring is of the form THH:MM:SS.ss/THH:MM:SS.ss +#' +#' # Select all observations between 13:00:00 and 13:59:59.9999 in two ways: +#' y1 <- x["T13/T13"] +#' head(y1) +#' +#' x[.indexhour(x) == 13] +#' +#' # Select all observations between 9:30am and 30 seconds, and 4.10pm: +#' x["T09:30:30/T16:10"] +#' +#' # It is possible to subset time of day overnight. +#' # e.g. This is useful for subsetting FX time series which trade 24 hours on week days +#' +#' # Select all observations between 23:50 and 00:15 the following day, in the xts time zone +#' z <- x["T23:50/T00:14"] +#' z["2018-02-10 12:00/"] # check the last day +#' +#' +#' # Select all observations between 7pm and 8.30am the following day: +#' z2 <- x["T19:00/T08:29:59"] +#' head(z2); tail(z2) +#' +`[.xts` <- function(x, i, j, drop = FALSE, which.i=FALSE,...) { USE_EXTRACT <- FALSE # initialize to FALSE @@ -294,6 +442,8 @@ function(x, i, j, drop = FALSE, which.i=FALSE,...) return(.Call(C__do_subset_xts, x, as.integer(i), as.integer(j), drop)) } +`.subset.xts` <- `[.xts` + # Replacement method for xts objects # # Adapted from [.xts code, making use of NextGeneric as @@ -411,6 +561,58 @@ window_idx <- function(x, index. = NULL, start = NULL, end = NULL) # window function for xts series, use binary search to be faster than base zoo function # index. defaults to the xts time index. If you use something else, it must conform to the standard for order.by in the xts constructor. # that is, index. must be time based, + + +#' Extract Time Windows from xts Objects +#' +#' Method for extracting time windows from xts objects. +#' +#' The xts `window()` method provides an efficient way to subset an xts object +#' between a start and end date using a binary search algorithm. Specifically, +#' it converts `start` and `end` to POSIXct and then does a binary search of +#' the index to quickly return a subset of `x` between `start` and `end`. +#' +#' Both `start` and `end` may be any class that is convertible to POSIXct, such +#' as a character string in the format \sQuote{yyyy-mm-dd}. When `start = NULL` +#' the returned subset will begin at the first value of `index.`. When +#' `end = NULL` the returned subset will end with the last value of `index.`. +#' Otherwise the subset will contain all timestamps where `index.` is between +#' `start` and `end`, inclusive. +#' +#' When `index.` is specified, [`findInterval()`] is used to quickly retrieve +#' large sets of sorted timestamps. For the best performance, `index.` must be +#' a *sorted* POSIXct vector or a numeric vector of seconds since the epoch. +#' `index.` is typically a subset of the timestamps in `x`. +#' +#' @param x An xts object. +#' @param index. A user defined time index (default `.index(x)`). +#' @param start A start time coercible to POSIXct. +#' @param end An end time coercible to POSIXct. +#' @param \dots Unused. +#' +#' @return The subset of `x` that matches the time window. +#' +#' @author Corwin Joy +#' +#' @seealso [`subset.xts()`], [`findInterval()`], [`xts()`] +#' +#' @keywords ts +#' @examples +#' +#' ## xts example +#' x.date <- as.Date(paste(2003, rep(1:4, 4:1), seq(1,19,2), sep = "-")) +#' x <- xts(matrix(rnorm(20), ncol = 2), x.date) +#' x +#' +#' window(x, start = "2003-02-01", end = "2003-03-01") +#' window(x, start = as.Date("2003-02-01"), end = as.Date("2003-03-01")) +#' window(x, index. = x.date[1:6], start = as.Date("2003-02-01")) +#' window(x, index. = x.date[c(4, 8, 10)]) +#' +#' ## Assign to subset +#' window(x, index. = x.date[c(4, 8, 10)]) <- matrix(1:6, ncol = 2) +#' x +#' window.xts <- function(x, index. = NULL, start = NULL, end = NULL, ...) { # scalar NA values are treated as NULL @@ -440,5 +642,3 @@ binsearch <- function(key, vec, start=TRUE) { } .Call(C_binsearch, key, vec, start) } - -# Unit tests for the above code may be found in runit.xts.methods.R diff --git a/R/xtsible.R b/R/xtsible.R deleted file mode 100644 index 4a3b20c5..00000000 --- a/R/xtsible.R +++ /dev/null @@ -1,71 +0,0 @@ -# -# xts: eXtensible time-series -# -# Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com -# -# Contributions from Joshua M. Ulrich -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -xtsible <- function(x) -{ - if(inherits(try(as.xts(x),silent=TRUE),'try-error')) { - FALSE - } else TRUE -} - -use.xts <- try.xts <- function(x, ..., error=TRUE) -{ - if(is.xts(x)) { - #attr(x,'.RECLASS') <- FALSE - return(x) - } - - xx <- try(as.xts(x,..., .RECLASS=TRUE),silent=TRUE) - if(inherits(xx,'try-error')) { - if(is.character(error)) { - stop(error) - } else - if(is.function(error)) { - return(error(x, ...)) - } else - if(error) { - stop(gsub('\n','',xx)) - } else { - return(x) - } - } else { - # made positive: now test if needs to be reclassed - structure(xx, .RECLASS=TRUE) - } -} - -.merge.xts.scalar <- function(x, length.out, ...) { - if( length.out == 0) - return(vector(storage.mode(x), 0)) - if( length(x) == 1 ) - return(matrix(rep(x, length.out=length.out))) - if( NROW(x) == length.out ) - return(x) - stop("improper length of one or more arguments to merge.xts") -} - -use.reclass <- Reclass <- function(x) { - xx <- match.call() - xxObj <- eval.parent(parse(text=all.vars(xx)[1]), 1) - inObj <- try.xts(xxObj, error=FALSE) - xx <- eval(match.call()[[-1]]) - reclass(xx, inObj) -} diff --git a/R/yearmon.R b/R/yearmon.R index f249a849..f6093efa 100644 --- a/R/yearmon.R +++ b/R/yearmon.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -19,11 +19,13 @@ # along with this program. If not, see . +#' @rdname as.xts as.xts.yearmon <- function(x, ...) { xts(x=NULL, order.by=x) } +#' @rdname as.xts as.xts.yearqtr <- function(x, ...) { xts(x=NULL, order.by=x) diff --git a/R/zoo.R b/R/zoo.R index 06b7b25b..8313ccbb 100644 --- a/R/zoo.R +++ b/R/zoo.R @@ -1,5 +1,5 @@ # -# xts: eXtensible time-series +# xts: eXtensible time-series # # Copyright (C) 2008 Jeffrey A. Ryan jeff.a.ryan @ gmail.com # @@ -37,6 +37,7 @@ function(x,...) { xx } +#' @rdname as.xts `as.xts.zoo` <- function(x,order.by=index(x),frequency=NULL,...,.RECLASS=FALSE) { if(.RECLASS) { @@ -52,14 +53,6 @@ function(x,order.by=index(x),frequency=NULL,...,.RECLASS=FALSE) { ...) } -# -# if(!is.null(attr(x,'names'))) { -# dim(xx) <- c(NROW(xx),NCOL(xx)) -# dn <- list(attr(x,'names'),colnames(x)) -# dimnames(xx) <- dn -# attr(xx,'.ROWNAMES') <- attr(x,'names') -# } -# xx } diff --git a/R/zzz.R b/R/zzz.R index de82e6db..0d48c816 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -90,14 +90,6 @@ function(pkg, generic, class, fun = NULL) .onLoad <- function(libname, pkgname) { -# if(Sys.getenv("TZ") == "") { -# packageStartupMessage("xts now requires a valid TZ environment variable to be set") -# packageStartupMessage(" no TZ var is set, setting to TZ=GMT") -# Sys.setenv(TZ="GMT") -# } else { -# packageStartupMessage("xts now requires a valid TZ environment variable to be set") -# packageStartupMessage(" your current TZ:",paste(Sys.getenv("TZ"))) -# } if (getRversion() < "3.6.0") { register_s3_method("timeSeries", "as.timeSeries", "xts") if (utils::packageVersion("zoo") < "1.8.5") { diff --git a/README.md b/README.md index 491f7324..c32dd069 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ constraints, while providing a truly time-based structure. Available as part of the Tidelift Subscription. -The maintainers of `xts` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/cran-xts?utm_source=cran-xts&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) +The maintainers of `xts` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/?utm_source=cran-xts&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ### Supporting xts development @@ -41,7 +41,7 @@ appendix in the [R Installation and Administration manual](https://cran.r-projec for your operating system: - [Windows](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#The-Windows-toolset) -- [MacOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) (the [R for Mac OS X Developer's Page](https://r.research.att.com/) might also be helpful) +- [MacOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) (the [R for Mac OS X Developer's Page](https://mac.r-project.org/) might also be helpful) - [Unix-alike](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#Essential-and-useful-other-programs-under-a-Unix_002dalike) ### Getting Started @@ -152,14 +152,14 @@ period.apply(x, endpoints(x, "months"), colMeans) ###### Have a question? -Ask your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/r) +Ask your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/r) or the [R-SIG-Finance](https://stat.ethz.ch/mailman/listinfo/r-sig-finance) mailing list (you must subscribe to post). ###### Want hands-on experience? - [DataCamp course on importing and managing financial data](https://www.datacamp.com/courses/importing-and-managing-financial-data-in-r) -- [DataCamp course on manipulating time series with xts & zoo](https://www.datacamp.com/courses/manipulating-time-series-data-in-r-with-xts-zoo) +- [DataCamp course on manipulating time series with xts & zoo](https://www.datacamp.com/courses/manipulating-time-series-data-in-r) ### Contributing diff --git a/inst/tinytest/test-merge.R b/inst/tinytest/test-merge.R index b6f43db2..bcd4f0bf 100644 --- a/inst/tinytest/test-merge.R +++ b/inst/tinytest/test-merge.R @@ -245,7 +245,6 @@ empty_with_dims_3x <- structure(integer(0), dim = c(0L, 9L), index = .index(x0), dimnames = list(NULL, c("a", "b", "c", "a.1", "b.1", "c.1", "a.2", "b.2", "c.2")), class = c("xts", "zoo")) -storage.mode(.index(empty_with_dims_3x)) <- "integer" ## FIXME: this should be 'numeric expect_identical(xm6, empty_with_dims_3x, info = "merge.xts([empty_xts_with_dims 3x]) has correct dims") @@ -277,3 +276,12 @@ x3 <- merge(x, v, x) z3 <- merge(z, v, z) expect_equivalent(coredata(x3), coredata(z3), info = "merge.xts(x_named, vector, x_named) coredata matches merge.zoo()") expect_equivalent(index(x3), index(z3), info = "merge.xts(x_named, vector, x_named) index matches merge.zoo()") + +# this was throwing a warning because 'dbl' was unnecessarily being converted to integer +retside <- c(TRUE, FALSE) +int <- xts(1:10, .Date(1:10)) +dbl <- int + 1e20 +expect_silent(merge(int, dbl, retside = retside), + info = "merge.xts(xts_int, xts_dbl) doesn't warn when xts_dbl isn't returned") +expect_silent(merge(dbl, int, retside = rev(retside)), + info = "merge.xts(xts_dbl, xts_int) doesn't warn when xts_dbl isn't returned") diff --git a/man/CLASS.Rd b/man/CLASS.Rd index 2f4584aa..c4774e35 100644 --- a/man/CLASS.Rd +++ b/man/CLASS.Rd @@ -1,34 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reclass.R \name{CLASS} \alias{CLASS} \alias{CLASS<-} -\title{ Extract and Set .CLASS Attribute } -\description{ -Simple extraction and replacement function -to access \code{xts} .CLASS attribute. The .CLASS -attribute is used by \code{reclass} to transform -an \code{xts} object back to its original class. -} +\title{Extract and Set .CLASS Attribute} \usage{ CLASS(x) CLASS(x) <- value } \arguments{ - \item{x}{ an xts object } - \item{value}{ the new .CLASS value to assign } -} -\details{ -It is not recommended that CLASS be called in -daily use. While it may be possible to coerce objects -to other classes than originally derived from, there is -little, if any, chance that the \code{reclass} function -will perform as expected. +\item{x}{An xts object.} -It is best to use the traditional \code{as} methods. +\item{value}{The new value to assign to the '.CLASS' attribute.} } \value{ -Called for its side-effect of changing the .CLASS attribute +Called for its side-effect of changing the '.CLASS' attribute. +} +\description{ +Extraction and replacement functions to access the xts '.CLASS' attribute. +The '.CLASS' attribute is used by \code{reclass()} to transform an xts object +back to its original class. +} +\details{ +This is meant for use in conjunction with \code{try.xts()} and \code{reclass()} and is +is not intended for daily use. While it's possible to interactively coerce +objects to other classes than originally derived from, it's likely to cause +unexpected behavior. It is best to use the usual \code{as.xts()} and other +classes' \code{as} methods. +} +\seealso{ +\code{\link[=as.xts]{as.xts()}}, \code{\link[=reclass]{reclass()}} +} +\author{ +Jeffrey A. Ryan } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{as.xts}},\code{\link{reclass}} } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/addEventLines.Rd b/man/addEventLines.Rd index 9b824e23..a74461e0 100644 --- a/man/addEventLines.Rd +++ b/man/addEventLines.Rd @@ -1,3 +1,5 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{addEventLines} \alias{addEventLines} \title{Add vertical lines to an existing xts plot} @@ -5,33 +7,31 @@ addEventLines(events, main = "", on = 0, lty = 1, lwd = 1, col = 1, ...) } \arguments{ -\item{events}{xts object of events and their associated labels. It is assumed -that the first column of \code{events} is the event description/label.} +\item{events}{An xts object of events and their associated labels. It is +ensured that the first column of \code{events} is the event description/label.} -\item{main}{main title for a new panel if drawn.} +\item{main}{Main title for a new panel, if drawn.} -\item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}. -The default, \code{on=0}, will add to the active panel. The active panel is -defined as the panel on which the most recent action was performed. Note that -only the first element of \code{on} is checked for the default behavior to +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}. +The default, \code{on = 0}, will add to the active panel. The active panel is +defined as the panel on which the most recent action was performed. Note +that only the first element of \code{on} is checked for the default behavior to add to the last active panel.} -\item{lty}{set the line type, same as in \code{\link{par}}.} +\item{lty}{Set the line type, same as in \code{\link[=par]{par()}}.} -\item{lwd}{set the line width, same as in \code{\link{par}}.} +\item{lwd}{Set the line width, same as in \code{\link[=par]{par()}}.} -\item{col}{color palette to use, set by default to rational choices.} +\item{col}{Color palette to use, set by default to rational choices.} -\item{\dots}{any other passthrough parameters to \code{\link{text}} to -control how the event labels are drawn} +\item{\dots}{Any other passthrough parameters to \code{\link[=text]{text()}} to control how +the event labels are drawn.} } \description{ -Add vertical lines and labels to an existing xts plot -} -\author{ -Ross Bennett +Add vertical lines and labels to an existing xts plot. } \examples{ + \dontrun{ library(xts) data(sample_matrix) @@ -39,6 +39,10 @@ sample.xts <- as.xts(sample_matrix) events <- xts(letters[1:3], as.Date(c("2007-01-12", "2007-04-22", "2007-06-13"))) plot(sample.xts[,4]) -addEventLines(events, srt=90, pos=2) +addEventLines(events, srt = 90, pos = 2) } + +} +\author{ +Ross Bennett } diff --git a/man/addLegend.Rd b/man/addLegend.Rd index d4e0c200..0e2f266e 100644 --- a/man/addLegend.Rd +++ b/man/addLegend.Rd @@ -1,35 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{addLegend} \alias{addLegend} \title{Add Legend} \usage{ -addLegend(legend.loc = "topright", legend.names = NULL, col = NULL, - ncol = 1, on = 0, ...) +addLegend( + legend.loc = "topright", + legend.names = NULL, + col = NULL, + ncol = 1, + on = 0, + ... +) } \arguments{ -\item{legend.loc}{legend.loc places a legend into one of nine locations on -the chart: bottomright, bottom, bottomleft, left, topleft, top, topright, -right, or center.} +\item{legend.loc}{One of nine locations: bottomright, bottom, bottomleft, +left, topleft, top, topright, right, or center.} -\item{legend.names}{character vector of names for the legend. If \code{NULL}, +\item{legend.names}{Character vector of names for the legend. When \code{NULL}, the column names of the current plot object are used.} -\item{col}{fill colors for the legend. If \code{NULL}, -the colorset of the current plot object data is used.} +\item{col}{Fill colors for the legend. When \code{NULL}, the colorset of the +current plot object data is used.} -\item{ncol}{number of columns for the legend} +\item{ncol}{Number of columns for the legend.} -\item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}. -The default, \code{on=0}, will add to the active panel. The active panel is -defined as the panel on which the most recent action was performed. Note that -only the first element of \code{on} is checked for the default behavior to +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}. +The default, \code{on = 0}, will add to the active panel. The active panel is +defined as the panel on which the most recent action was performed. Note +that only the first element of \code{on} is checked for the default behavior to add to the last active panel.} -\item{\dots}{any other passthrough parameters to \code{\link{legend}}.} +\item{\dots}{Any other passthrough parameters to \code{\link[=legend]{legend()}}.} } \description{ -Add Legend +Add a legend to an existing panel. } \author{ Ross Bennett } - diff --git a/man/addPanel.Rd b/man/addPanel.Rd index e3be5b00..37e23830 100644 --- a/man/addPanel.Rd +++ b/man/addPanel.Rd @@ -1,40 +1,49 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{addPanel} \alias{addPanel} \title{Add a panel to an existing xts plot} \usage{ -addPanel(FUN, main = "", on = NA, type = "l", col = NULL, lty = 1, - lwd = 1, pch = 1, ...) +addPanel( + FUN, + main = "", + on = NA, + type = "l", + col = NULL, + lty = 1, + lwd = 1, + pch = 1, + ... +) } \arguments{ -\item{FUN}{an xts object to plot.} +\item{FUN}{An xts object to plot.} -\item{main}{main title for a new panel if drawn.} +\item{main}{Main title for a new panel if drawn.} -\item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}.} +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}.} -\item{type}{the type of plot to be drawn, same as in \code{\link{plot}}.} +\item{type}{The type of plot to be drawn, same as in \code{\link[=plot]{plot()}}.} -\item{col}{color palette to use, set by default to rational choices.} +\item{col}{Color palette to use, set by default to rational choices.} -\item{lty}{set the line type, same as in \code{\link{par}}.} +\item{lty}{Set the line type, same as in \code{\link[=par]{par()}}.} -\item{lwd}{set the line width, same as in \code{\link{par}}.} +\item{lwd}{Set the line width, same as in \code{\link[=par]{par()}}.} -\item{pch}{the type of plot to be drawn, same as in \code{\link{par}}.} +\item{pch}{The type of plot to be drawn, same as in \code{\link[=par]{par()}}.} -\item{\dots}{additional named arguments passed through to \code{FUN} and -any other graphical passthrough parameters.} +\item{\dots}{Additional named arguments passed through to \code{FUN} and any +other graphical passthrough parameters.} } \description{ -Apply a function to the data of an existing xts plot object and plot -the result. \code{FUN} should have arguments \code{x} or \code{R} for the -data of the existing xts plot object to be passed to. All other additional -arguments for \code{FUN} are passed through \dots. -} -\author{ -Ross Bennett +Apply a function to the data of an existing xts plot object and plot the +result on an existing or new panel. \code{FUN} should have arguments \code{x} or \code{R} +for the data of the existing xts plot object to be passed to. All other +additional arguments for \code{FUN} are passed through \dots. } \examples{ + library(xts) data(sample_matrix) sample.xts <- as.xts(sample_matrix) @@ -53,8 +62,15 @@ calcReturns <- function(price, method = c("discrete", "log")){ # plot the Close plot(sample.xts[,"Close"]) # calculate returns -addPanel(calcReturns, method="discrete", type="h") +addPanel(calcReturns, method = "discrete", type = "h") # Add simple moving average to panel 1 -addPanel(rollmean, k=20, on=1) -addPanel(rollmean, k=40, col="blue", on=1) +addPanel(rollmean, k = 20, on = 1) +addPanel(rollmean, k = 40, col = "blue", on = 1) + +} +\seealso{ +\code{\link[=plot.xts]{plot.xts()}}, \code{\link[=addSeries]{addSeries()}} +} +\author{ +Ross Bennett } diff --git a/man/addPolygon.Rd b/man/addPolygon.Rd index fe5c723d..cfa525d8 100644 --- a/man/addPolygon.Rd +++ b/man/addPolygon.Rd @@ -1,27 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{addPolygon} \alias{addPolygon} \title{Add a polygon to an existing xts plot} -\description{ -Draw a polygon on an existing xts plot by specifying a time series of y -coordinates. The xts index is used for the x coordinates and the first two -columns are the upper and lower y coordinates, respectively. -} \usage{ addPolygon(x, y = NULL, main = "", on = NA, col = NULL, ...) } \arguments{ - \item{x}{ - an xts object to plot. Must contain 2 columns for the upper and lower y - coordinates for the polygon. The first column is interpreted as the upper y - coordinates and the second column as the lower y coordinates. +\item{x}{An xts object to plot. Must contain 2 columns for the upper and +the lower y coordinates for the polygon. The first column is interpreted +as upper y coordinates and the second column as the lower y coordinates.} + +\item{y}{\code{NULL}, not used.} + +\item{main}{Main title for a new panel, if drawn.} + +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}.} + +\item{col}{Color palette to use, set by default to rational choices.} + +\item{\dots}{Any other passthrough parameters to \code{\link[=par]{par()}}.} } - \item{y}{NULL, not used} - \item{main}{main title for a new panel if drawn.} - \item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}.} - \item{col}{color palette to use, set by default to rational choices.} - \item{\dots}{passthru parameters to \code{\link{par}}} +\description{ +Draw a polygon on an existing xts plot by specifying a time series of y +coordinates. The xts index is used for the x coordinates and the first two +columns are the upper and lower y coordinates, respectively. } \examples{ + \dontrun{ library(xts) data(sample_matrix) @@ -34,8 +40,12 @@ plot(x) # set on = -1 to draw the shaded region *behind* the main series addPolygon(shade, on = -1, col = "lightgrey") } + } \references{ -Based on code by Dirk Eddelbuettel from \url{http://dirk.eddelbuettel.com/blog/2011/01/16/} +Based on code by Dirk Eddelbuettel from +\url{http://dirk.eddelbuettel.com/blog/2011/01/16/} +} +\author{ +Ross Bennett } -\author{Ross Bennett} diff --git a/man/addSeries.Rd b/man/addSeries.Rd index 881c004b..6c87d722 100644 --- a/man/addSeries.Rd +++ b/man/addSeries.Rd @@ -1,28 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{addSeries} \alias{addSeries} \title{Add a time series to an existing xts plot} \usage{ -addSeries(x, main = "", on = NA, type = "l", col = NULL, lty = 1, - lwd = 1, pch = 1, ...) +addSeries( + x, + main = "", + on = NA, + type = "l", + col = NULL, + lty = 1, + lwd = 1, + pch = 1, + ... +) } \arguments{ -\item{x}{an xts object to plot.} +\item{x}{An xts object to add to the plot.} -\item{main}{main title for a new panel if drawn.} +\item{main}{Main title for a new panel if drawn.} -\item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}.} +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}.} -\item{type}{the type of plot to be drawn, same as in \code{\link{plot}}.} +\item{type}{The type of plot to be drawn, same as in \code{\link[=plot]{plot()}}.} -\item{col}{color palette to use, set by default to rational choices.} +\item{col}{Color palette to use, set by default to rational choices.} -\item{lty}{set the line type, same as in \code{\link{par}}.} +\item{lty}{Set the line type, same as in \code{\link[=par]{par()}}.} -\item{lwd}{set the line width, same as in \code{\link{par}}.} +\item{lwd}{Set the line width, same as in \code{\link[=par]{par()}}.} -\item{pch}{the type of plot to be drawn, same as in \code{\link{par}}.} +\item{pch}{The type of plot to be drawn, same as in \code{\link[=par]{par()}}.} -\item{\dots}{any other passthrough graphical parameters.} +\item{\dots}{Any other passthrough graphical parameters.} } \description{ Add a time series to an existing xts plot @@ -30,4 +41,3 @@ Add a time series to an existing xts plot \author{ Ross Bennett } - diff --git a/man/align.time.Rd b/man/align.time.Rd index a142fd5f..9789a57c 100644 --- a/man/align.time.Rd +++ b/man/align.time.Rd @@ -1,54 +1,40 @@ -\name{align.time} -\Rdversion{1.1} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/adj.time.R, R/align.time.R +\name{adj.time} +\alias{adj.time} \alias{align.time} \alias{align.time.xts} -\alias{adj.time} \alias{shift.time} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ -Align seconds, minutes, and hours to beginning of next period. -} -\description{ -Change timestamps to the start of the next period, specified -in multiples of seconds. -} +\title{Align seconds, minutes, and hours to beginning of next period.} \usage{ -align.time(x, ...) +adj.time(x, ...) -\method{align.time}{xts}(x, n=60, \dots) +align.time(x, ...) -shift.time(x, n=60, ...) +\method{align.time}{xts}(x, n = 60, ...) -adj.time(x, ...) +shift.time(x, n = 60, ...) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{x}{ - object to align -} - \item{n}{ - number of seconds to adjust by -} - \item{\dots}{ - additional arguments. See details. -} -} -\details{ -This function is an S3 generic. -The result is to round up to the next -period determined by \code{n modulo x}. +\item{x}{Object containing timestamps to align.} + +\item{\dots}{Additional arguments. See details.} + +\item{n}{Number of seconds to adjust by.} } \value{ -A new object of class(x) +A new object with the same class as \code{x}. } -\author{ -Jeffrey A. Ryan with input from Brian Peterson +\description{ +Change timestamps to the start of the next period, specified in multiples of +seconds. } - -\seealso{ -\code{\link{to.period}} +\details{ +This function is an S3 generic. The result is to round up to the next period +determined by 'n modulo x'. } \examples{ + x <- Sys.time() + 1:1000 # every 10 seconds @@ -59,11 +45,15 @@ align.time(x, 60) # align to next whole 10 min interval align.time(x, 10 * 60) -} -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ chron }% __ONLY ONE__ keyword per line -\keyword{ manip }% __ONLY ONE__ keyword per line -\keyword{ ts }% __ONLY ONE__ keyword per line -\keyword{ misc }% __ONLY ONE__ keyword per line +} +\seealso{ +\code{\link[=to.period]{to.period()}} +} +\author{ +Jeffrey A. Ryan with input from Brian Peterson +} +\keyword{chron} +\keyword{manip} +\keyword{misc} +\keyword{ts} diff --git a/man/apply.monthly.Rd b/man/apply.monthly.Rd index 5ed704db..f63e1f01 100644 --- a/man/apply.monthly.Rd +++ b/man/apply.monthly.Rd @@ -1,64 +1,66 @@ -\name{apply.monthly} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/period.apply.R +\name{apply.daily} \alias{apply.daily} \alias{apply.weekly} \alias{apply.monthly} \alias{apply.quarterly} \alias{apply.yearly} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ Apply Function over Calendar Periods } -\description{ -Apply a specified function to each distinct period in a given -time series object. -} +\title{Apply Function over Calendar Periods} \usage{ apply.daily(x, FUN, ...) + apply.weekly(x, FUN, ...) + apply.monthly(x, FUN, ...) + apply.quarterly(x, FUN, ...) + apply.yearly(x, FUN, ...) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{x}{ an time-series object coercible to xts } - \item{FUN}{ an \R function } - \item{\dots}{ additional arguments to FUN } +\item{x}{A time-series object coercible to xts.} + +\item{FUN}{A function to apply to each period.} + +\item{\dots}{Additional arguments to \code{FUN}.} +} +\value{ +A vector of results produced by \code{FUN}, corresponding to the +appropriate periods. +} +\description{ +Apply a specified function to each distinct period in a given time series +object. } \details{ -Simple mechanism to apply a function to non-overlapping -time periods, e.g. weekly, monthly, etc. Different from rolling -functions in that this will subset the data based on the specified -time period (implicit in the call), and return a vector of values -for each period in the original data. +Simple mechanism to apply a function to non-overlapping time periods, e.g. +weekly, monthly, etc. Different from rolling functions in that this will +subset the data based on the specified time period (implicit in the call), +and return a vector of values for each period in the original data. -Essentially a wrapper to the \pkg{xts} functions -\code{endpoints} and \code{period.apply}, mainly as -a convenience. +Essentially a wrapper to the \pkg{xts} functions \code{endpoints()} and +\code{period.apply()}, mainly as a convenience. } \note{ - When \code{FUN = mean} the results will contain one column for every column - in the input, which is different from other math functions (e.g. \code{median}, - \code{sum}, \code{prod}, \code{sd}, etc.). +When \code{FUN = mean} the results will contain one column for every +column in the input, which is different from other math functions (e.g. +\code{median}, \code{sum}, \code{prod}, \code{sd}, etc.). - \code{FUN = mean} works by column because the default method \code{stats::mean} - used to work by column for matrices and data.frames. R Core changed the - behavior of \code{mean} to always return one column in order to be consistent - with the other math functions. This broke some \pkg{xts} dependencies and - \code{mean.xts} was created to maintain the original behavior. +\code{FUN = mean} works by column because the default method \code{stats::mean} +previously worked by column for matrices and data.frames. R Core changed the +behavior of \code{mean} to always return one column in order to be consistent +with the other math functions. This broke some \pkg{xts} dependencies and +\code{mean.xts()} was created to maintain the original behavior. - Using \code{FUN = mean} will print a message that describes this inconsistency. - To avoid the message and confusion, use \code{FUN = colMeans} to calculate - means by column and use \code{FUN = function(x) mean} to calculate one mean - for all the data. Set \code{options(xts.message.period.apply.mean = FALSE)} - to suppress this message. -} -\value{ -A vector of results produced by \code{FUN}, corresponding -to the appropriate periods. +Using \code{FUN = mean} will print a message that describes this inconsistency. +To avoid the message and confusion, use \code{FUN = colMeans} to calculate means +by column and use \code{FUN = function(x) mean} to calculate one mean for all the +data. Set \code{options(xts.message.period.apply.mean = FALSE)} to suppress this +message. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}}, \code{\link{period.apply}}, - \code{\link{to.monthly}} } \examples{ + xts.ts <- xts(rnorm(231),as.Date(13514:13744,origin="1970-01-01")) start(xts.ts) @@ -66,5 +68,12 @@ end(xts.ts) apply.monthly(xts.ts,colMeans) apply.monthly(xts.ts,function(x) var(x)) + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}}, \code{\link[=period.apply]{period.apply()}}, \code{\link[=to.monthly]{to.monthly()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/as.environment.Rd b/man/as.environment.Rd deleted file mode 100644 index 0325454c..00000000 --- a/man/as.environment.Rd +++ /dev/null @@ -1,36 +0,0 @@ -\name{as.environment.xts} -\alias{as.environment.xts} -\title{ Coerce an \sQuote{xts} Object to an Environment by Column } -\description{ -Method to automatically convert an \sQuote{xts} object to an environment -containing vectors representing each column of the original xts object. Each -objects will be named according to the column name it is exracted by. -} -\usage{ -\method{as.environment}{xts}(x) -} -\arguments{ - \item{x}{ an \code{xts} object } -} -\details{ -An experimental tool to convert \code{xts} objects into environments -for simplifying use withing the standard R formula/data paradigm. -} -\value{ -An \code{environment} containing \code{ncol(x)} vectors -extracted by column from \code{x}. Note that environments -do not preserve (or have knowledge) of column position, a.k.a order. -} -\author{ Jeffrey A. Ryan } -\examples{ -x <- xts(1:10, Sys.Date()+1:10) -colnames(x) <- "X" -y <- xts(1:10, Sys.Date()+1:10) -colnames(x) <- "Y" -xy <- cbind(x,y) -colnames(xy) -e <- as.environment(xy) # currently using xts-style positive k -ls(xy) -ls.str(xy) -} -\keyword{ manip }% __ONLY ONE__ keyword per line diff --git a/man/as.environment.xts.Rd b/man/as.environment.xts.Rd new file mode 100644 index 00000000..8ba0feb6 --- /dev/null +++ b/man/as.environment.xts.Rd @@ -0,0 +1,42 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/as.environment.xts.R +\name{as.environment.xts} +\alias{as.environment.xts} +\title{Coerce an xts Object to an Environment by Column} +\usage{ +\method{as.environment}{xts}(x) +} +\arguments{ +\item{x}{An xts object.} +} +\value{ +An environment containing \code{ncol(x)} vectors extracted by +column from \code{x}. +} +\description{ +Method to automatically convert an xts object to an environment containing +vectors representing each column of the original xts object. The name of +each object in the resulting environment corresponds to the name of the +column of the xts object. +} +\note{ +Environments do not preserve (or have knowledge) of column order and +cannot be subset by an integer index. +} +\examples{ + +x <- xts(1:10, Sys.Date()+1:10) +colnames(x) <- "X" +y <- xts(1:10, Sys.Date()+1:10) +colnames(x) <- "Y" +xy <- cbind(x,y) +colnames(xy) +e <- as.environment(xy) # currently using xts-style positive k +ls(xy) +ls.str(xy) + +} +\author{ +Jeffrey A. Ryan +} +\keyword{manip} diff --git a/man/as.xts.Rd b/man/as.xts.Rd index 066c96d8..f3d3ac4b 100644 --- a/man/as.xts.Rd +++ b/man/as.xts.Rd @@ -1,96 +1,129 @@ -\name{as.xts} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Date.R, R/POSIX.R, R/data.frame.R, R/irts.R, +% R/matrix.R, R/timeDate.R, R/timeSeries.R, R/ts.R, R/xts.R, R/yearmon.R, +% R/zoo.R +\name{as.xts.Date} +\alias{as.xts.Date} +\alias{as.xts.POSIXt} +\alias{as.xts.data.frame} +\alias{as.xts.irts} +\alias{as.xts.matrix} +\alias{as.xts.timeDate} +\alias{as.xts.timeSeries} +\alias{as.xts.ts} \alias{as.xts} \alias{xtsible} -\alias{use.xts} -\alias{try.xts} -\alias{use.reclass} -\alias{Reclass} -\alias{reclass} -\title{ Convert Object To And From Class xts } -\description{ -Conversion functions to coerce data objects of -arbitrary classes to class \code{xts} and back, without -losing any attributes of the original format. -} +\alias{as.xts.yearmon} +\alias{as.xts.yearqtr} +\alias{as.xts.zoo} +\title{Convert Objects To and From xts} \usage{ +\method{as.xts}{Date}(x, ...) + +\method{as.xts}{POSIXt}(x, ...) + +\method{as.xts}{data.frame}( + x, + order.by, + dateFormat = "POSIXct", + frequency = NULL, + ..., + .RECLASS = FALSE +) + +\method{as.xts}{irts}(x, order.by, frequency = NULL, ..., .RECLASS = FALSE) + +\method{as.xts}{matrix}( + x, + order.by, + dateFormat = "POSIXct", + frequency = NULL, + ..., + .RECLASS = FALSE +) + +\method{as.xts}{timeDate}(x, ...) + +\method{as.xts}{timeSeries}( + x, + dateFormat = "POSIXct", + FinCenter, + recordIDs, + title, + documentation, + ..., + .RECLASS = FALSE +) + +\method{as.xts}{ts}(x, dateFormat, ..., .RECLASS = FALSE) + as.xts(x, ...) + xtsible(x) -Reclass(x) +\method{as.xts}{yearmon}(x, ...) + +\method{as.xts}{yearqtr}(x, ...) -try.xts(x, ..., error = TRUE) -reclass(x, match.to, error = FALSE, ...) +\method{as.xts}{zoo}(x, order.by = index(x), frequency = NULL, ..., .RECLASS = FALSE) } \arguments{ - \item{x}{ data object to convert. See details for supported types } - \item{match.to}{ \code{xts} object whose attributes will be passed to \code{x}} - \item{error}{ error handling option. See Details. } - \item{\dots}{ additional parameters or attributes } +\item{x}{Data object to convert. See details for supported types.} + +\item{\dots}{Additional parameters or attributes.} + +\item{order.by, frequency}{See \link[zoo:zoo]{zoo} help.} + +\item{dateFormat}{What class should the dates be converted to?} + +\item{.RECLASS}{Should the conversion be reversible via \code{\link[=reclass]{reclass()}}?} + +\item{FinCenter, recordIDs, title, documentation}{See \link[timeSeries:timeSeries]{timeSeries} help.} +} +\value{ +An S3 object of class xts. +} +\description{ +Conversion S3 methods to coerce data objects of arbitrary classes to xts +and back, without losing any attributes of the original format. } \details{ -A simple and reliable way to convert many different -objects into a uniform format for use within \R. - -It is possible with a call to \code{as.xts} to -convert objects of class \code{timeSeries}, \code{ts}, \code{irts}, -\code{matrix}, \code{data.frame}, and \code{zoo}. - -\code{xtsible} safely checks whether an object can be converted to -an \code{xts} object; returning TRUE on success and FALSE -otherwise. - -The help file \code{as.xts.methods} lists all available -xts methods and arguments specific to each coercible type. - -Additional name=value pairs may be passed to the function -to be added to the new object. A special print.xts method -will assure that the attributes are hidden from view, but will -be available via \R's standard \code{attr} function, as well -as the \code{xtsAttributes} function. - -The returned object will preserve all relevant attribute/slot -data within itself, allowing for temporary conversion to use -zoo and xts compatible methods. A call to \code{reclass} -returns the object to its original class, with all original -attributes intact - unless otherwise changed. - -It should be obvious, but any attributes added via the \dots -argument will not be carried back to the original data object, -as there would be no available storage slot/attribute. - -\code{Reclass} is designed for top-level use, where it is -desirable to have the object returned from an arbitrary -function in the same class as the object passed in. Most -functions within \R are not designed to return objects -matching the original object's class. While this tool is -highly experimental at present, it attempts to handle -conversion and reconversion transparently. The caveats are -that the original object must be coercible to \code{xts}, -the returned object must be of the same row length as the -original object, and that the object to reconvert to is -the first argument to the function being wrapped. - -\code{try.xts} and \code{reclass} are functions that enable -external developers access to the reclassing tools within -\pkg{xts} to help speed development of time-aware functions, -as well as provide a more robust and seemless end-user experience, -regardless of the end-user's choice of data-classes. - -The \code{error} argument to try.xts accepts a logical value, -indicating where an error should be thrown, a character string -allowing for custom error messages to be displayed, or -a function of the form \code{f(x, ...)}, to be called -upon construction error. - -See the accompanying vignette for more details on the above usage -and the package in general. +A simple and reliable way to convert many different objects into a uniform +format for use within \R. + +\code{as.xts()} can convert objects of the following classes into an xts object: +object: \link[timeSeries:timeSeries]{timeSeries}, \link{ts}, \link{matrix}, \link{data.frame}, +and \link{zoo}. \code{xtsible()} safely checks whether an object can be converted to +an xts object. + +Additional \code{name = value} pairs may be passed to the function to be added to +the new object. A special \code{\link[=print.xts]{print.xts()}} method ensures the attributes are +hidden from view, but will be available via \R's standard \code{attr()} function, +as well as the \code{\link[=xtsAttributes]{xtsAttributes()}} function. + +When \code{.RECLASS = TRUE}, the returned xts object internally preserves all +relevant attribute/slot data from the input \code{x}. This allows for temporary +conversion to xts in order to use zoo and xts compatible methods. See +\code{\link[=reclass]{reclass()}} for details. } -\value{ -An S3 object of class \code{xts}. +\examples{ -In the case of \code{Reclass} and \code{reclass}, the object -returned will be of the original class as identified by \code{CLASS}. +\dontrun{ +# timeSeries +library(timeSeries) +x <- timeSeries(1:10, 1:10) + +str(as.xts(x)) +str(reclass(as.xts(x))) +str(try.xts(x)) +str(reclass(try.xts(x))) +} + +} +\seealso{ +\code{\link[=xts]{xts()}}, \code{\link[=reclass]{reclass()}}, \code{\link[zoo:zoo]{zoo()}} +} +\author{ +Jeffrey A. Ryan } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{xts}},\code{\link{as.xts.methods}} } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/as.xts.methods.Rd b/man/as.xts.methods.Rd deleted file mode 100644 index 1ab9c39b..00000000 --- a/man/as.xts.methods.Rd +++ /dev/null @@ -1,88 +0,0 @@ -\name{as.xts.methods} -\alias{as.xts.methods} -\alias{as.xts.timeSeries} -\alias{as.timeSeries.xts} -\alias{as.xts.xts} -\alias{as.xts.zoo} -\alias{as.xts.ts} -\alias{as.xts.data.frame} -\alias{as.xts.matrix} -\title{ Convert Object To And From Class xts } -\description{ -Conversion S3 methods to coerce data objects of -arbitrary classes to class \code{xts} and back, without -losing any attributes of the original format. -} -\usage{ -\method{as.xts}{xts}(x,...,.RECLASS=FALSE) - - -\method{as.xts}{timeSeries}(x, dateFormat="POSIXct", FinCenter, recordIDs, - title, documentation, ..., .RECLASS=FALSE) - -\method{as.xts}{zoo}(x, order.by=index(x), frequency=NULL, ..., .RECLASS=FALSE) - -\method{as.xts}{ts}(x, dateFormat,...,.RECLASS=FALSE) - -\method{as.xts}{data.frame}(x, order.by, dateFormat="POSIXct", - frequency=NULL, ...,.RECLASS=FALSE) - -\method{as.xts}{matrix}(x, order.by, dateFormat="POSIXct", - frequency=NULL, ..., .RECLASS=FALSE) -} -\arguments{ - \item{x}{ data object to convert. See details for supported types } - \item{dateFormat}{what format should the dates be converted to} - \item{FinCenter}{see timeSeries help} - \item{recordIDs}{see timeSeries help} - \item{title}{see timeSeries help} - \item{documentation}{see timeSeries help} - \item{order.by}{see \link[zoo]{zoo} help } - \item{frequency}{see \link[zoo]{zoo} help } - \item{\dots}{ additional parameters or attributes } - \item{.RECLASS}{ should conversion be reversible? } -} -\details{ -A simple and reliable way to convert many different -objects into a uniform format for use within \R. - -It is possible with a call to \code{as.xts} to -convert objects of class \code{timeSeries}, \code{ts}, -\code{matrix}, \code{data.frame}, and \code{zoo}. - -Additional name=value pairs may be passed to the function -to be added to the new object. A special print.xts method -will assure that the attributes are hidden from view, but will -be available via \R's standard \code{attr} function. - -If \code{.RECLASS=TRUE}, the returned object will preserve all relevant attribute/slot -data within itself, allowing for temporary conversion to use -zoo and xts compatible methods. A call to \code{reclass} -returns the object to its original class, with all original -attributes intact - unless otherwise changed. This is the default -behavior when \code{try.xts} is used for conversion, and should -not be altered by the user; i.e. don't touch it unless you are -aware of the consequences. - -It should be obvious, but any attributes added via the \dots -argument will not be carried back to the original data object, -as there would be no available storage slot/attribute. -} -\value{ -An S3 object of class \code{xts}. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{xts}}, \code{\link[zoo]{zoo}} } -\examples{ - \dontrun{ - # timeSeries - library(timeSeries) - x <- timeSeries(1:10, 1:10) - - str( as.xts(x) ) - str( reclass(as.xts(x)) ) - str( try.xts(x) ) - str( reclass(try.xts(x)) ) - } -} -\keyword{ utilities } diff --git a/man/axTicksByTime.Rd b/man/axTicksByTime.Rd index db267024..dc4c1d75 100644 --- a/man/axTicksByTime.Rd +++ b/man/axTicksByTime.Rd @@ -1,55 +1,72 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/axTicksByTime.R \name{axTicksByTime} \alias{axTicksByTime} - -\title{ Compute x-Axis Tickmark Locations by Time } -\description{ -Compute x-axis tickmarks like \code{axTicks} in base -but with respect to time. Additionally the first -argument is the object indexed by time which you -are looking to derive tickmark locations for. - -It is possible to specify the detail you are seeking, -or by passing 'auto' to the \code{ticks.on} argument, -to get a best heuristic fit. -} +\title{Compute x-Axis Tickmark Locations by Time} \usage{ -axTicksByTime(x, ticks.on='auto', k = 1, - labels=TRUE, format.labels=TRUE, ends=TRUE, - gt = 2, lt = 30) +axTicksByTime( + x, + ticks.on = "auto", + k = 1, + labels = TRUE, + format.labels = TRUE, + ends = TRUE, + gt = 2, + lt = 30 +) } \arguments{ - \item{x}{ the object indexed by time, or a vector of times/dates } - \item{ticks.on}{ what to break on } - \item{k}{ frequency of breaks } - \item{labels}{ should a labeled vector be returned } - \item{format.labels}{ format labels - may be format to use } - \item{ends}{ should the ends be adjusted } - \item{gt}{ lower bound on number of breaks } - \item{lt}{ upper bound on number of breaks } -} -\details{ -This function is written for internal use, and documented -for those wishing to use outside of the internal function -uses. In general it is most unlikely that the end user will -call this function directly. +\item{x}{An object indexed by time or a vector of times/dates.} + +\item{ticks.on}{Time unit for tick locations.} + +\item{k}{Frequency of tick locations.} + +\item{labels}{Should a labeled vector be returned?} + +\item{format.labels}{Either a logical value specifying whether labels should +be formatted, or a character string specifying the format to use.} + +\item{ends}{Should the ends be adjusted?} -The \code{format.labels} argument allows for standard formatting like -that used in \code{format}, \code{strptime}, and \code{strftime}. +\item{gt}{Lower bound on number of tick locations.} + +\item{lt}{Upper bound on number of tick locations.} } \value{ -A numeric vector of index element locations where tick marks should be drawn. -These are \emph{locations} (e.g. 1, 2, 3, ...), \emph{not} the index -timestamps. +A numeric vector of index element locations where tick marks should +be drawn. These are \emph{locations} (e.g. 1, 2, 3, ...), \emph{not} the +index timestamps. If possible, the result will be named using formatted values from the index timestamps. The names will be used for the tick mark labels. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}} } +\description{ +Compute x-axis tickmarks like \code{\link[=axTicks]{axTicks()}} in base but with respect to +time. This function is written for internal use, and documented for those +wishing to use it for customized plots. +} +\details{ +The default \code{ticks.on = "auto"} uses heuristics to compute sensible tick +locations. Use a combination of \code{ticks.on} and \code{k} to create tick locations +at specific intervals. For example, \code{ticks.on = "days"} and \code{k = 7} will +create tick marks every 7 days. + +When \code{format.labels} is a character string the possible values are the same +as those listed in the Details section of \code{\link[=strptime]{strptime()}}. +} \examples{ + data(sample_matrix) axTicksByTime(as.xts(sample_matrix),'auto') axTicksByTime(as.xts(sample_matrix),'weeks') axTicksByTime(as.xts(sample_matrix),'months',7) + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/coredata.xts.Rd b/man/coredata.xts.Rd index 392228bd..4422deab 100644 --- a/man/coredata.xts.Rd +++ b/man/coredata.xts.Rd @@ -1,57 +1,66 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/coredata.xts.R \name{coredata.xts} \alias{coredata.xts} \alias{xcoredata} \alias{xcoredata<-} -\title{ Extract/Replace Core Data of an xts Object } -\description{ -Mechanism to extract and replace the core data of an -\code{xts} object. -} +\title{Extract/Replace Core Data of an xts Object} \usage{ -\method{coredata}{xts}(x, fmt=FALSE, ...) +\method{coredata}{xts}(x, fmt = FALSE, ...) + +xcoredata(x, ...) -xcoredata(x,...) xcoredata(x) <- value } \arguments{ - \item{x}{ an \code{xts} object } - \item{fmt}{ should the rownames be formated in a non-standard way } - \item{value}{ non-core attributes to assign } - \item{\dots}{ further arguments [unused] } -} -\details{ -Extract coredata of an \code{xts} object - removing -all attributes except \code{dim} and \code{dimnames} and -returning a matrix object with rownames converted from -the index of the \code{xts} object. - -The \code{fmt} argument, if TRUE, allows the internal -index formatting specified by the user to be used. Alternatively, -it may be a valid formatting string to be passed to \code{format}. -Setting to FALSE will return the row names by simply -coercing the index class to a character string in the default -manner. - -\code{xcoredata} is the functional complement to -\code{coredata}, returning all of the attributes -normally removed by \code{coredata}. Its purpose, -along with the replacement function \code{xcoredata<-} -is primarily for use by developers using \pkg{xts} -to allow for internal replacement of values -removed during use of non xts-aware functions. +\item{x}{An xts object.} + +\item{fmt}{Should the rownames be formated using \code{tformat()}? Alternatively +a date/time string to be passed to \code{format()}. See details.} + +\item{\dots}{Unused.} + +\item{value}{Non-core attributes to assign.} } \value{ -Returns either a matrix object for coredata, or -a list of named attributes. +Returns either a matrix object for coredata, or a list of named +attributes. The replacement functions are called for their side-effects. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link[zoo:zoo]{coredata}}, \code{\link{xtsAttributes}} } +\description{ +Mechanism to extract and replace the core data of an xts object. +} +\details{ +Extract coredata of an xts object - removing all attributes except +\code{dim} and \code{dimnames} and returning a matrix object with rownames +converted from the index of the xts object. + +The rownames of the result use the format specified by \code{tformat(x)} when +\code{fmt = TRUE}. When \code{fmt} is a character string to be passed to \code{format()}. +See \code{\link[=strptime]{strptime()}} for valid format strings. Setting \code{fmt = FALSE} will +return the row names by simply coercing the index class to a character +string in the default manner. + +\code{xcoredata()} is the complement to \code{coredata()}. It returns all of the +attributes normally removed by \code{coredata()}. Its purpose, along with the +the replacement function \verb{xcoredata<-} is primarily for developers using +\pkg{xts}' \code{\link[=try.xts]{try.xts()}} and \code{\link[=reclass]{reclass()}} functionality inside functions +so the functions can take any time series class as an input and return the +same time series class. +} \examples{ + data(sample_matrix) x <- as.xts(sample_matrix, myattr=100) coredata(x) xcoredata(x) + +} +\seealso{ +\code{\link[zoo:zoo]{coredata()}}, \code{\link[=xtsAttributes]{xtsAttributes()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/diff.Rd b/man/diff.Rd deleted file mode 100644 index 4745c481..00000000 --- a/man/diff.Rd +++ /dev/null @@ -1,74 +0,0 @@ -\name{diff.xts} -\alias{diff.xts} -\alias{lag.xts} -\alias{lagts.xts} -\title{ Lags and Differences of xts Objects } -\description{ -Methods for computing lags and differences on \code{xts} objects. This -matches most of the functionality of \pkg{zoo} methods, with some default -argument changes. -} -\usage{ -\method{lag}{xts}(x, k = 1, na.pad = TRUE, ...) - -%\method{lagts}{xts}(x, k = 1, na.pad = TRUE, ...) -% -\method{diff}{xts}(x, lag = 1, differences = 1, arithmetic = TRUE, log = FALSE, na.pad = TRUE, ...) -} -\arguments{ - \item{x}{ an \code{xts} object } - \item{k}{ period to lag over } - \item{lag}{ period to difference over } - \item{differences}{ order of differencing } - \item{arithmetic}{ should arithmetic or geometric differencing be used } - \item{log}{ should (geometric) log differences be returned } - \item{na.pad}{ pad vector back to original size } - \item{\dots}{ additional arguments } -} -\details{ -The primary motivation for having methods specific to \code{xts} -was to make use of faster C-level code within xts. Additionally, -it was decided that \code{lag}'s default behavior should -match the common time-series interpretation of that operator --- specifically -that a value at time \sQuote{t} should be the value at time \sQuote{t-1} -for a positive lag. This is different than \code{lag.zoo} as well -as \code{lag.ts}. - -Another notable difference is that \code{na.pad} is set to -TRUE by default, to better reflect the transformation visually -and within functions requiring positional matching of data. - -Backwards compatability with zoo can be achieved by setting -\code{options(xts.compat.zoo.lag=TRUE)}. This will change the -defaults of lag.xts to k=-1 and na.pad=FALSE. - -%With the introduction of the new \code{lagts} generic in zoo, lag.xts -%will begin the process of reverting to zoo-behavior, i.e. negative -%k values will indicate positive lags. The current xts behavior will -%then move to lagts. The process by which this will happen will be -%a warning displayed in any lag.xts call at first, calling attention -%to the upcoming change. The new xts method for lagts will be be made available -%as of 0.8-1. Warning messages of the change will follow in subsequent releases. -} -\value{ -An \code{xts} object reflected the desired lag and/or differencing. -} -\references{ \url{https://en.wikipedia.org/wiki/Lag } } -\author{ Jeffrey A. Ryan } -\examples{ -x <- xts(1:10, Sys.Date()+1:10) -lag(x) # currently using xts-style positive k -%lagts(x) # same as original lag.xts, to allow for lag.xts to revert to R lag consistency - -lag(x, k=2) -%lagts(x, k=2) - -lag(x, k=-1, na.pad=FALSE) # matches lag.zoo(x, k=1) - -diff(x) -diff(x, lag=1) -diff(x, diff=2) -diff(diff(x)) -} -\keyword{ manip }% __ONLY ONE__ keyword per line -\keyword{ chron }% __ONLY ONE__ keyword per line diff --git a/man/diff.xts.Rd b/man/diff.xts.Rd new file mode 100644 index 00000000..4d0f7086 --- /dev/null +++ b/man/diff.xts.Rd @@ -0,0 +1,85 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/lag.xts.R +\name{lag.xts} +\alias{lag.xts} +\alias{diff.xts} +\title{Lags and Differences of xts Objects} +\usage{ +\method{lag}{xts}(x, k = 1, na.pad = TRUE, ...) + +\method{diff}{xts}( + x, + lag = 1, + differences = 1, + arithmetic = TRUE, + log = FALSE, + na.pad = TRUE, + ... +) +} +\arguments{ +\item{x}{An xts object.} + +\item{k}{Number of periods to shift.} + +\item{na.pad}{Should \code{NA} be added so the result has the same number of +observations as \code{x}?} + +\item{\dots}{Additional arguments.} + +\item{lag}{Period to difference over.} + +\item{differences}{Order of differencing.} + +\item{arithmetic}{Should arithmetic or geometric differencing be used?} + +\item{log}{Should (geometric) log differences be returned?} +} +\value{ +An xts object with the desired lag and/or differencing. +} +\description{ +Methods for computing lags and differences on xts objects. This provides +similar functionality as the \pkg{zoo} counterparts, but with some different +defaults. +} +\details{ +The primary motivation for these methods was to take advantage of a faster +C-level implementation. Another motivation was to make \code{lag()} behave using +standard sign for \code{k}. Both \code{\link[=lag.zoo]{lag.zoo()}} and \code{\link[=lag.default]{lag.default()}} require a +\emph{negative} value for \code{k} in order to shift a series backward. So \code{k = 1}, +shifts the series \emph{forward} one observation. This is especially confusing +because \code{k = 1} is the default for those functions. When \code{x} is an xts +object, \code{lag(x, 1)} returns an object where the value at time 't' is the +value at time 't-1' in the original object. + +Another difference is that \code{na.pad = TRUE} by default, to better reflect the +transformation visually and for functions the require positional alignment +of data. + +Set \code{options(xts.compat.zoo.lag = TRUE)} to use make \code{lag.xts()} consistent +with \code{lag.zoo()} by reversing the sign of \code{k} and setting \code{na.pad = FALSE}. +} +\examples{ + +x <- xts(1:10, Sys.Date()+1:10) +lag(x) # currently using xts-style positive k + +lag(x, k=2) + +lag(x, k=-1, na.pad=FALSE) # matches lag.zoo(x, k=1) + +diff(x) +diff(x, lag=1) +diff(x, diff=2) +diff(diff(x)) + +} +\references{ +\url{https://en.wikipedia.org/wiki/Lag} +} +\author{ +Jeffrey A. Ryan +} +\keyword{chron} +\keyword{manip} diff --git a/man/dimnames.xts.Rd b/man/dimnames.xts.Rd index b124557c..a3786686 100644 --- a/man/dimnames.xts.Rd +++ b/man/dimnames.xts.Rd @@ -1,71 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dimnames.R \name{dimnames.xts} \alias{dimnames.xts} \alias{dimnames<-.xts} -\title{ Dimnames of an xts Object } -\description{ -Get or set dimnames of an xts object. -} +\title{Dimnames of an xts Object} \usage{ \method{dimnames}{xts}(x) \method{dimnames}{xts}(x) <- value } \arguments{ - \item{x}{ an xts object } - \item{value}{ a list object of length two. See Details. } -} -\details{ -The functions \code{dimnames.xts} and \code{dimnames<-.xts} are -methods for the base functions \code{dimnames} and \code{dimnames<-}. - -\code{xts} objects by design are intended for lightweight management -of time-indexed data. - -Rownames are redundant in this design, as well -as quite burdensome with respect to memory consumption and -internal copying costs. - -\code{rownames} and \code{colnames} in \R make use of \code{dimnames} method -dispatch internally, and thus require only modifications -to dimnames to enforce the \code{xts} no rownames requirement. - -To prevent accidental setting of rownames, \code{dimnames<-} -for \code{xts} will simply set the rownames to \code{NULL} -when invoked, regardless of attempts to set otherwise. - -This is done for internal compatibility reasons, as well as -to provide consistency in performance regardless of object use. +\item{x}{An xts object.} -User level interaction with either dimnames or rownames will -produce a character vector of the index, formatted based -on the current specification of \code{indexFormat}. This -occurs within the call by converting the results -of calling \code{index(x)} to a character string, which itself -first creates the object type specified internally from the -underlying numeric time representation. +\item{value}{A two element list. See Details.} } \value{ -A list or character string containing coerced row names -and/or actual column names. +A list or character string containing coerced row names and/or +actual column names. -Attempts to set rownames on xts objects via rownames or dimnames -will silently fail. This is your warning. +Attempts to set rownames on xts objects via rownames or dimnames will +silently fail. } -\author{ Jeffrey A. Ryan } -\note{ -All \code{xts} objects have dimension. There are -no \code{xts} objects representable as named or unnamed -vectors. +\description{ +Get or set dimnames of an xts object. +} +\details{ +For efficienty, xts objects do not have rownames (unlike zoo objects). +Attempts to set rownames on an xts object will silently set them to \code{NULL}. +This is done for internal compatibility reasons, as well as to provide +consistency in performance regardless of object use. +} +\note{ +Unlike zoo, all xts objects have dimensions. xts objects cannot be +plain vectors. } -\seealso{ \code{\link{xts}} } \examples{ + x <- xts(1:10, Sys.Date()+1:10) dimnames(x) rownames(x) rownames(x) <- 1:10 rownames(x) str(x) + +} +\seealso{ +\code{\link[=xts]{xts()}} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ misc } +\keyword{misc} diff --git a/man/endpoints.Rd b/man/endpoints.Rd index 0f6bf422..fb447724 100644 --- a/man/endpoints.Rd +++ b/man/endpoints.Rd @@ -1,39 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/endpoints.R \name{endpoints} \alias{endpoints} -\title{ Locate Endpoints by Time } -\description{ -Extract index locations for an \code{xts} object that correspond to the -\emph{last} observation in each period specified by \code{on}. -} +\title{Locate Endpoints by Time} \usage{ -endpoints(x, on="months", k=1) +endpoints(x, on = "months", k = 1) } \arguments{ - \item{x}{ an xts object } - \item{on}{ the periods endpoints to find as a character string } - \item{k}{ along every k-th element - see notes } +\item{x}{An xts object.} + +\item{on}{A character string specifying the period.} + +\item{k}{The number of periods each endpoint should cover.} +} +\value{ +A numeric vector of beginning with 0 and ending with the number of +of observations in \code{x}. +} +\description{ +Extract index locations for an xts object that correspond to the \emph{last} +observation in each period specified by \code{on} and \code{k}. } \details{ -\code{endpoints} returns a numeric vector corresponding to the \emph{last} -observation in each period. The vector always begins with zero and ends with -the last observation in \code{x}. +\code{endpoints()} returns a numeric vector that always begins with zero and ends +with the number of observations in \code{x}. Periods are always based on the distance from the UNIX epoch (midnight -1970-01-01 UTC), \emph{not the first observation in \code{x}}. The examples -illustrate this behavior. +1970-01-01 UTC), \emph{not the first observation in \code{x}}. See the examples. -Valid values for the argument \code{on} include: \dQuote{us} (microseconds), +Valid values for the \code{on} argument are: \dQuote{us} (microseconds), \dQuote{microseconds}, \dQuote{ms} (milliseconds), \dQuote{milliseconds}, \dQuote{secs} (seconds), \dQuote{seconds}, \dQuote{mins} (minutes), \dQuote{minutes}, \dQuote{hours}, \dQuote{days}, \dQuote{weeks}, \dQuote{months}, \dQuote{quarters}, and \dQuote{years}. } -\value{ -A numeric vector of beginning with 0 and ending with the value equal to the -number of observations in the \code{x} argument. -} -\author{ Jeffrey A. Ryan } \examples{ + data(sample_matrix) endpoints(sample_matrix) @@ -50,4 +52,7 @@ ep <- endpoints(x, "years", k = 2) x[ep, ] } -\keyword{ utilities } +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/first.Rd b/man/first.Rd index b6cc90a7..ca52df50 100644 --- a/man/first.Rd +++ b/man/first.Rd @@ -1,3 +1,5 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/first.R, R/last.R \name{first} \alias{first} \alias{first.default} @@ -5,84 +7,66 @@ \alias{last} \alias{last.default} \alias{last.xts} -\title{ Return First or Last n Elements of A Data Object } -\description{ -A generic function to return the first or last -elements or rows of a vector or two-dimensional -data object. - -A more advanced subsetting is available for -zoo objects with indexes inheriting from POSIXt -or Date classes. -} +\title{Return First or Last n Elements of A Data Object} \usage{ -first(x,...) -last(x,...) +first(x, ...) -\method{first}{default}(x,n=1,keep=FALSE,...) +\method{first}{default}(x, n = 1, keep = FALSE, ...) -\method{last}{default}(x,n=1,keep=FALSE,...) +\method{first}{xts}(x, n = 1, keep = FALSE, ...) -\method{first}{xts}(x,n=1,keep=FALSE,...) +last(x, ...) -\method{last}{xts}(x,n=1,keep=FALSE,...) +\method{last}{default}(x, n = 1, keep = FALSE, ...) + +\method{last}{xts}(x, n = 1, keep = FALSE, ...) } \arguments{ - \item{x}{ 1 or 2 dimensional data object } - \item{n}{ number of periods to return } - \item{keep}{ should removed values be kept? } - \item{\dots}{ additional args - unused } -} -\details{ -Provides the ability to identify the first or last -\code{n} rows or observations of a data set. The generic -method behaves much like \code{head} and \code{tail} from -\pkg{base}, except by default only the \emph{first} or -\emph{last} observation will be returned. - -The more useful method for the xts class allows for -time based subsetting, given an xtsible object. - -\code{n} may be either a numeric value, indicating the number of -observations to return - forward from \code{first}, or backwards from \code{last}, -or it may be a character string describing the number and type of periods to -return. - -\code{n} may be positive or negative, in either numeric or character -contexts. When positive it will return the result expected - e.g. -\code{last(X,'1 month')} will return the last month's data. If negative, -all data will be returned \emph{except} for the last month. It is important -to note that this is not the same as calling \code{first(X,'1 month')} or -\code{first(X,'-1 month')}. All 4 variations return different subsets of -data and have distinct purposes. - -If \code{n} is a character string, it must be of the form \sQuote{n period.type} -or \sQuote{period.type}, -where \code{n} is a numeric value (defaults to 1 if not provided) -describing the number of \code{period.types} -to move forward (first) or back (last). - -For example, to return the last 3 weeks of a time oriented zoo object, one -could call \code{last(X,'3 weeks')}. Valid period.types are: secs, seconds, -mins, minutes, hours, days, weeks, months, quarters, and years. - -It is possible to use any frequency specification (secs, mins, days, \ldots) -for the period.type portion of the string, even if the original data is in -a higher frequency. This makes it possible to return the last \sQuote{2 months} -of data from an oject that has a daily periodicity. - -It should be noted that it is only possible to extract data with methods -equal to or less than the frequency of the original data set. Attempting otherwise -will result in error. - -Requesting more data than is in the original data object will produce a warning -advising as such, and the object returned will simply be the original data. +\item{x}{An object.} + +\item{\dots}{Arguments passed to other methods.} + +\item{n}{Number of observations to return.} + +\item{keep}{Should removed values be kept as an attribute on the result?} } \value{ -A subset of elements/rows of the original data. +A subset of elements/rows of the original data. +} +\description{ +Generic functions to return the first or last elements or rows of a vector +or two-dimensional data object. +} +\details{ +A more advanced subsetting is available for zoo objects with indexes +inheriting from POSIXt or Date classes. + +Quickly and easily extract the first or last \code{n} observations of an object. +When \code{n} is a number, these functions are similar to \code{\link[=head]{head()}} and +\code{\link[=tail]{tail()}}, but only return the \emph{first} or \emph{last} observation by default. + +\code{n} can be a character string if \code{x} is an xts object or coerceable to xts. +It must be of the form \sQuote{n period}, where 'n' is a numeric value +(1 if not provided) describing the number of periods to return. Valid +periods are: secs, seconds, mins, minutes, hours, days, weeks, months, +quarters, and years. + +The 'period' portion can be any frequency greater than or equal to the +frequency of the object's time index. For example, \code{first(x, "2 months")} +will return the first 2 months of data even if \code{x} is hourly frequency. +Attempts to set 'period' to a frequency less than the object's frequency +will throw an error. + +\code{n} may be positive or negative, whether it's a number or character string. +When \code{n} is positive, the functions return the obvious result. For example, +\code{first(x, "1 month")} returns the first month's data. When \code{n} is negative, +all data \emph{except} first month's is returned. + +Requesting more data than is in \code{x} will throw a warning and simply return +\code{x}. } -\author{ Jeffrey A. Ryan } \examples{ + first(1:100) last(1:100) @@ -97,5 +81,9 @@ first(x, '4 days') first(x, 'month') last(x, '2 months') last(x, '6 weeks') + +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/firstof.Rd b/man/firstof.Rd index 54a50cdf..5908801e 100644 --- a/man/firstof.Rd +++ b/man/firstof.Rd @@ -1,38 +1,56 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/endpoints.R \name{firstof} \alias{firstof} \alias{lastof} -\title{ Create a POSIXct Object } -\description{ -Enable fast creation of time stamps corresponding -to the first or last observation in a specified -time period. -} +\title{Create a POSIXct Object} \usage{ firstof(year = 1970, month = 1, day = 1, hour = 0, min = 0, sec = 0, tz = "") + +lastof( + year = 1970, + month = 12, + day = 31, + hour = 23, + min = 59, + sec = 59, + subsec = 0.99999, + tz = "" +) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{year,month,day}{ numerical values to specify a day } - \item{hour,min,sec}{ numerical vaues to specify time within a day } - \item{tz}{ timezone used for conversion } -} -\details{ -A wrapper to the \R function ISOdatetime with -defaults corresponding to the first or last -possible time in a given period. +\item{year, month, day}{Numeric values to specify a day.} + +\item{hour, min, sec}{Numeric vaues to specify time within a day.} + +\item{tz}{Timezone used for conversion.} + +\item{subsec}{Number of sub-seconds.} } \value{ -An object of class POSIXct. +An POSIXct object. +} +\description{ +Easily create of time stamps corresponding to the first or last observation +in a specified time period. +} +\details{ +This is a wrapper to \code{\link[=ISOdatetime]{ISOdatetime()}} with defaults corresponding to the +first or last possible time in a given period. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{ISOdatetime}} } \examples{ + firstof(2000) firstof(2005,01,01) lastof(2007) lastof(2007,10) + +} +\seealso{ +\code{\link[=ISOdatetime]{ISOdatetime()}} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ utilities } +\keyword{utilities} diff --git a/man/index.Rd b/man/index.Rd deleted file mode 100644 index 0a97b5fb..00000000 --- a/man/index.Rd +++ /dev/null @@ -1,226 +0,0 @@ -\name{index.xts} -\alias{index.xts} -\alias{index<-.xts} -\alias{.index} -\alias{.index<-} -\alias{.indexhour} -\alias{.indexsec} -\alias{.indexmin} -\alias{.indexyear} -\alias{.indexymon} -\alias{.indexyday} -\alias{.indexday} -\alias{.indexDate} -\alias{.indexmday} -\alias{.indexwday} -\alias{.indexweek} -\alias{.indexmon} -\alias{.indexisdst} -\alias{convertIndex} -\title{ Get and Replace the Class of an xts Index } -\description{ -Functions to get and replace an xts object's index values and it's components. -} -\usage{ -\method{index}{xts}(x, ...) -\method{index}{xts}(x) <- value - -.index(x, ...) -.index(x) <- value - -convertIndex(x, value) - -# date/time component extraction -.indexsec(x) -.indexmin(x) -.indexhour(x) - -.indexDate(x) -.indexday(x) -.indexwday(x) -.indexmday(x) - -.indexweek(x) -.indexmon(x) -.indexyear(x) -.indexyday(x) - -.indexisdst(x) -} -\arguments{ - \item{x}{ an \code{xts} object } - \item{value}{ new index value } - \item{\dots}{ arguments passed to other methods } -} -\details{ -Internally, an xts object's index is a \emph{numeric} value corresponding to -seconds since the epoch in the UTC timezone. The \code{.index} and -\code{.index<-} functions get and replace the internal \emph{numeric} value of -the index, respectively. These functions are primarily for internal use, but -are exported because they may be useful for users. - -The \code{index} and \code{index<-} methods get and replace the xts object's -index, respectively. The replacement method also updates the \code{\link{tclass}} -and \code{\link{tzone}} of the index to match the class and timezone of the new -index, respectively. The \code{index} method converts the index to the class -specified by the \code{\link{tclass}} attribute and with the timezone specified by -the \code{\link{tzone}} attribute before returning the index values to the user. - -% #### this is not true, it returns the original object as of 2023-02-02 #### -%The \code{convertIndex} function returns a modified \code{xts} object, and -%\emph{does not} alter the original. - -The \code{.indexXXX} functions extract time components (similar to -\code{\link{POSIXlt}} components) from the internal time index: - -\describe{ - \item{\code{.indexsec}}{0 - 61: seconds of the minute (local time)} - \item{\code{.indexmin}}{0 - 59: minutes of the hour (local time)} - \item{\code{.indexhour}}{0 - 23: hours of the day (local time)} - \item{\code{.indexDate}}{date as seconds since the epoch (UTC \emph{not local time}} - \item{\code{.indexday}}{date as seconds since the epoch (UTC \emph{not local time}} - \item{\code{.indexwday}}{0 - 6: day of the week (Sunday - Saturday, local time)} - \item{\code{.indexmday}}{1 - 31: day of the month (local time)} - \item{\code{.indexweek}}{weeks since the epoch (UTC \emph{not local time}} - \item{\code{.indexmon}}{0 - 11: month of the year (local time)} - \item{\code{.indexyear}}{years since 1900 (local time)} - \item{\code{.indexyday}}{0 - 365: day of the year (local time, 365 only in leap years)} - \item{\code{.indexisdst}}{1, 0, -1: Daylight Saving Time flag. Positive if Daylight - Saving Time is in effect, zero if not, negative if unknown.} -} - -Changes in timezone, index class, and index format internal structure, -by \pkg{xts} version: - -\describe{ - \item{Version 0.12.0:}{The \code{.indexTZ}, \code{.indexCLASS} and - \code{.indexFORMAT} attributes are no longer stored on xts objects, only - on the index itself. - - The \code{indexTZ}, \code{indexClass}, and \code{indexFormat} functions - (and their respective replacement methods) are deprecated in favor of their - respective \code{tzone}, \code{tclass}, and \code{tformat} versions. The - previous versions will throw a warning that they're deprecated, but they - will continue to work. There are no plans to remove them or have them - throw an error. Ever. - - The latter versions are careful to look for the old attributes on the xts - object, in case they're ever called on an xts object that was created prior - to the attributes being added to the index itself. - - There are options to throw a warning if there is no \code{tzone} or - \code{tclass} attribute on the index, even if there may be one on the xts - object. This gives the user a way to know if an xts object should be - updated to use the new structure. - - You can enable the warnings via: - \code{options(xts.warn.index.missing.tzone = TRUE, xts.warn.index.missing.tclass = TRUE)} - You can identify xts objects with the old structure by printing them. Then - you can update them to the new structure using \code{x <- as.xts(x)}. - } - \item{Version 0.9.8:}{The index timezone is now set to "UTC" for time classes - that do not have any intra-day component (e.g. days, months, quarters). - Previously the timezone was blank, which meant "local time" as determined - by R and the OS. - } - \item{Version 0.9.2:}{There are new get/set methods for the timezone, index - class, and index format attributes: \code{tzone} and, \code{tzone<-}, - \code{tclass} and \code{tclass<-}, and \code{tformat} and \code{tformat<-}. - - These new functions are aliases to their \code{indexTZ}, \code{indexClass}, - and \code{indexFormat} counterparts. - } - \item{Version 0.7.5:}{The timezone, index class, and index format were added - as attributes to the index itself, as \code{tzone}, \code{tclass}, and - \code{tformat}, respectively. This is in order to remove those three - attributes from the xts object, so they're only on the index itself. - - The \code{indexTZ}, \code{indexClass}, and \code{indexFormat} functions - (and their respective replacement methods) will continue to work as in - prior \pkg{xts} versions. The attributes on the index take priority over - their respective counterparts that may be on the xts object. - } - \item{Versions 0.6.4 and prior:}{Objects track their timezone and index class - in their \code{.indexTZ} and \code{.indexCLASS} attributes, respectively.} -} -} -\seealso{ -\code{\link{tformat}} describes how the index values are formatted when printed, -\code{\link{tclass}} provides details how \pkg{xts} handles the class of the index, -and \code{\link{tzone}} has more information about the index timezone settings. -} -\author{ Jeffrey A. Ryan } -\examples{ -x <- timeBasedSeq('2010-01-01/2010-01-01 12:00/H') -x <- xts(seq_along(x), x) - -# the index values, converted to 'tclass' (POSIXct in this case) -index(x) -class(index(x)) # POSIXct -tclass(x) # POSIXct - -# the internal numeric index -.index(x) -# add 1 hour (3600 seconds) to the numeric index -.index(x) <- index(x) + 3600 -index(x) - -y <- timeBasedSeq('2010-01-01/2010-01-02 12:00') -y <- xts(seq_along(y), y) - -# Select all observations in the first 6 and last 3 minutes of the -# 8th and 15th hours on each day -y[.indexhour(y) \%in\% c(8, 15) & .indexmin(y) \%in\% c(0:5, 57:59)] - -i <- 0:60000 -focal_date <- as.numeric(as.POSIXct("2018-02-01", tz = "UTC")) -y <- .xts(i, c(focal_date + i * 15), tz = "UTC", dimnames = list(NULL, "value")) - -# Select all observations for the first minute of each hour -y[.indexmin(y) == 0] - -# Select all observations on Monday -mon <- y[.indexwday(y) == 1] -head(mon) -tail(mon) -unique(weekdays(index(mon))) # check - -# Disjoint time of day selections - -# Select all observations between 08:30 and 08:59:59.9999 or between 12:00 and 12:14:59.99999: -y[.indexhour(y) == 8 & .indexmin(y) >= 30 | .indexhour(y) == 12 & .indexmin(x) \%in\% 0:14] - -### Compound selections - -# Select all observations for Wednesdays or Fridays between 9am and 4pm (exclusive of 4pm): -y[.indexwday(y) \%in\% c(3, 5) & (.indexhour(y) \%in\% c(9:15))] - -# Select all observations on Monday between 8:59:45 and 09:04:30: - -y[.indexwday(y) == 1 & (.indexhour(y) == 8 & .indexmin(y) == 59 & .indexsec(y) >= 45 | - .indexhour(y) == 9 & - (.indexmin(y) < 4 | .indexmin(y) == 4 & .indexsec(y) <= 30))] - -i <- 0:30000 -u <- .xts(i, c(focal_date + i * 1800), tz = "UTC", dimnames = list(NULL, "value")) - -# Select all observations for January or February: -u[.indexmon(u) \%in\% c(0, 1)] - -# Select all data for the 28th to 31st of each month, excluding any Fridays: -u[.indexmday(u) \%in\% 28:31 & .indexwday(u) != 5] - -# Subset by week since origin -unique(.indexweek(u)) -origin <- xts(1, as.POSIXct("1970-01-01")) -unique(.indexweek(origin)) - -# Select all observations in weeks 2515 to 2517. -u2 <- u[.indexweek(u) \%in\% 2515:2517] -head(u2); tail(u2) - -# Select all observations after 12pm for day 50 and 51 in each year -u[.indexyday(u) \%in\% 50:51 & .indexhour(u) >= 12] -} -\keyword{ts} -\keyword{utilities} diff --git a/man/index.xts.Rd b/man/index.xts.Rd new file mode 100644 index 00000000..e397a1c8 --- /dev/null +++ b/man/index.xts.Rd @@ -0,0 +1,244 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/index.R +\name{index.xts} +\alias{index.xts} +\alias{index<-.xts} +\alias{time<-.xts} +\alias{time.xts} +\alias{.index} +\alias{.index<-} +\alias{.indexsec} +\alias{.indexmin} +\alias{.indexhour} +\alias{.indexmday} +\alias{.indexmon} +\alias{.indexyear} +\alias{.indexwday} +\alias{.indexbday} +\alias{.indexyday} +\alias{.indexisdst} +\alias{.indexDate} +\alias{.indexday} +\alias{.indexweek} +\alias{.indexyweek} +\alias{convertIndex} +\title{Get and Replace the Class of an xts Index} +\usage{ +\method{index}{xts}(x, ...) + +\method{index}{xts}(x) <- value + +\method{time}{xts}(x) <- value + +\method{time}{xts}(x, ...) + +.index(x, ...) + +.index(x) <- value + +.indexsec(x) + +.indexmin(x) + +.indexhour(x) + +.indexmday(x) + +.indexmon(x) + +.indexyear(x) + +.indexwday(x) + +.indexbday(x) + +.indexyday(x) + +.indexisdst(x) + +.indexDate(x) + +.indexday(x) + +.indexweek(x) + +.indexyweek(x) + +convertIndex(x, value) +} +\arguments{ +\item{x}{An xts object.} + +\item{\dots}{Arguments passed to other methods.} + +\item{value}{A new time index value.} +} +\description{ +Functions to get and replace an xts object's index values and it's +components. +} +\details{ +An xts object's index is stored internally as the number of seconds since +UNIX epoch in the UTC timezone. The \code{.index()} and \verb{.index<-} functions get +and replace the internal numeric value of the index, respectively. These +functions are primarily for internal use, but are exported because they may +be useful for users. + +The replacement method also updates the \code{\link[=tclass]{tclass()}} and \code{\link[=tzone]{tzone()}} of the +index to match the class and timezone of the new index, respectively. The +\code{index()} method converts the internal numeric index to the class specified +by the 'tclass' attribute and with the timezone specified by the 'tzone' +attribute before returning the index values to the user. + +The \code{.indexXXX()} functions below extract time components from the internal +time index. They return values like the values of \link{POSIXlt} components. + +\describe{ +\item{\code{.indexsec}}{0 - 61: seconds of the minute (local time)} +\item{\code{.indexmin}}{0 - 59: minutes of the hour (local time)} +\item{\code{.indexhour}}{0 - 23: hours of the day (local time)} +\item{\code{.indexDate}}{date as seconds since the epoch (UTC \emph{not local time}} +\item{\code{.indexday}}{date as seconds since the epoch (UTC \emph{not local time}} +\item{\code{.indexwday}}{0 - 6: day of the week (Sunday - Saturday, local time)} +\item{\code{.indexmday}}{1 - 31: day of the month (local time)} +\item{\code{.indexweek}}{weeks since the epoch (UTC \emph{not local time}} +\item{\code{.indexmon}}{0 - 11: month of the year (local time)} +\item{\code{.indexyear}}{years since 1900 (local time)} +\item{\code{.indexyday}}{0 - 365: day of the year (local time, 365 only in leap years)} +\item{\code{.indexisdst}}{1, 0, -1: Daylight Saving Time flag. Positive if +Daylight Saving Time is in effect, zero if not, negative if unknown.} +} + +Changes in timezone, index class, and index format internal structure, by +\pkg{xts} version: + +\describe{ +\item{Version 0.12.0:}{The \code{.indexTZ}, \code{.indexCLASS} and \code{.indexFORMAT} +attributes are no longer stored on xts objects, only on the index itself. +\cr\cr +The \code{indexTZ()}, \code{indexClass()}, and \code{indexFormat()} functions (and +their respective replacement methods) are deprecated in favor of their +respective \code{tzone()}, \code{tclass()}, and \code{tformat()} versions. The previous +versions throw a warning that they're deprecated, but they will continue +to work. They will never be removed or throw an error. Ever. +\cr\cr +The new versions are careful to look for the old attributes on the xts +object, in case they're ever called on an xts object that was created prior +to the attributes being added to the index itself. +\cr\cr +You can set \code{options(xts.warn.index.missing.tzone = TRUE)} and +\code{options(xts.warn.index.missing.tclass = TRUE)} to identify xts objects +that do not have a 'tzone' or 'tclass' attribute on the index, even if +there is a 'tzone' or 'tclass' attribute on the xts object itself. The +warnings will be thrown when the object is printed. +Use \code{x <- as.xts(x)} to update these objects to the new structure.} + +\item{Version 0.9.8:}{The index timezone is now set to "UTC" for time classes +that do not have any intra-day component (e.g. days, months, quarters). +Previously the timezone was blank, which meant "local time" as determined by +\R and the OS.} + +\item{Version 0.9.2:}{There are new get/set methods for the timezone, index +class, and index format attributes: \code{tzone()} and, \verb{tzone<-}, \code{tclass()} +and \verb{tclass<-}, and \code{tformat()} and \verb{tformat<-}. These new functions are +aliases to their \code{indexTZ()}, \code{indexClass()}, and \code{indexFormat()} +counterparts.} + +\item{Version 0.7.5:}{The timezone, index class, and index format were added +as attributes to the index itself, as 'tzone', 'tclass', and 'tformat', +respectively. This is in order to remove those three attributes from the xts +object, so they're only on the index itself. +\cr\cr +The \code{indexTZ()}, \code{indexClass()}, and \code{indexFormat()} functions (and their +respective replacement methods) will continue to work as in prior \pkg{xts} +versions. The attributes on the index take priority over their respective +counterparts that may be on the xts object.} + +\item{Versions 0.6.4 and prior:}{Objects track their timezone and index class +in their '.indexTZ' and '.indexCLASS' attributes, respectively.} +} +} +\examples{ + +x <- timeBasedSeq('2010-01-01/2010-01-01 12:00/H') +x <- xts(seq_along(x), x) + +# the index values, converted to 'tclass' (POSIXct in this case) +index(x) +class(index(x)) # POSIXct +tclass(x) # POSIXct + +# the internal numeric index +.index(x) +# add 1 hour (3600 seconds) to the numeric index +.index(x) <- index(x) + 3600 +index(x) + +y <- timeBasedSeq('2010-01-01/2010-01-02 12:00') +y <- xts(seq_along(y), y) + +# Select all observations in the first 6 and last 3 minutes of the +# 8th and 15th hours on each day +y[.indexhour(y) \%in\% c(8, 15) & .indexmin(y) \%in\% c(0:5, 57:59)] + +i <- 0:60000 +focal_date <- as.numeric(as.POSIXct("2018-02-01", tz = "UTC")) +y <- .xts(i, c(focal_date + i * 15), tz = "UTC", dimnames = list(NULL, "value")) + +# Select all observations for the first minute of each hour +y[.indexmin(y) == 0] + +# Select all observations on Monday +mon <- y[.indexwday(y) == 1] +head(mon) +tail(mon) +unique(weekdays(index(mon))) # check + +# Disjoint time of day selections + +# Select all observations between 08:30 and 08:59:59.9999 or between 12:00 and 12:14:59.99999: +y[.indexhour(y) == 8 & .indexmin(y) >= 30 | .indexhour(y) == 12 & .indexmin(x) \%in\% 0:14] + +### Compound selections + +# Select all observations for Wednesdays or Fridays between 9am and 4pm (exclusive of 4pm): +y[.indexwday(y) \%in\% c(3, 5) & (.indexhour(y) \%in\% c(9:15))] + +# Select all observations on Monday between 8:59:45 and 09:04:30: + +y[.indexwday(y) == 1 & (.indexhour(y) == 8 & .indexmin(y) == 59 & .indexsec(y) >= 45 | + .indexhour(y) == 9 & + (.indexmin(y) < 4 | .indexmin(y) == 4 & .indexsec(y) <= 30))] + +i <- 0:30000 +u <- .xts(i, c(focal_date + i * 1800), tz = "UTC", dimnames = list(NULL, "value")) + +# Select all observations for January or February: +u[.indexmon(u) \%in\% c(0, 1)] + +# Select all data for the 28th to 31st of each month, excluding any Fridays: +u[.indexmday(u) \%in\% 28:31 & .indexwday(u) != 5] + +# Subset by week since origin +unique(.indexweek(u)) +origin <- xts(1, as.POSIXct("1970-01-01")) +unique(.indexweek(origin)) + +# Select all observations in weeks 2515 to 2517. +u2 <- u[.indexweek(u) \%in\% 2515:2517] +head(u2); tail(u2) + +# Select all observations after 12pm for day 50 and 51 in each year +u[.indexyday(u) \%in\% 50:51 & .indexhour(u) >= 12] + +} +\seealso{ +\code{\link[=tformat]{tformat()}} describes how the index values are formatted when +printed, \code{\link[=tclass]{tclass()}} documents how \pkg{xts} handles the index class, and +\code{\link[=tzone]{tzone()}} has more information about index timezone settings. +} +\author{ +Jeffrey A. Ryan +} +\keyword{ts} +\keyword{utilities} diff --git a/man/isOrdered.Rd b/man/isOrdered.Rd index 10a8864b..2f982ea7 100644 --- a/man/isOrdered.Rd +++ b/man/isOrdered.Rd @@ -1,28 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/isOrdered.R \name{isOrdered} \alias{isOrdered} -\title{ Check If A Vector Is Ordered } -\description{ -Performs check to determine if a vector is strictly increasing, -strictly decreasing, not decreasing, or not increasing. -} +\title{Check If A Vector Is Ordered} \usage{ isOrdered(x, increasing = TRUE, strictly = TRUE) } \arguments{ - \item{x}{ a numeric vector } - \item{increasing}{ test for increasing/decreasing values } - \item{strictly}{ are duplicates OK } -} -\details{ -Designed for internal use with \pkg{xts}, this provides -highly optimized tests for ordering. +\item{x}{A numeric vector.} + +\item{increasing}{Test for increasing (\code{TRUE}) or decreasing (\code{FALSE}) values?} + +\item{strictly}{When \code{TRUE}, vectors with duplicate values are \emph{not} +considered ordered.} } \value{ -Logical +A logical scalar indicating whether or not \code{x} is ordered. +} +\description{ +Check if a vector is strictly increasing, strictly decreasing, not +decreasing, or not increasing. +} +\details{ +Designed for internal use with \pkg{xts}, this provides highly optimized +tests for ordering. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{is.unsorted}} } \examples{ + # strictly increasing isOrdered(1:10, increasing=TRUE) isOrdered(1:10, increasing=FALSE) @@ -34,4 +38,10 @@ isOrdered(10:1, increasing=TRUE) isOrdered(10:1, increasing=FALSE) } -\keyword{ misc } +\seealso{ +\code{\link[=is.unsorted]{is.unsorted()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{misc} diff --git a/man/make.index.unique.Rd b/man/make.index.unique.Rd index 5c8412bf..157e362e 100644 --- a/man/make.index.unique.Rd +++ b/man/make.index.unique.Rd @@ -1,64 +1,51 @@ -\name{make.index.unique} -\alias{make.index.unique} -\alias{make.time.unique} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/align.time.R +\name{is.index.unique} \alias{is.index.unique} \alias{is.time.unique} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ -Force Time Values To Be Unique -} -\description{ -A generic function to force sorted time vectors to be -unique. Useful for high-frequency time-series where original -time-stamps may have identical values. For the case -of xts objects, the default \code{eps} is set to ten -microseconds. In practice this advances each subsequent -identical time by \code{eps} over the previous (possibly also -advanced) value. -} +\alias{make.index.unique} +\alias{make.time.unique} +\title{Force Time Values To Be Unique} \usage{ -make.index.unique(x, eps = 1e-06, drop=FALSE, fromLast=FALSE, ...) +is.index.unique(x) + +is.time.unique(x) -make.time.unique(x, eps = 1e-06, drop=FALSE, fromLast=FALSE, ...) +make.index.unique(x, eps = 1e-06, drop = FALSE, fromLast = FALSE, ...) + +make.time.unique(x, eps = 1e-06, drop = FALSE, fromLast = FALSE, ...) } \arguments{ - \item{x}{ -An xts object, or POSIXct vector. -} - \item{eps}{ -value to add to force uniqueness. -} - \item{drop}{ -drop duplicates instead of adjusting by \code{eps} -} - \item{fromLast}{ -if drop=TRUE, fromLast controls which duplicated times -are dropped. If fromLast=FALSE, the earliest observation -with an identical timestamp is kept with subsequent observations -dropped. +\item{x}{An xts object, or POSIXct vector.} + +\item{eps}{A value to add to force uniqueness.} + +\item{drop}{Should duplicates be dropped instead of adjusted by \code{eps}?} + +\item{fromLast}{When \code{drop = TRUE}, \code{fromLast} controls which duplicated +times are dropped. When \code{fromLast = FALSE}, the earliest observation with +an identical timestamp is kept and subsequent observations are dropped.} + +\item{\dots}{Unused.} } - \item{\dots}{ -unused +\value{ +A modified version of \code{x} with unique timestamps. } +\description{ +A generic function to force sorted time vectors to be unique. Useful for +high-frequency time-series where original time-stamps may have identical +values. For the case of xts objects, the default \code{eps} is set to ten +microseconds. In practice this advances each subsequent identical time by +\code{eps} over the previous (possibly also advanced) value. } \details{ -The returned time-series object will have new time-stamps -so that \code{isOrdered( .index(x) )} evaluates to TRUE. -} -\value{ -A modified version of x. -} -\author{ -Jeffrey A. Ryan +The returned time-series object will have new time-stamps so that +\code{isOrdered(.index(x))} evaluates to \code{TRUE}. } \note{ -Incoming values must be pre-sorted, and no check is done to -make sure that this is the case. If the index values are -of storage.mode \sQuote{integer}, they will be coerced -to \sQuote{double} if drop=FALSE. -} -\seealso{ -\code{\link{align.time}} +Incoming values must be pre-sorted, and no check is done to make sure +that this is the case. \sQuote{integer} index value will be coerced to +\sQuote{double} when \code{drop = FALSE}. } \examples{ @@ -69,7 +56,12 @@ x make.index.unique(x) options(ds) + +} +\seealso{ +\code{\link[=align.time]{align.time()}} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ ts } +\keyword{ts} diff --git a/man/merge.Rd b/man/merge.Rd deleted file mode 100644 index c1cd7c98..00000000 --- a/man/merge.Rd +++ /dev/null @@ -1,101 +0,0 @@ -\name{merge.xts} -\alias{merge.xts} -\alias{cbind.xts} -\title{ Merge xts Objects } -\description{ -Used to perform merge operation on \code{xts} objects -by \emph{time} (index). Given the -inherent ordered nature of \code{xts} time-series, a -merge-join style merge allows for optimally efficient -joins. -} -\usage{ -\method{merge}{xts}(..., - all = TRUE, - fill = NA, - suffixes = NULL, - join = "outer", - retside = TRUE, - retclass = "xts", - tzone = NULL, - drop=NULL, - check.names=NULL) -} -\arguments{ - \item{\dots}{ one or more xts objects, or objects coercible to class xts } - \item{all}{ a logical vector indicating merge type } - \item{fill}{ values to be used for missing elements } - \item{suffixes}{ to be added to merged column names } - \item{join}{ type of database join } - \item{retside}{ which side of the merged object should be returned (2-case only) } - \item{retclass}{ object to return } - \item{tzone}{ time zone of merged object } - \item{drop}{ not currently used } - \item{check.names}{ not currently used } -} -\details{ -This is an xts method compatible with merge.zoo, as xts extends zoo. -That documentation should also be referenced. -Difference are noted where applicable. - -Implemented almost entirely in custom C-level code, -it is possible using either the \code{all} argument or -the \code{join} argument to implement all common -database join operations along the to-be-merged objects -time-index: \sQuote{outer} (full outer - all rows), -\sQuote{inner} (only rows with common indexes), -\sQuote{left} (all rows in the left object, and those that match in the right), -and \sQuote{right} (all rows in the right object, and those that match in the left). - -The above join types can also be expressed as a vector of -logical values passed to \code{all}. c(TRUE,TRUE) or TRUE for \sQuote{join="outer"}, -c(FALSE,FALSE) or FALSE for \sQuote{join="inner"}, c(TRUE, FALSE) for \sQuote{join="left"}, -and c(FALSE,TRUE) for \sQuote{join="right"}. - -Note that the \code{all} and \code{join} arguments imply a two case scenario. For merging -more than two objects, they will simply fall back to a full outer or full inner join, -depending on the first position of all, as -left and right can be ambiguous with respect to sides. - -To do something along the lines of merge.zoo's method of joining based on -an all argument of the same length of the arguments to join, see the example. - -The resultant object will have the timezone of the leftmost -argument if available. Use \code{tzone} to override. - -If \code{retclass} is \code{NULL}, the joined objects will be split -and reassigned silently back to the original environment they are called -from. This is for backward compatibility with zoo, though unused -by xts. - -If \code{retclass} is \code{FALSE} the object will be stripped of -its class attribute. This is for internal use. -} -\value{ -A new \code{xts} object containing the appropriate -elements of the objects passed in to be merged. -} -\references{ Merge Join Discussion: \url{https://blogs.msdn.microsoft.com/craigfr/2006/08/03/merge-join/} } -\author{ Jeffrey A. Ryan } -\note{ -This is a highly optimized merge, specifically designed for ordered data. The -only supported merging is based on the underlying time index. -} -\examples{ -(x <- xts(4:10, Sys.Date()+4:10)) -(y <- xts(1:6, Sys.Date()+1:6)) - -merge(x,y) -merge(x,y, join='inner') -merge(x,y, join='left') -merge(x,y, join='right') - -merge.zoo(zoo(x),zoo(y),zoo(x), all=c(TRUE, FALSE, TRUE)) -merge(merge(x,x),y,join='left')[,c(1,3,2)] - -# zero-width objects (only index values) can be used -xi <- xts( , index(x)) -merge(y, xi) -} -\keyword{ manip } -\keyword{ utilities } diff --git a/man/merge.xts.Rd b/man/merge.xts.Rd new file mode 100644 index 00000000..1a2d5ebb --- /dev/null +++ b/man/merge.xts.Rd @@ -0,0 +1,119 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/merge.R +\name{merge.xts} +\alias{merge.xts} +\alias{cbind.xts} +\title{Merge xts Objects} +\usage{ +\method{merge}{xts}( + ..., + all = TRUE, + fill = NA, + suffixes = NULL, + join = "outer", + retside = TRUE, + retclass = "xts", + tzone = NULL, + drop = NULL, + check.names = NULL +) + +\method{cbind}{xts}(..., all = TRUE, fill = NA, suffixes = NULL) +} +\arguments{ +\item{\dots}{One or more xts objects, or objects coercible to class xts.} + +\item{all}{A logical vector indicating merge type.} + +\item{fill}{Values to be used for missing elements.} + +\item{suffixes}{Suffix to be added to merged column names.} + +\item{join}{Type of database join. One of 'outer', 'inner', 'left', or 'right'.} + +\item{retside}{Which side of the merged object should be returned (2-case only)?} + +\item{retclass}{Either a logical value indicating whether the result should +have a 'class' attribute, or the name of the desired class for the result.} + +\item{tzone}{Time zone to use for the merged result.} + +\item{drop}{Not currently used.} + +\item{check.names}{Use \code{\link[=make.names]{make.names()}} to ensure column names are vaild \R +object names?} +} +\value{ +A new xts object containing the appropriate elements of the +objects passed in to be merged. +} +\description{ +Perform merge operations on xts objects by time index. +} +\details{ +This xts method is compatible with \code{\link[=merge.zoo]{merge.zoo()}} but implemented almost +entirely in C-level code for efficiency. + +The function can perform all common database join operations along the time +index by setting 'join' to one of the values below. Note that 'left' and +'right' are only implemented for two objects. +\itemize{ +\item outer: full outer (all rows in all objects) +\item inner: only rows with common indexes in all objects +\item left: all rows in the first object, and rows from the second object that +have the same index as the first object +\item right: all rows in the second object, and rows from the first object that +have the same index as the second object +} + +The above join types can also be accomplished by setting 'all' to one of the +values below. +\itemize{ +\item outer: \code{all = TRUE} or \code{all = c(TRUE, TRUE)} +\item inner: \code{all = FALSE} or \code{all = c(FALSE, FALSE)} +\item left: \code{all = c(TRUE, FALSE)} +\item right: \code{all = c(FALSE, TRUE)} +} + +The result will have the timezone of the leftmost argument if available. Use +the 'tzone' argument to override the default behavior. + +When \code{retclass = NULL} the joined objects will be split and reassigned +silently back to the original environment they are called from. This is for +backward compatibility with zoo, but unused by xts. When \code{retclass = FALSE} +the object will be stripped of its class attribute. This is for internal use. + +See the examples in order to join using an 'all' argument that is the same +arguments to join, like you can do with \code{merge.zoo()}. +} +\note{ +This is a highly optimized merge, specifically designed for ordered +data. The only supported merging is based on the underlying time index. +} +\examples{ + +(x <- xts(4:10, Sys.Date()+4:10)) +(y <- xts(1:6, Sys.Date()+1:6)) + +merge(x,y) +merge(x,y, join='inner') +merge(x,y, join='left') +merge(x,y, join='right') + +merge.zoo(zoo(x),zoo(y),zoo(x), all=c(TRUE, FALSE, TRUE)) +merge(merge(x,x),y,join='left')[,c(1,3,2)] + +# zero-width objects (only index values) can be used +xi <- xts( , index(x)) +merge(y, xi) + +} +\references{ +Merge Join Discussion: +\url{https://learn.microsoft.com/en-us/archive/blogs/craigfr/merge-join} +} +\author{ +Jeffrey A. Ryan +} +\keyword{manip} +\keyword{utilities} diff --git a/man/na.locf.xts.Rd b/man/na.locf.xts.Rd index c6d2c39f..8459140b 100644 --- a/man/na.locf.xts.Rd +++ b/man/na.locf.xts.Rd @@ -1,55 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/na.R \name{na.locf.xts} \alias{na.locf.xts} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ -Last Observation Carried Forward -} -\description{ -\pkg{xts} method replace \sQuote{NA} with most recent non-\sQuote{NA} -} +\title{Last Observation Carried Forward} \usage{ -\method{na.locf}{xts}(object, na.rm = FALSE, fromLast = FALSE, maxgap=Inf, ...) +\method{na.locf}{xts}(object, na.rm = FALSE, fromLast = FALSE, maxgap = Inf, ...) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{object}{ -an xts object -} - \item{na.rm}{ -logical. Should leading/trailing \sQuote{NA}'s be removed? -The default for xts \code{FALSE} is different than the -default S3 method in the \pkg{zoo} package. -} - \item{fromLast}{ -logical. Cause observations to be carried backward rather -than forward. Default is \code{FALSE}. -} - \item{maxgap}{ -runs of more than \sQuote{maxgap} will retain \sQuote{NA}s after the -maximum gap specified. See \code{na.locf} in the zoo package. +\item{object}{An xts object.} + +\item{na.rm}{Logical indicating whether leading/trailing \code{NA} should be +removed. The default is \code{FALSE} unlike the zoo method.} + +\item{fromLast}{Logical indicating whether observations should be carried +backward rather than forward. Default is \code{FALSE}.} + +\item{maxgap}{Consecutive runs of observations more than 'maxgap' will +remain \code{NA}. See \code{\link[zoo:zoo]{na.locf()}} for details.} + +\item{\dots}{Unused.} } - \item{\dots}{ -unused +\value{ +An object where each \code{NA} in \code{object} is replaced by the most recent +non-NA prior to it. See \code{\link[zoo:zoo]{na.locf()}} for details. } +\description{ +\pkg{xts} method replace \code{NA} with most recent non-NA } \details{ -This is the \pkg{xts} method for the S3 generic \code{na.locf}. -The primary difference to note is that after the \sQuote{NA} -fill action is carried out, the default it to leave -trailing or leading \sQuote{NA}'s in place. This is different +This is the \pkg{xts} method for the S3 generic \code{na.locf()}. The primary +difference to note is that after the \code{NA} fill action is carried out, the +default it to leave trailing or leading \code{NA}'s in place. This is different than \pkg{zoo} behavior. } -\value{ -See the documentation in zoo. -} -\references{ -\sQuote{zoo} -} -\author{ -Jeffrey A. Ryan -} - \examples{ + x <- xts(1:10, Sys.Date()+1:10) x[c(1,2,5,9,10)] <- NA @@ -57,7 +42,12 @@ x na.locf(x) na.locf(x, fromLast=TRUE) na.locf(x, na.rm=TRUE, fromLast=TRUE) + +} +\seealso{ +\code{\link[zoo:zoo]{na.locf()}} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ misc } +\keyword{misc} diff --git a/man/ndays.Rd b/man/ndays.Rd index 7cb16f15..a80f1dfd 100644 --- a/man/ndays.Rd +++ b/man/ndays.Rd @@ -1,4 +1,6 @@ -\name{ndays} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/nperiods.R +\name{nseconds} \alias{nseconds} \alias{nminutes} \alias{nhours} @@ -7,50 +9,61 @@ \alias{nmonths} \alias{nquarters} \alias{nyears} -\title{ Number of Periods in Data } -\description{ -Calculate the number of specified periods in a given -time series like data object. -} +\title{Number of Periods in Data} \usage{ nseconds(x) + nminutes(x) + nhours(x) + ndays(x) + nweeks(x) + nmonths(x) + nquarters(x) + nyears(x) } \arguments{ - \item{x}{ A time-based object } +\item{x}{A time-based object.} +} +\value{ +The number of respective periods in \code{x}. +} +\description{ +Calculate the number of specified periods in a given time series like data +object. } \details{ -Essentially a wrapper to \code{endpoints} with the appropriate -period specified; the resulting value derived from counting the -endpoints +Essentially a wrapper to \code{endpoints()} with the appropriate period +specified. The result is the number of endpoints found. As a compromise between simplicity and accuracy, the results will always -round up to the nearest complete period. So n**** - 1 will return -the completed periods. +round up to the nearest complete period. Subtract 1 from the result to +get the completed periods. -For finer grain detail one should call -a higher frequency n**** function. +For finer grain detail one should call the higher frequency functions. -An alternative summary can be found with \code{periodicity} -and \code{unclass(periodicity(x))}. -} -\value{ -The number of observations for the period type specified +An alternative summary can be found with \code{periodicity(x)} and +\code{unclass(periodicity(x))}. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}} } \examples{ + \dontrun{ getSymbols("QQQQ") ndays(QQQQ) nweeks(QQQQ) } + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/parseISO8601.Rd b/man/parseISO8601.Rd index fb7a0f03..c06869c7 100644 --- a/man/parseISO8601.Rd +++ b/man/parseISO8601.Rd @@ -1,94 +1,57 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/parse8601.R \name{.parseISO8601} +\alias{.parseISO8601} \alias{ISO8601} -\Rdversion{1.1} \alias{parseISO8601} -\alias{makeISO8601} -\alias{.parseISO8601} -\alias{.makeISO8601} -\title{ -Internal ISO 8601:2004(e) Time Parser -} -\description{ -This function is used internally in the subsetting -mechanism of xts. The function is unexported, though -documented for use with xts subsetting. -} +\title{Internal ISO 8601:2004(e) Time Parser} \usage{ -.parseISO8601(x, start, end, tz="") - -.makeISO8601(x) +.parseISO8601(x, start, end, tz = "") } \arguments{ - \item{x}{ -For .parseISO8601(x), a character string conforming -to the ISO 8601:2004(e) rules. For .makeISO8601(x), \code{x} -should be a time-like object with -\code{start} and \code{end} methods. -} - \item{start}{ -lower constraint on range -} - \item{end}{ -upper constraint of range -} - \item{tz}{ -timezone (tzone) to use internally -} -} -\details{ -This function replicates most of the ISO -standard for expressing time and time-based -ranges in a universally accepted way. - -The best documentation is now the official -ISO page as well as the Wikipedia entry for -ISO 8601:2004. +\item{x}{A character string conforming to the ISO 8601:2004(e) rules.} -The basic idea is to create -the endpoints of a range, given a string -representation. These endpoints are aligned -in POSIXct time to the zero second of the day -at the beginning, and the 59.9999th second of the 59th -minute of the 23rd hour of the final day. +\item{start}{Lower constraint on range.} -For dates prior to the epoch (1970-01-01) the -ending time is aligned to the 59.0000 second. This -is due to a bug/feature in the \R implementation of -asPOSIXct and mktime0 at the C-source level. This limits -the precision of ranges prior to 1970 to 1 minute -granularity with the current \pkg{xts} workaround. +\item{end}{Upper constraint of range} -Recurring times over multiple days may be specified -using the T notation. See the examples for details. +\item{tz}{Timezone (tzone) to use internally.} } \value{ -A list of length two, with an entry -named \sQuote{first.time} and one -names \sQuote{last.time}. - -For .makeISO8601, a character vector of length -one describing the ISO-style format for a given -time-based object. +A two element list with an entry named \sQuote{first.time} and +one named \sQuote{last.time}. } -\references{ -\url{https://en.wikipedia.org/wiki/ISO_8601}\cr -\url{https://www.iso.org/iso-8601-date-and-time-format.html} +\description{ +This function replicates most of the ISO standard for parsing times and +time-based ranges in a universally accepted way. The best documentation is +the official ISO page as well as the Wikipedia entry for ISO 8601:2004. } -\author{ -Jeffrey A. Ryan +\details{ +The basic idea is to create the endpoints of a range, given a string +representation. These endpoints are aligned in POSIXct time to the zero +second of the day at the beginning, and the 59.9999th second of the 59th +minute of the 23rd hour of the final day. + +For dates prior to the epoch (1970-01-01) the ending time is aligned to the +59.0000 second. This is due to a bug/feature in the \R implementation of +\code{as.POSIXct()} and \code{mktime0()} at the C-source level. This limits the +precision of ranges prior to 1970 to 1 minute granularity with the current +\pkg{xts} workaround. + +Recurring times over multiple days may be specified using the "T" notation. +See the examples for details. } \note{ -There is no checking done to test for a properly constructed -ISO format string. This must be correctly entered by the user, lest -bad things may happen. +There is no checking done to test for a properly constructed ISO +format string. This must be correctly entered by the user. -When using durations, it is important to note that the -time of the duration specified is not necessarily the -same as the realized periods that may be returned when -applied to an irregular time series. This is not a bug, -rather it is a standards and implementation gotcha. +When using durations, it is important to note that the time of the duration +specified is not necessarily the same as the realized periods that may be +returned when applied to an irregular time series. This is not a bug, it is +a standards and implementation gotcha. } \examples{ + # the start and end of 2000 .parseISO8601('2000') @@ -106,7 +69,13 @@ rather it is a standards and implementation gotcha. # 8:30 to 15:00 (used in xts subsetting to extract recurring times) .parseISO8601('T08:30/T15:00') + +} +\references{ +\url{https://en.wikipedia.org/wiki/ISO_8601}\cr +\url{https://www.iso.org/iso-8601-date-and-time-format.html} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ utilities } +\keyword{utilities} diff --git a/man/period.apply.Rd b/man/period.apply.Rd index ab412786..bfc3f2bd 100644 --- a/man/period.apply.Rd +++ b/man/period.apply.Rd @@ -1,64 +1,75 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/period.apply.R \name{period.apply} \alias{period.apply} -\title{ Apply Function Over Specified Interval } -\description{ -Apply a specified function to data over intervals specified by \code{INDEX}. -The intervals are defined as the observations from \code{INDEX[k]+1} to -\code{INDEX[k+1]}, for \code{k = 1:(length(INDEX)-1)}. -} +\title{Apply Function Over Specified Interval} \usage{ period.apply(x, INDEX, FUN, ...) } \arguments{ - \item{x}{ The data that FUN will be applied to. } - \item{INDEX}{ A numeric vector of index breakpoint locations. The vector - should begin with 0 and end with \code{NROW(x)}. } - \item{FUN}{ A \code{function} to apply to each interval in \code{x}. } - \item{\dots}{ Additional arguments for \code{FUN}. } +\item{x}{The data that \code{FUN} will be applied to.} + +\item{INDEX}{A numeric vector of index breakpoint locations. The vector +should begin with 0 and end with \code{nrow(x)}.} + +\item{FUN}{A function to apply to each interval in \code{x}.} + +\item{\dots}{Additional arguments for \code{FUN}.} +} +\value{ +An object with \code{length(INDEX) - 1} observations, assuming \code{INDEX} +starts with 0 and ends with \code{nrow(x)}. +} +\description{ +Apply a specified function to data over intervals specified by \code{INDEX}. The +intervals are defined as the observations from \code{INDEX[k]+1} to \code{INDEX[k+1]}, +for \code{k = 1:(length(INDEX)-1)}. } \details{ Similar to the rest of the apply family, \code{period.apply()} calculates the specified function's value over a subset of data. The primary difference is -that \code{period.apply()} applies the function to non-overlapping intervals -of a vector or matrix. +that \code{period.apply()} applies the function to non-overlapping intervals of a +vector or matrix. -Useful for applying functions over an entire data object by any non-overlapping -intervals. For example, when \code{INDEX} is the result of a call to -\code{endpoints()}. +Useful for applying functions over an entire data object by any +non-overlapping intervals. For example, when \code{INDEX} is the result of a +call to \code{endpoints()}. -\code{period.apply()} checks that \code{INDEX} is sorted, unique, starts with -0, and ends with \code{NROW(x)}. All those conditions are true of vectors -returned by \code{endpoints()}. +\code{period.apply()} checks that \code{INDEX} is sorted, unique, starts with 0, and +ends with \code{nrow(x)}. All those conditions are true of vectors returned by +\code{endpoints()}. } \note{ - When \code{FUN = mean} the results will contain one column for every column - in the input, which is different from other math functions (e.g. \code{median}, - \code{sum}, \code{prod}, \code{sd}, etc.). +When \code{FUN = mean} the results will contain one column for every +column in the input, which is different from other math functions (e.g. +\code{median}, \code{sum}, \code{prod}, \code{sd}, etc.). - \code{FUN = mean} works by column because the default method \code{stats::mean} - used to work by column for matrices and data.frames. R Core changed the - behavior of \code{mean} to always return one column in order to be consistent - with the other math functions. This broke some \pkg{xts} dependencies and - \code{mean.xts} was created to maintain the original behavior. +\code{FUN = mean} works by column because the default method \code{stats::mean} +previously worked by column for matrices and data.frames. R Core changed the +behavior of \code{mean} to always return one column in order to be consistent +with the other math functions. This broke some \pkg{xts} dependencies and +\code{mean.xts()} was created to maintain the original behavior. - Using \code{FUN = mean} will print a message that describes this inconsistency. - To avoid the message and confusion, use \code{FUN = colMeans} to calculate - means by column and use \code{FUN = function(x) mean} to calculate one mean - for all the data. Set \code{options(xts.message.period.apply.mean = FALSE)} - to suppress this message. -} -\value{ -An object with \code{length(INDEX) - 1} observations (assuming \code{INDEX} -starts with 0 and ends with \code{NROW(x)}). +Using \code{FUN = mean} will print a message that describes this inconsistency. +To avoid the message and confusion, use \code{FUN = colMeans} to calculate means +by column and use \code{FUN = function(x) mean} to calculate one mean for all the +data. Set \code{options(xts.message.period.apply.mean = FALSE)} to suppress this +message. } -\author{ Jeffrey A. Ryan, Joshua M. Ulrich } -\seealso{ \code{\link{endpoints}} \code{\link{apply.monthly}}} \examples{ + zoo.data <- zoo(rnorm(31)+10,as.Date(13514:13744,origin="1970-01-01")) ep <- endpoints(zoo.data,'weeks') period.apply(zoo.data, INDEX=ep, FUN=function(x) colMeans(x)) period.apply(zoo.data, INDEX=ep, FUN=colMeans) #same period.apply(letters,c(0,5,7,26), paste0) + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}} \code{\link[=apply.monthly]{apply.monthly()}} +} +\author{ +Jeffrey A. Ryan, Joshua M. Ulrich } -\keyword{ utilities }% __ONLY ONE__ keyword per line +\keyword{utilities} diff --git a/man/period.max.Rd b/man/period.max.Rd deleted file mode 100644 index ec716172..00000000 --- a/man/period.max.Rd +++ /dev/null @@ -1,37 +0,0 @@ -\name{period.max} -\alias{period.max} -\title{ Calculate Max By Period } -\description{ -Calculate a maximum for each period of INDEX. Essentially a rolling -application of maximum over a series of non-overlapping sections. -} -\usage{ -period.max(x, INDEX) -} -\arguments{ - \item{x}{ a univariate data object } - \item{INDEX}{ a numeric vector of endpoints to calculate maximum on } -} -\details{ -Used to calculate a maximum per period given an arbitrary -index of sections to be calculated over. This is an optimized function -for maximum. There are additional optimized versions for min, sum, and -prod. - -For xts-coercible objects, an appropriate INDEX can be derived -from a call to 'endpoints'. -} -\value{ -An xts or zoo object of maximums, indexed by the period endpoints. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}}, \code{\link{period.sum}}, - \code{\link{period.min}}, \code{\link{period.prod}} } -\examples{ -period.max(c(1,1,4,2,2,6,7,8,-1,20),c(0,3,5,8,10)) - -data(sample_matrix) -period.max(sample_matrix[,1],endpoints(sample_matrix)) -period.max(as.xts(sample_matrix)[,1],endpoints(sample_matrix)) -} -\keyword{ utilities }% __ONLY ONE__ keyword per line diff --git a/man/period.min.Rd b/man/period.min.Rd deleted file mode 100644 index e5b1b006..00000000 --- a/man/period.min.Rd +++ /dev/null @@ -1,37 +0,0 @@ -\name{period.min} -\alias{period.min} -\title{ Calculate Min By Period } -\description{ -Calculate a minimum for each period of INDEX. Essentially a rolling -application of minimum over a series of non-overlapping sections. -} -\usage{ -period.min(x, INDEX) -} -\arguments{ - \item{x}{ a univariate data object } - \item{INDEX}{ a numeric vector of endpoints to calculate maximum on } -} -\details{ -Used to calculate a minimum per period given an arbitrary -index of sections to be calculated over. This is an optimized function -for minimum. There are additional optimized versions for max, sum, and -prod. - -For xts-coercible objects, an appropriate INDEX -can be derived from a call to \code{endpoints}. -} -\value{ -An xts or zoo object of minimums, indexed by the period endpoints. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}}, \code{\link{period.sum}}, - \code{\link{period.max}}, \code{\link{period.prod}} } -\examples{ -period.min(c(1,1,4,2,2,6,7,8,-1,20),c(0,3,5,8,10)) - -data(sample_matrix) -period.min(sample_matrix[,1],endpoints(sample_matrix)) -period.min(as.xts(sample_matrix)[,1],endpoints(sample_matrix)) -} -\keyword{ utilities }% __ONLY ONE__ keyword per line diff --git a/man/period.prod.Rd b/man/period.prod.Rd deleted file mode 100644 index 7d4a77ac..00000000 --- a/man/period.prod.Rd +++ /dev/null @@ -1,38 +0,0 @@ -\name{period.prod} -\alias{period.prod} -\title{ Calculate Product By Period } -\description{ -Calculate a product for each period of INDEX. Essentially a rolling -application of prod over a series of non-overlapping sections. -} -\usage{ -period.prod(x, INDEX) -} -\arguments{ - \item{x}{ a univariate data object } - \item{INDEX}{ a vector of breakpoints to calculate product on } -} -\details{ -Used to calculate a product per period given an arbitrary -index of sections to be calculated over. This is an optimized function -for product. There are additionally optimized versions for min, max, and -sum. - -For xts-coercible objects, an appropriate INDEX can be -derived from a call to \code{endpoints}. -} -\value{ -An \code{xts} or \code{zoo} object of products, -indexed by the period endpoints. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}}, \code{\link{period.sum}}, - \code{\link{period.min}}, \code{\link{period.max}} } -\examples{ -period.prod(c(1,1,4,2,2,6,7,8,-1,20),c(0,3,5,8,10)) - -data(sample_matrix) -period.prod(sample_matrix[,1],endpoints(sample_matrix)) -period.prod(as.xts(sample_matrix)[,1],endpoints(sample_matrix)) -} -\keyword{ utilities }% __ONLY ONE__ keyword per line diff --git a/man/period.sum.Rd b/man/period.sum.Rd deleted file mode 100644 index 022e4424..00000000 --- a/man/period.sum.Rd +++ /dev/null @@ -1,38 +0,0 @@ -\name{period.sum} -\alias{period.sum} -\title{ Calculate Sum By Period } -\description{ -Calculate a sum for each period of INDEX. Essentially a rolling -application of sum over a series of non-overlapping sections. -} -\usage{ -period.sum(x, INDEX) -} -\arguments{ - \item{x}{ a univariate data object } - \item{INDEX}{ a numeric vector of endpoints to calculate sum on } -} -\details{ -Used to calculate a sum per period given an arbitrary -index of sections to be calculated over. This is an optimized function -for sum. There are additionally optimized versions for min, max, and -prod. - -For xts-coercible objects, an appropriate INDEX can be derived -from a call to \code{endpoints}. -} -\value{ -An \code{xts} or \code{zoo} object of sums, -indexed by the period endpoints. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{endpoints}}, \code{\link{period.max}}, - \code{\link{period.min}}, \code{\link{period.prod}} } -\examples{ -period.sum(c(1,1,4,2,2,6,7,8,-1,20),c(0,3,5,8,10)) - -data(sample_matrix) -period.sum(sample_matrix[,1],endpoints(sample_matrix)) -period.sum(as.xts(sample_matrix)[,1],endpoints(sample_matrix)) -} -\keyword{ utilities }% __ONLY ONE__ keyword per line diff --git a/man/period_math.Rd b/man/period_math.Rd new file mode 100644 index 00000000..70244191 --- /dev/null +++ b/man/period_math.Rd @@ -0,0 +1,72 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/period.R +\name{period.sum} +\alias{period.sum} +\alias{period.prod} +\alias{period.max} +\alias{period.min} +\title{Optimized Calculations By Period} +\usage{ +period.sum(x, INDEX) + +period.prod(x, INDEX) + +period.max(x, INDEX) + +period.min(x, INDEX) +} +\arguments{ +\item{x}{A univariate data object.} + +\item{INDEX}{A numeric vector of endpoints for each period.} +} +\value{ +An xts or zoo object containing the sum, product, minimum, or +maximum for each endpoint in \code{INDEX}. +} +\description{ +Calculate a sum, product, minimum, or maximum for each non-overlapping +period specified by \code{INDEX}. +} +\details{ +These functions are similar to calling \code{period.apply()} with the same +endpoints and function. There may be slight differences in the results due +to numerical accuracy. + +For xts-coercible objects, an appropriate \code{INDEX} can be created by a call +to \code{endpoints()}. +} +\examples{ + +x <- c(1, 1, 4, 2, 2, 6, 7, 8, -1, 20) +i <- c(0, 3, 5, 8, 10) + +period.sum(x, i) +period.prod(x, i) +period.min(x, i) +period.max(x, i) + +data(sample_matrix) +y <- sample_matrix[, 1] +ep <- endpoints(sample_matrix) + +period.sum(y, ep) +period.sum(as.xts(y), ep) + +period.prod(y, ep) +period.prod(as.xts(y), ep) + +period.min(y, ep) +period.min(as.xts(y), ep) + +period.max(y, ep) +period.max(as.xts(y), ep) + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}}, \code{\link[=period.apply]{period.apply()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/periodicity.Rd b/man/periodicity.Rd index 376b2aa1..844187e4 100644 --- a/man/periodicity.Rd +++ b/man/periodicity.Rd @@ -1,59 +1,66 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/periodicity.R \name{periodicity} \alias{periodicity} -\title{ Approximate Series Periodicity } -\description{ -Estimate the periodicity of a time-series-like -object by calculating the median time between -observations in days. -} +\title{Approximate Series Periodicity} \usage{ periodicity(x, ...) } \arguments{ - \item{x}{ time-series-like object } - \item{\dots}{ unused } -} -\details{ -A simple wrapper to quickly estimate the periodicity -of a given data. Returning an object of type \code{periodicity}. +\item{x}{A time-series-like object.} -This calculates the -median number of days between observations -as a difftime object, the numerical difference, -the units of measurement, -and the derived scale of the data as a string. +\item{\dots}{Unused.} +} +\value{ +A 'periodicity' object with the following elements: +\itemize{ +\item the \code{difftime} object, +\item frequency: the median time difference between observations +\item start: the first observation +\item end: the last observation +\item units: one of secs, mins, hours, or days +\item scale: one of seconds, minute, hourly, daily, weekly, monthly, quarterly, or yearly +\item label: one of second, minute, hour, day, week, month, quarter, year +} -The time index currently must be of either \code{Date} -or \code{POSIX} class, or coercible to such. +Possible \code{scale} values are: \sQuote{minute}, \sQuote{hourly}, \sQuote{daily}, +\sQuote{weekly}, \sQuote{monthly}, \sQuote{quarterly}, and \sQuote{yearly}. +} +\description{ +Estimate the periodicity of a time-series-like object by calculating the +median time between observations in days. +} +\details{ +A simple wrapper to quickly estimate the periodicity of a given data. +Returning an object of type \code{periodicity}. -The only list item of note is the \code{scale}. -This is an estimate of the periodicity of the data -in common terms - e.g. 7 day daily data is best -described as \sQuote{weekly}, and would be returned as -such. +This calculates the median time difference between observations as a +difftime object, the numerical difference, the units of measurement, and the +derived scale of the data as a string. -Possible \code{scale} values are: +The time index currently must be of either a 'Date' or 'POSIXct' class, or +or coercible to one of them. -\sQuote{minute},\sQuote{hourly}, -\sQuote{daily},\sQuote{weekly}, -\sQuote{monthly},\sQuote{quarterly}, -and \sQuote{yearly}. -} -\value{ -An object containing a list containing the \code{difftime} object, -frequency, units, and suitable scale. +The 'scale' component of the result is an estimate of the periodicity of the +data in common terms - e.g. 7 day daily data is best described as 'weekly', +and would be returned as such. } \note{ -This function is only a \emph{good estimate} for -the underlying periodicity. If the series is too -short, or has \emph{no} real periodicity, the return -values will obviously be wrong. That said, it is quite -robust and used internally within \pkg{xts}. -} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{difftime}} } +This function only attempts to be a \emph{good estimate} for the underlying +periodicity. If the series is too short, or has highly irregular periodicity, +the return values will not be accurate. That said, it is quite robust and +used internally within \pkg{xts}. +} \examples{ + zoo.ts <- zoo(rnorm(231),as.Date(13514:13744,origin="1970-01-01")) periodicity(zoo.ts) + +} +\seealso{ +\code{\link[=difftime]{difftime()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/plot.xts.Rd b/man/plot.xts.Rd index 803e8daa..552ce4f2 100644 --- a/man/plot.xts.Rd +++ b/man/plot.xts.Rd @@ -1,135 +1,170 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R \name{plot.xts} \alias{plot.xts} \alias{lines.xts} \alias{points.xts} \title{Plotting xts Objects} \usage{ -\method{plot}{xts}(x, y = NULL, ..., subset = "", - panels = NULL, multi.panel = FALSE, col = 1:8, up.col = NULL, - dn.col = NULL, bg = "#FFFFFF", type = "l", lty = 1, lwd = 2, lend = 1, - main = deparse(substitute(x)), main.timespan = TRUE, observation.based = FALSE, - log = FALSE, ylim = NULL, yaxis.same = TRUE, yaxis.left = TRUE, yaxis.right = TRUE, - yaxis.ticks = 5, major.ticks = "auto", minor.ticks = NULL, - grid.ticks.on = "auto", grid.ticks.lwd = 1, grid.ticks.lty = 1, - grid.col = "darkgray", labels.col = "#333333", format.labels = TRUE, - grid2 = "#F5F5F5", legend.loc = NULL, extend.xaxis = FALSE) -\method{lines}{xts}(x, ..., main = "", on = 0, col = NULL, type = "l", - lty = 1, lwd = 1, pch = 1) +\method{plot}{xts}( + x, + y = NULL, + ..., + subset = "", + panels = NULL, + multi.panel = FALSE, + col = 1:8, + up.col = NULL, + dn.col = NULL, + bg = "#FFFFFF", + type = "l", + lty = 1, + lwd = 2, + lend = 1, + main = deparse(substitute(x)), + main.timespan = TRUE, + observation.based = FALSE, + log = FALSE, + ylim = NULL, + yaxis.same = TRUE, + yaxis.left = TRUE, + yaxis.right = TRUE, + yaxis.ticks = 5, + major.ticks = "auto", + minor.ticks = NULL, + grid.ticks.on = "auto", + grid.ticks.lwd = 1, + grid.ticks.lty = 1, + grid.col = "darkgray", + labels.col = "#333333", + format.labels = TRUE, + grid2 = "#F5F5F5", + legend.loc = NULL, + extend.xaxis = FALSE +) + +\method{lines}{xts}( + x, + ..., + main = "", + on = 0, + col = NULL, + type = "l", + lty = 1, + lwd = 1, + pch = 1 +) + \method{points}{xts}(x, ..., main = "", on = 0, col = NULL, pch = 1) } \arguments{ -\item{x}{xts object} +\item{x}{A xts object.} -\item{y}{NULL, not used} +\item{y}{Not used, always \code{NULL}.} -\item{\dots}{any passthrough graphical arguments for \code{lines} and \code{points}} +\item{\dots}{Any passthrough arguments for \code{lines()} and \code{points()}.} -\item{subset}{character vector of length one of the subset range using subsetting as in \code{\link{xts}}} +\item{subset}{An ISO8601-style subset string.} -\item{panels}{character vector of expressions to plot as panels} +\item{panels}{Character vector of expressions to plot as panels.} -\item{multi.panel}{TRUE/FALSE or an integer less than or equal to the number -of columns in the data set. If TRUE, each column of the data is plotted in a -separate panel. For example, if \code{multi.panel = 2}, then the data -will be plotted in groups of 2 columns and each group is plotted in a -separate panel.} +\item{multi.panel}{Either \code{TRUE}, \code{FALSE}, or an integer less than or equal +to the number of columns in the data set. When \code{TRUE}, each column of the +data is plotted in a separate panel. When an integer 'n', the data will be +plotted in groups of 'n' columns per panel and each group will be plotted +in a separate panel.} -\item{col}{color palette to use, set by default to rational choices} +\item{col}{Color palette to use.} -\item{up.col}{color for positive bars if \code{type="h"}} +\item{up.col}{Color for positive bars when \code{type = "h"}.} -\item{dn.col}{color for negative bars if \code{type="h"}} +\item{dn.col}{Color for negative bars when \code{type = "h"}.} -\item{bg}{background color of plotting area, same as in \code{\link{par}}} +\item{bg}{Background color of plotting area, same as in \code{\link[=par]{par()}}.} -\item{type}{the type of plot to be drawn, same as in \code{\link{plot}}} +\item{type}{The type of plot to be drawn, same as in \code{\link[=plot]{plot()}}.} -\item{lty}{set the line type, same as in \code{\link{par}}} +\item{lty}{Set the line type, same as in \code{\link[=par]{par()}}.} -\item{lwd}{set the line width, same as in \code{\link{par}}} +\item{lwd}{Set the line width, same as in \code{\link[=par]{par()}}.} -\item{lend}{set the line end style, same as in \code{\link{par}}} +\item{lend}{Set the line end style, same as in \code{\link[=par]{par()}}.} -\item{main}{main title} +\item{main}{Main plot title.} -\item{main.timespan}{include the timespan of the series on the plot? (default \code{TRUE})} +\item{main.timespan}{Should the timespan of the series be shown in the top +right corner of the plot?} -\item{observation.based}{TRUE/FALSE (default FALSE). If \code{TRUE}, the x-axis is drawn based on observations in the data. If \code{FALSE}, the x-axis is drawn based on the time index of the data.} +\item{observation.based}{When \code{TRUE}, all the observations are equally spaced +along the x-axis. When \code{FALSE} (the default) the observations on the x-axis +are spaced based on the time index of the data.} -\item{log}{TRUE/FALSE (default FALSE). If \code{TRUE}, the y-axis is drawn in log-scale} +\item{log}{Should the y-axis be in log scale? Default \code{FALSE}.} -\item{ylim}{the range of the y axis} +\item{ylim}{The range of the y axis.} -\item{yaxis.same}{TRUE/FALSE. If TRUE, the y axis is drawn with the same ylim for multiple panels} +\item{yaxis.same}{Should 'ylim' be the same for every panel? Default \code{TRUE}.} -\item{yaxis.left}{if TRUE, draws the y axis on the left} +\item{yaxis.left}{Add y-axis labels to the left side of the plot?} -\item{yaxis.right}{if TRUE, draws the y axis on the right} +\item{yaxis.right}{Add y-axis labels to the right side of the plot?} -\item{yaxis.ticks}{desired number of y axis grid lines. The actual number - of grid lines is determined by the \code{n} argument to \code{\link{pretty}}.} +\item{yaxis.ticks}{Desired number of y-axis grid lines. The actual number of +grid lines is determined by the \code{n} argument to \code{\link[=pretty]{pretty()}}.} -\item{major.ticks}{period that specifies where tick marks and labels will be - drawn on the x-axis. See Details for possible values.} +\item{major.ticks}{Period specifying locations for major tick marks and labels +on the x-axis. See Details for possible values.} -\item{minor.ticks}{period that specifies where minor ticks on will be drawn on - the x-axis. If \code{NULL}, minor ticks are not drawn. See Details for - possible values.} +\item{minor.ticks}{Period specifying locations for minor tick marks on the +x-axis. When \code{NULL}, minor ticks are not drawn. See details for possible +values.} -\item{grid.ticks.on}{period that specifies where vertical grid lines will be - drawn. See Details for possible values.} +\item{grid.ticks.on}{Period specifying locations for vertical grid lines. +See details for possible values.} -\item{grid.ticks.lwd}{line width of the grid} +\item{grid.ticks.lwd}{Line width of the grid.} -\item{grid.ticks.lty}{line type of the grid} +\item{grid.ticks.lty}{Line type of the grid.} -\item{grid.col}{color of the grid} +\item{grid.col}{Color of the grid.} -\item{labels.col}{color of the axis labels} +\item{labels.col}{Color of the axis labels.} -\item{format.labels}{label format to draw lower frequency x-axis ticks and labels passed to \code{\link{axTicksByTime}}} +\item{format.labels}{Label format to draw lower frequency x-axis ticks and +labels passed to \code{\link[=axTicksByTime]{axTicksByTime()}}} -\item{grid2}{color for secondary x axis grid} +\item{grid2}{Color for secondary x-axis grid.} -\item{legend.loc}{places a legend into one of nine locations on the chart: +\item{legend.loc}{Places a legend into one of nine locations on the chart: bottomright, bottom, bottomleft, left, topleft, top, topright, right, or -center. Default NULL does not draw a legend.} +center. Default \code{NULL} does not draw a legend.} -\item{pch}{the plotting character to use, same as in \code{\link{par}}.} +\item{extend.xaxis}{When \code{TRUE}, extend the x-axis before and/or after the +plot's existing time index range, so all of of the time index values of +the new series are included in the plot. Default \code{FALSE}.} -\item{on}{panel number to draw on. A new panel will be drawn if \code{on=NA}. -The default, \code{on=0}, will add to the active panel. The active panel is -defined as the panel on which the most recent action was performed. Note that -only the first element of \code{on} is checked for the default behavior to +\item{on}{Panel number to draw on. A new panel will be drawn if \code{on = NA}. +The default, \code{on = 0}, will add to the active panel. The active panel is +defined as the panel on which the most recent action was performed. Note +that only the first element of \code{on} is checked for the default behavior to add to the last active panel.} -\item{extend.xaxis}{TRUE/FALSE (default FALSE). If TRUE, extend the x-axis -before and/or after the plot's existing time index range, so all of of the -time index values of the new series are included in the plot.} - -} -\details{ - Possible values for arguments \code{major.ticks}, \code{minor.ticks}, - and \code{grid.ticks.on} include \sQuote{auto}, \sQuote{minute}, - \sQuote{hours}, \sQuote{days}, \sQuote{weeks}, \sQuote{months}, - \sQuote{quarters}, and \sQuote{years}. The default is \sQuote{auto}, which - attempts to determine sensible locations from the periodicity and locations - of observations. The other values are based on the possible values for the - \code{ticks.on} argument of \code{\link{axTicksByTime}}. +\item{pch}{the plotting character to use, same as in 'par'} } \description{ Plotting for xts objects. } -\author{ -Ross Bennett -} -\references{ -based on \code{chart_Series} in the \code{quantmod} package by Jeffrey A. Ryan -} -\seealso{ -\code{\link{addSeries}}, \code{\link{addPanel}} +\details{ +Possible values for arguments \code{major.ticks}, \code{minor.ticks}, and +\code{grid.ticks.on} include \sQuote{auto}, \sQuote{minute}, \sQuote{hours}, +\sQuote{days}, \sQuote{weeks}, \sQuote{months}, \sQuote{quarters}, and +\sQuote{years}. The default is \sQuote{auto}, which attempts to determine +sensible locations from the periodicity and locations of observations. The +other values are based on the possible values for the \code{ticks.on} +argument of \code{\link[=axTicksByTime]{axTicksByTime()}}. } \examples{ + \dontrun{ data(sample_matrix) sample.xts <- as.xts(sample_matrix) @@ -138,7 +173,7 @@ sample.xts <- as.xts(sample_matrix) plot(sample.xts[,"Close"]) # plot a subset of the data -plot(sample.xts[,"Close"], subset="2007-04-01/2007-06-31") +plot(sample.xts[,"Close"], subset = "2007-04-01/2007-06-31") # function to compute simple returns simple.ret <- function(x, col.name){ @@ -148,20 +183,31 @@ simple.ret <- function(x, col.name){ # plot the close and add a panel with the simple returns plot(sample.xts[,"Close"]) R <- simple.ret(sample.xts, "Close") -lines(R, type="h", on=NA) +lines(R, type = "h", on = NA) # add the 50 period simple moving average to panel 1 of the plot library(TTR) -lines(SMA(sample.xts[,"Close"], n = 50), on=1, col="blue") +lines(SMA(sample.xts[,"Close"], n = 50), on = 1, col = "blue") # add month end points to the chart points(sample.xts[endpoints(sample.xts[,"Close"], on = "months"), "Close"], - col="red", pch=17, on=1) + col = "red", pch = 17, on = 1) # add legend to panel 1 -addLegend("topright", on=1, +addLegend("topright", on = 1, legend.names = c("Close", "SMA(50)"), - lty=c(1, 1), lwd=c(2, 1), - col=c("black", "blue", "red")) + lty = c(1, 1), lwd = c(2, 1), + col = c("black", "blue", "red")) +} + +} +\references{ +based on \code{\link[quantmod:quantmod-package]{chart_Series()}} in \pkg{quantmod} +written by Jeffrey A. Ryan +} +\seealso{ +\code{\link[=addSeries]{addSeries()}}, \code{\link[=addPanel]{addPanel()}} } +\author{ +Ross Bennett } diff --git a/man/print.Rd b/man/print.Rd deleted file mode 100644 index 9a91a3fe..00000000 --- a/man/print.Rd +++ /dev/null @@ -1,38 +0,0 @@ -\name{print.xts} -\alias{print.xts} -\title{ Print An xts Time-Series Object } -\description{ - Method for printing an extensible time-series object. -} -\usage{ -\method{print}{xts}(x, fmt, ..., show.rows = 10, max.rows = 100) -} - -\arguments{ - \item{x}{ An xts object } - \item{fmt}{ Passed to \code{\link{coredata}} to format the time index } - \item{\dots}{ Arguments passed to other methods } - \item{show.rows}{ The number of first and last rows to print if the number of - rows is truncated (default 10, or \code{getOption("xts.print.show.rows")}) } - \item{max.rows}{ The output will contain at most \code{max.rows} rows before - being truncated (default 100, or \code{getOption("xts.print.max.rows")}) } -} -%\details{ -% Add notes about truncated rows, columns, any addition descriptive information we add -% -%} -\value{ - Returns \code{x} invisibly. -} -\author{ Joshua M. Ulrich } -\examples{ -data(sample_matrix) -sample.xts <- as.xts(sample_matrix) - -# output is truncated and shows first and last 10 observations -print(sample.xts) - -# show the first and last 5 observations -print(sample.xts, show.rows = 5) -} -\keyword{ print } diff --git a/man/print.xts.Rd b/man/print.xts.Rd new file mode 100644 index 00000000..bcebc559 --- /dev/null +++ b/man/print.xts.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/print.R +\name{print.xts} +\alias{print.xts} +\title{Print An xts Time-Series Object} +\usage{ +\method{print}{xts}(x, fmt, ..., show.rows = 10, max.rows = 100) +} +\arguments{ +\item{x}{An xts object.} + +\item{fmt}{Passed to \code{\link[=coredata]{coredata()}} to format the time index.} + +\item{\dots}{Arguments passed to other methods.} + +\item{show.rows}{The number of first and last rows to print if the number of +rows is truncated (default 10, or \code{getOption("xts.print.show.rows")}).} + +\item{max.rows}{The output will contain at most \code{max.rows} rows before being +truncated (default 100, or \code{getOption("xts.print.max.rows")}).} +} +\value{ +Returns \code{x} invisibly. +} +\description{ +Method for printing an extensible time-series object. +} +\examples{ + +data(sample_matrix) +sample.xts <- as.xts(sample_matrix) + +# output is truncated and shows first and last 10 observations +print(sample.xts) + +# show the first and last 5 observations +print(sample.xts, show.rows = 5) + +} +\author{ +Joshua M. Ulrich +} +\keyword{print} diff --git a/man/rbind.xts.Rd b/man/rbind.xts.Rd index 414f500f..d02b1f4e 100644 --- a/man/rbind.xts.Rd +++ b/man/rbind.xts.Rd @@ -1,62 +1,44 @@ -\name{rbind.xts} -\alias{rbind.xts} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/bind.R +\name{c.xts} \alias{c.xts} -\title{ Concatenate Two or More xts Objects by Row } -\description{ -Concatenate or bind by row two or more xts objects -along a time-based index. -} +\alias{rbind.xts} +\title{Concatenate Two or More xts Objects by Row} \usage{ \method{c}{xts}(...) \method{rbind}{xts}(..., deparse.level = 1) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{\dots}{ objects to bind } - \item{deparse.level}{ not implemented } -} -\details{ -Implemented in C, these functions bind \code{xts} objects -by row, resulting in another \code{xts} object - -There may be non-unique index -values in either the original series, or -the resultant series. - -Identical indexed series are bound in the order -or the arguments passed to rbind. See examples. - -All objects must have the same number of -columns, as well as be \code{xts} objects -or coercible to such. +\item{\dots}{Objects to bind by row.} -\code{rbind} and \code{c} are aliases. - -For traditional merge operations, see \code{merge.xts} and -\code{cbind.xts}. +\item{deparse.level}{Not implemented.} } \value{ -An \code{xts} object with one row per row -for each object concatenated. +An xts object with one row per row for each object concatenated. +} +\description{ +Concatenate or bind by row two or more xts objects along a time-based index. +All objects must have the same number of columns and be xts objects or +coercible to xts. } -\author{ Jeffrey A. Ryan } -\note{ -This differs from rbind.zoo in that non-unique index values are allowed, -in addition to the completely different algorithms used internally. +\details{ +Duplicate index values are supported. When one or more input has the same +index value, the duplicated index values in the result are in the same order +the objects are passed to \code{rbind()}. See examples. -All operations may not behave as expected on objects with non-unique -indices. You have been warned. +\code{c()} is an alias for \code{rbind()} for xts objects. -\code{rbind} is a .Primitive function in \R. As such -method dispatch occurs at the C-level, and may not be -consistent with expectations. See the details section -of the base function, and if needed call rbind.xts directly -to avoid dispatch ambiguity. +See \code{\link[=merge.xts]{merge.xts()}} for traditional merge operations. +} +\note{ +\code{rbind()} is a '.Primitive' function in \R, which means method dispatch +occurs at the C-level, and may not be consistent with normal S3 method +dispatch (see \code{\link[=rbind]{rbind()}} for details). Call \code{rbind.xts()} directly to +avoid potential dispatch ambiguity. } -\seealso{ \code{\link{merge.xts}} - \code{\link{rbind}} } \examples{ + x <- xts(1:10, Sys.Date()+1:10) str(x) @@ -75,6 +57,10 @@ rbind(x,y) rbind(y,x) } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ utilities } +\seealso{ +\code{\link[=merge.xts]{merge.xts()}} \code{\link[=rbind]{rbind()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/reclass.Rd b/man/reclass.Rd new file mode 100644 index 00000000..94574d4c --- /dev/null +++ b/man/reclass.Rd @@ -0,0 +1,98 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/reclass.R +\name{try.xts} +\alias{try.xts} +\alias{use.xts} +\alias{reclass} +\alias{Reclass} +\alias{use.reclass} +\title{Convert Objects to xts and Back to Original Class} +\usage{ +try.xts(x, ..., error = TRUE) + +reclass(x, match.to, error = FALSE, ...) + +Reclass(x) +} +\arguments{ +\item{x}{Data object to convert. See details for supported types.} + +\item{\dots}{Additional parameters or attributes.} + +\item{error}{Error handling option. See Details.} + +\item{match.to}{An xts object whose attributes will be copied to the result.} +} +\value{ +\code{try.xts()} returns an xts object when conversion is successful. +The \code{error} argument controls the function's behavior when conversion fails. + +\code{Reclass()} and \code{reclass()} return the object as its original class, as +specified by the 'CLASS' attribute. +} +\description{ +Functions to convert objects of arbitrary classes to xts and then back to +the original class, without losing any attributes of the original class. +} +\details{ +A simple and reliable way to convert many different objects into a uniform +format for use within \R. + +\code{try.xts()} and \code{reclass()} are functions that enable external developers +access to the reclassing tools within \pkg{xts} to help speed development of +time-aware functions, as well as provide a more robust and seemless end-user +experience, regardless of the end-user's choice of data-classes. + +\code{try.xts()} calls \code{as.xts()} internally. See \code{\link[=as.xts]{as.xts()}} for available xts +methods and arguments for each coercible class. Since it calls \code{as.xts()}, +you can add custom attributes as \code{name = value} pairs in the same way. But +these custom attributes will not be copied back to the original object when +\code{reclass()} is called. + +The \code{error} argument can be a logical value indicating whether an error +should be thrown (or fail silently), a character string allowing for custom +error error messages, or a function of the form \code{f(x, ...)} that will be +called if the conversion fails. + +\code{reclass()} converts an object created by \code{try.xts()} back to its original +class with all the original attributes intact (unless they were changed +after the object was converted to xts). The \code{match.to} argument allows you +copy the index attributes (\code{\link{tclass}}, \code{\link{tformat}}, and \code{\link{tzone}}) and +\code{\link[=xtsAttributes]{xtsAttributes()}} from another xts object to the result. \code{match.to} must +be an xts object with an index value for every observation in \code{x}. + +\code{Reclass()} is designed for top-level use, where it is desirable to have +the object returned from an arbitrary function in the same class as the +object passed in. Most functions in \R are not designed to return objects +matching the original object's class. It attempts to handle conversion and +reconversion transparently but it requires the original object must be +coercible to xts, the result of the function must have the same number of +rows as the input, and the object to be converted/reclassed must be the +first argument to the function being wrapped. Note that this function +hasn't been tested for robustness. + +See the accompanying vignette for more details on the above usage. +} +\examples{ + +a <- 1:10 + +# fails silently, the result is still an integer vector +try.xts(a, error = FALSE) + +# control the result with a function +try.xts(a, error = function(x, ...) { "I'm afraid I can't do that." }) + +z <- zoo(1:10, timeBasedSeq("2020-01-01/2020-01-10")) +x <- try.xts(z) # zoo to xts +str(x) +str(reclass(x)) # reclass back to zoo + +} +\seealso{ +\code{\link[=as.xts]{as.xts()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/sample.data.Rd b/man/sample.data.Rd index 7daae993..44462725 100644 --- a/man/sample.data.Rd +++ b/man/sample.data.Rd @@ -1,21 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts-package.R +\docType{data} \name{sample_matrix} \alias{sample_matrix} -\docType{data} -\title{ Sample Data Matrix For xts Example and Unit Testing } -\description{ -Simulated 180 observations on 4 variables. -} -\usage{data(sample_matrix)} +\title{Sample Data Matrix For xts Example and Unit Testing} \format{ -\preformatted{ - The format is: - num [1:180, 1:4] 50.0 50.2 50.4 50.4 50.2 ... - - attr(*, "dimnames")=List of 2 - ..$ : chr [1:180] "2007-01-02" "2007-01-03" "2007-01-04" "2007-01-05" ... - ..$ : chr [1:4] "Open" "High" "Low" "Close" +\preformatted{The format is: + num [1:180, 1:4] 50.0 50.2 50.4 50.4 50.2 ... + - attr(*, "dimnames")=List of 2 + ..$ : chr [1:180] "2007-01-02" "2007-01-03" "2007-01-04" "2007-01-05" ... + ..$ : chr [1:4] "Open" "High" "Low" "Close" } +} +\usage{ +data(sample_matrix) } +\description{ +Simulated 180 observations on 4 variables. } \examples{ -data(.sample.matrix) + +data(sample_matrix) + } \keyword{datasets} diff --git a/man/split.Rd b/man/split.Rd deleted file mode 100644 index 9ca76189..00000000 --- a/man/split.Rd +++ /dev/null @@ -1,72 +0,0 @@ -\name{split.xts} -\Rdversion{1.1} -\alias{split.xts} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ -Divide into Groups by Time -} -\description{ -Creates a list of xts objects split along -time periods. -} -\usage{ -\method{split}{xts}(x, f = "months", drop=FALSE, k = 1, ...) -} -%- maybe also 'usage' for other objects documented here. -\arguments{ - \item{x}{ -an xts object -} - \item{f}{ -a 'character' vector describing the period to split by -} - \item{drop}{ -ignored by split.xts -} - \item{k}{ -number of periods to aggregate into each split. See Details. -} - \item{\dots}{ -further args to non-xts method -} -} -\details{ -A quick way to break up a large xts -object by standard time periods; e.g. 'months', 'quarters', etc. - -\code{endpoints} is used to find the start and end of -each period (or k-periods). See that function for valid -arguments. - -If \code{f} is not a character vector, the NextMethod is -called, which would in turn dispatch to the split.zoo method. -} -\value{ -A list of xts objects. -} -\author{ -Jeffrey A. Ryan -} -\note{ -\code{aggregate.zoo} would be more flexible, though not as fast -for xts objects. -} - - -\seealso{ -\code{\link{endpoints}}, -\code{\link[zoo]{split.zoo}}, -\code{\link[zoo]{aggregate.zoo}} -} -\examples{ -data(sample_matrix) -x <- as.xts(sample_matrix) - - -split(x) -split(x, f="weeks") -split(x, f="weeks", k=4) -} -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ utilities } diff --git a/man/split.xts.Rd b/man/split.xts.Rd new file mode 100644 index 00000000..5b2b73fe --- /dev/null +++ b/man/split.xts.Rd @@ -0,0 +1,56 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/split.R +\name{split.xts} +\alias{split.xts} +\title{Divide into Groups by Time} +\usage{ +\method{split}{xts}(x, f = "months", drop = FALSE, k = 1, ...) +} +\arguments{ +\item{x}{An xts object.} + +\item{f}{A character vector describing the period to split by.} + +\item{drop}{Ignored by \code{split.xts()}.} + +\item{k}{Number of periods to aggregate into each split. See details.} + +\item{\dots}{Further arguments passed to other methods.} +} +\value{ +A list of xts objects. +} +\description{ +Creates a list of xts objects split along time periods. +} +\details{ +A quick way to break up a large xts object by standard time periods; e.g. +'months', 'quarters', etc. + +\code{\link[=endpoints]{endpoints()}} is used to find the start and end of each period (or +k-periods). See that function for valid arguments. + +The inputs are passed to \code{\link[=split.zoo]{split.zoo()}} when \code{f} is not a character vector. +} +\note{ +\code{\link[=aggregate.zoo]{aggregate.zoo()}} is more flexible, though not as fast for xts +objects. +} +\examples{ + +data(sample_matrix) +x <- as.xts(sample_matrix) + + +split(x) +split(x, f="weeks") +split(x, f="weeks", k=4) + +} +\seealso{ +\code{\link[=endpoints]{endpoints()}}, \code{\link[zoo:zoo]{split.zoo()}}, \code{\link[zoo:zoo]{aggregate.zoo()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/subset.xts.Rd b/man/subset.xts.Rd index 4ac64dc7..4c23b1a2 100644 --- a/man/subset.xts.Rd +++ b/man/subset.xts.Rd @@ -1,123 +1,85 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts.methods.R \name{[.xts} -\Rdversion{1.1} \alias{[.xts} \alias{subset.xts} \alias{.subset.xts} \alias{.subset_xts} -\title{ -Extract Subsets of xts Objects -} -\description{ -Details on efficient subsetting of \code{xts} objects -for maximum performance and compatibility. -} +\title{Extract Subsets of xts Objects} \usage{ -\method{[}{xts}(x, i, j, drop = FALSE, which.i=FALSE, ...) +\method{[}{xts}(x, i, j, drop = FALSE, which.i = FALSE, ...) } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{x}{ - xts object -} - \item{i}{ - the rows to extract. Numeric, timeBased or ISO-8601 style (see details) -} - \item{j}{ - the columns to extract, numeric or by name -} - \item{drop}{ - should dimension be dropped, if possible. See NOTE. -} - \item{which.i}{ - return the \sQuote{i} values used for subsetting. No -subset will be performed. +\item{x}{An xts object.} + +\item{i}{The rows to extract. Can be a numeric vector, time-based vector, or +an ISO-8601 style range string (see details).} + +\item{j}{The columns to extract, either a numeric vector of column locations +or a character vector of column names.} + +\item{drop}{Should dimension be dropped, if possible? See notes section.} + +\item{which.i}{Logical value that determines whether a subset xts object is +returned (the default), or the locations of the matching rows (when +\code{which.i = TRUE}).} + +\item{\dots}{Additional arguments (currently unused).} } - \item{\dots}{ - additional arguments (unused) +\value{ +An xts object containing the subset of \code{x}. When \code{which.i = TRUE}, +the corresponding integer locations of the matching rows is returned. } +\description{ +Details on efficient subsetting of xts objects for maximum performance +and compatibility. } \details{ -One of the primary motivations, and key points of differentiation -of the time series class xts, is the ability to subset rows -by specifying ISO-8601 compatible range strings. This allows -for natural range-based time queries without requiring prior -knowledge of the underlying time object used in construction. +One of the primary motivations and key points of differentiation of xts is +the ability to subset rows by specifying ISO-8601 compatible range strings. +This allows for natural range-based time queries without requiring prior +knowledge of the underlying class used for the time index. -When a raw character vector is used for the \code{i} -subset argument, it is processed as if it was ISO-8601 -compliant. This means that it is parsed from left to -right, according to the following specification: +When \code{i} is a character string, it is processed as an ISO-8601 formatted +datetime or time range using \code{\link[=.parseISO8601]{.parseISO8601()}}. A single datetime is +parsed from left to to right, according to the following specification: CCYYMMDD HH:MM:SS.ss+ -A full description will be expanded from a left-specified -truncated one. - -Additionally, one may specify range-based queries -by simply supplying two time descriptions seperated -by a forward slash: +A time range can be specified by two datetimes separated by a forward slash +or double-colon. For example: CCYYMMDD HH:MM:SS.ss+/CCYYMMDD HH:MM:SS.ss -The algorithm to parse the above is \code{.parseISO8601} from -the \pkg{xts} package. - -ISO-style subsetting, given a range type query, makes use -of a custom binary search mechanism that allows for -very fast subsetting as no linear search though the index -is required. ISO-style character vectors may be longer than -length one, allowing for multiple non-contiguous ranges -to be selected in one subsetting call. - -If a character \emph{vector} representing time is used in place of -numeric values, ISO-style queries, or timeBased -objects, the above parsing will be carried out on -each element of the i-vector. This overhead can -be very costly. If the character approach is used when -no ISO range querying is needed, it is -recommended to wrap the \sQuote{i} character vector with the \code{I()} -function call, to allow for more efficient internal processing. -Alternately converting character vectors to POSIXct objects will -provide the most performance efficiency. - -As \code{xts} uses POSIXct time representations -of all user-level index classes internally, the fastest -timeBased subsetting will always be from POSIXct objects, -regardless of the \code{tclass} of the original -object. All non-POSIXct time classes -are converted to character first to preserve -consistent TZ behavior. -} -\value{ -An extraction of the original xts object. If \code{which.i} -is TRUE, the corresponding integer \sQuote{i} values used to -subset will be returned. +The ISO8601 time range subsetting uses a custom binary search algorithm to +efficiently find the beginning and end of the time range. \code{i} can also be a +vector of ISO8601 time ranges, which enables subsetting by multiple +non-contiguous time ranges in one subset call. + +The above parsing, both for single datetimes and time ranges, will be done +on each element when \code{i} is a character \emph{vector}. This is very inefficient, +especially for long vectors. In this case, it's recommened to use \code{I(i)} so +the xts subset function can process the vector more efficiently. Another +alternative is to convert \code{i} to POSIXct before passing it to the subset +function. See the examples for an illustration of using \code{I(i)}. + +The xts index is stored as POSIXct internally, regardless of the value of +its \code{tclass} attribute. So the fastest time-based subsetting is always when +\code{i} is a POSIXct vector. } \note{ -By design, drop=FALSE in the default case. This preserves the basic -underlying type of \code{matrix} and the \code{dim()} to be non-NULL. -This is different from both matrix and \code{zoo} behavior as \R -uses \code{drop=TRUE}. Explicitly passing \code{drop=TRUE} may -be required when performing certain matrix operations. -} -\references{ -ISO 8601: Date elements and interchange formats - -Information interchange - Representation of dates and time -\url{https://www.iso.org} -} -\author{ -Jeffrey A. Ryan -} -\seealso{ -\code{\link{xts}}, -\code{\link{.parseISO8601}}, -\code{\link{.index}} +By design, xts objects always have two dimensions. They cannot be +vectors like zoo objects. Therefore \code{drop = FALSE} by default in order to +preserve the xts object's dimensions. This is different from both matrix and +zoo, which use \code{drop = TRUE} by default. Explicitly setting \code{drop = TRUE} +may be needed when performing certain matrix operations. } \examples{ + x <- xts(1:3, Sys.Date()+1:3) xx <- cbind(x,x) -# drop=FALSE for xts, differs from zoo and matrix +# drop = FALSE for xts, differs from zoo and matrix z <- as.zoo(xx) z/z[,1] @@ -127,11 +89,11 @@ m/m[,1] # this will fail with non-conformable arrays (both retain dim) tryCatch( xx/x[,1], - error=function(e) print("need to set drop=TRUE") + error = function(e) print("need to set drop = TRUE") ) # correct way -xx/xx[,1,drop=TRUE] +xx/xx[,1,drop = TRUE] # or less efficiently xx/drop(xx[,1]) @@ -191,6 +153,15 @@ z["2018-02-10 12:00/"] # check the last day z2 <- x["T19:00/T08:29:59"] head(z2); tail(z2) - } -\keyword{ utilities } +\references{ +ISO 8601: Date elements and interchange formats - Information +interchange - Representation of dates and time \url{https://www.iso.org} +} +\seealso{ +\code{\link[=xts]{xts()}}, \code{\link[=.parseISO8601]{.parseISO8601()}}, \code{\link[=.index]{.index()}} +} +\author{ +Jeffrey A. Ryan +} +\keyword{utilities} diff --git a/man/tclass.Rd b/man/tclass.Rd index a80d652b..99dd1821 100644 --- a/man/tclass.Rd +++ b/man/tclass.Rd @@ -1,78 +1,95 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tclass.R \name{tclass} \alias{tclass} -\alias{tclass<-} +\alias{tclass.default} \alias{tclass.xts} -\alias{tclass<-.xts} +\alias{tclass<-} +\alias{tclass<-.default} \alias{indexClass} \alias{indexClass<-} -\title{ Get or Replace the Class of an xts Object's Index } -\description{ -Generic functions to get or replace the class of an xts object's index. -} +\alias{tclass<-.xts} +\title{Get or Replace the Class of an xts Object's Index} \usage{ -tclass(x, \dots) +tclass(x, ...) + +\method{tclass}{default}(x, ...) + +\method{tclass}{xts}(x, ...) + tclass(x) <- value -\method{tclass}{xts}(x, \dots) -\method{tclass}{xts}(x) <- value +\method{tclass}{default}(x) <- value -##### The functions below are DEPRECATED ##### indexClass(x) + indexClass(x) <- value + +\method{tclass}{xts}(x) <- value } \arguments{ - \item{x}{ an \code{xts} object } - \item{value}{ new index class (see Details for valid values) } - \item{\dots}{ arguments passed to other methods } -} -\details{ -Internally, an xts object's index is a \emph{numeric} value corresponding to -seconds since the epoch in the UTC timezone. The index class is stored as the -\code{tclass} attribute on the internal index. This is used to convert the -internal index values to the desired class when the \code{index} function is -called. - -The \code{tclass} function retrieves the class of the internal index, and the -\code{tclass<-} function sets it. The specified value for \code{tclass<-} must -be one of the following character strings: \code{"Date"}, \code{"POSIXct"}, -\code{"chron"}, \code{"yearmon"}, \code{"yearqtr"}, or \code{"timeDate"}. +\item{x}{An xts object.} + +\item{\dots}{Arguments passed to other methods.} + +\item{value}{The new index class (see Details for valid values).} } \value{ A vector containing the class of the object's index. } -\note{ -Both \code{indexClass} and \code{indexClass<-} are deprecated in favor of -\code{tclass} and \code{tclass<-}, respectively. +\description{ +Generic functions to get or replace the class of an xts object's index. +} +\details{ +Internally, an xts object's index is a \emph{numeric} value corresponding to +seconds since the epoch in the UTC timezone. The index class is stored as +the \code{tclass} attribute on the internal index. This is used to convert +the internal index values to the desired class when the \code{index} +function is called. -Replacing the \code{tclass} \emph{does not} change the values of the internal -index. See the examples. +The \code{tclass} function retrieves the class of the internal index, and +the \verb{tclass<-} function sets it. The specified value for +\verb{tclass<-} must be one of the following character strings: +\code{"Date"}, \code{"POSIXct"}, \code{"chron"}, \code{"yearmon"}, +\code{"yearqtr"}, or \code{"timeDate"}. } -\seealso{ -\code{\link{index}} has more information on the xts index, \code{\link{tformat}} -details how the index values are formatted when printed, \code{\link{tzone}} -has more information about the index timezone settings. +\note{ +Both \code{indexClass} and \verb{indexClass<-} are deprecated in favor +of \code{tclass} and \verb{tclass<-}, respectively. -The following help pages describe the characteristics of the valid index -classes: \code{\link{POSIXct}}, \code{\link{Date}}, \code{\link[chron]{chron}}, -\code{\link[zoo]{yearmon}}, \code{\link[zoo]{yearqtr}}, -\code{\link[timeDate]{timeDate}}. +Replacing the \code{tclass} can \emph{potentially change} the values of the internal +index. For example, changing the 'tclass' from POSIXct to Date will +truncate the POSIXct value and convert the timezone to UTC (since the Date +class doesn't have a timezone). See the examples. } -\author{ Jeffrey A. Ryan } \examples{ + x <- timeBasedSeq('2010-01-01/2010-01-02 12:00') x <- xts(seq_along(x), x) - y <- timeBasedSeq('2010-01-01/2010-01-03 12:00/H') y <- xts(seq_along(y), y, tzone = "America/New_York") -# Changing the tclass does not change the internal index values, but it -# does change how the index is printed! -head(y) # the index has times -.index(y) +# Changing the tclass *changes* the internal index values +head(y) # the index has times +head(.index(y)) tclass(y) <- "Date" -head(y) # the index prints without times, but -.index(y) # the internal index is not changed! +head(y) # the index prints as a Date +head(.index(y)) # the internal index is truncated + +} +\seealso{ +\code{\link[=index]{index()}} has more information on the xts index, \code{\link[=tformat]{tformat()}} +details how the index values are formatted when printed, and \code{\link[=tzone]{tzone()}} +has more information about the index timezone settings. + +The following help pages describe the characteristics of the valid index +classes: \code{\link[=POSIXct]{POSIXct()}}, \code{\link[=Date]{Date()}}, \link[chron:chron]{chron()}, +\code{\link[zoo:zoo]{yearmon()}}, \code{\link[zoo:zoo]{yearqtr()}}, +\code{\link[timeDate:timeDate]{timeDate()}} +} +\author{ +Jeffrey A. Ryan } \keyword{ts} \keyword{utilities} diff --git a/man/tformat.Rd b/man/tformat.Rd index 529fd120..183fdc6a 100644 --- a/man/tformat.Rd +++ b/man/tformat.Rd @@ -1,65 +1,69 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tformat.R \name{tformat} \alias{tformat} \alias{tformat<-} -\alias{tformat.xts} -\alias{tformat<-.xts} \alias{indexFormat} \alias{indexFormat<-} -\title{ Get or Replace the Format of an xts Object's Index } -\description{ -Generic functions to get or replace the format that determines how an xts -object's index is printed. -} +\title{Get or Replace the Format of an xts Object's Index} \usage{ -tformat(x, \dots) -tformat(x) <- value +tformat(x, ...) -\method{tformat}{xts}(x, \dots) -\method{tformat}{xts}(x) <- value +tformat(x) <- value -##### The functions below are DEPRECATED ##### indexFormat(x) + indexFormat(x) <- value } \arguments{ - \item{x}{ an \code{xts} object } - \item{value}{ new index format string (see Details for valid values) } - \item{\dots}{ arguments passed to other methods } -} -\details{ - Valid values for the \code{value} argument are the same as specified in the - \emph{Details} section of \code{\link{strptime}}. +\item{x}{An xts object.} - An xts object's \code{tformat} is \code{NULL} by default, so the index will be - formatted according to its \code{\link{tclass}} (e.g. \code{Date}, - \code{POSIXct}, \code{timeDate}, \code{yearmon}, etc.). +\item{\dots}{Arguments passed to other methods.} - \code{tformat} only changes how the index is \emph{printed} and how the row - names are formatted when xts objects are converted to other classes (e.g. - \code{matrix} or \code{data.frame}. It does not affect the internal index - in any way. +\item{value}{New index format string (see \code{\link[=strptime]{strptime()}} details for valid +values).} } \value{ A vector containing the format for the object's index. } -\note{ -Both \code{indexFormat} and \code{indexFormat<-} are deprecated in favor of -\code{tformat} and \code{tformat<-}, respectively. +\description{ +Generic functions to get or replace the format that determines how an xts +object's index is printed. } -\seealso{ -\code{\link{index}} has more information on the xts index, \code{\link{tclass}} -details how \pkg{xts} handles the class of the index, \code{\link{tzone}} has -more information about the index timezone settings. +\details{ +Valid values for the \code{value} argument are the same as specified in the +\emph{Details} section of \code{\link[=strptime]{strptime()}}. + +An xts object's \code{tformat} is \code{NULL} by default, so the index will be +be formatted according to its \code{\link[=tclass]{tclass()}} (e.g. Date, POSIXct, timeDate, +yearmon, etc.). + +The \code{tformat} only changes how the index is \emph{printed} and how the row names +are formatted when xts objects are converted to other classes (e.g. matrix +or data.frame). It does not affect the internal index in any way. +} +\note{ +Both \code{indexFormat()} and \verb{indexFormat<-} are deprecated in +favor of \code{tformat()} and \verb{tformat<-}, respectively. } -\author{ Jeffrey A. Ryan } \examples{ - x <- timeBasedSeq('2010-01-01/2010-01-02 12:00') - x <- xts(seq_along(x), x) - # set a custom index format - head(x) - tformat(x) <- "\%Y-\%b-\%d \%H:\%M:\%OS3" - head(x) +x <- timeBasedSeq('2010-01-01/2010-01-02 12:00') +x <- xts(seq_along(x), x) + +# set a custom index format +head(x) +tformat(x) <- "\%Y-\%b-\%d \%H:\%M:\%OS3" +head(x) + +} +\seealso{ +\code{\link[=index]{index()}} has more information on the xts index, \code{\link[=tclass]{tclass()}} +details how \pkg{xts} handles the class of the index, \code{\link[=tzone]{tzone()}} has more +information about the index timezone settings. +} +\author{ +Jeffrey A. Ryan } \keyword{ts} \keyword{utilities} diff --git a/man/timeBased.Rd b/man/timeBased.Rd index 2340ee65..516d0d5e 100644 --- a/man/timeBased.Rd +++ b/man/timeBased.Rd @@ -1,31 +1,34 @@ -\name{timeBased} -\alias{timeBased} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/period.R +\name{is.timeBased} \alias{is.timeBased} -\title{ Check if Class is Time-Based } -\description{ -Used to verify that the object is one of the -known time-based classes in R. -} +\alias{timeBased} +\title{Check if Class is Time-Based} \usage{ is.timeBased(x) + timeBased(x) } \arguments{ - \item{x}{ object to test } -} -\details{ -Current time-based objects supported are -\code{Date}, \code{POSIXct}, \code{chron}, -\code{yearmon}, \code{yearqtr}, and \code{timeDate}. +\item{x}{Object to test.} } \value{ -Logical +A logical scalar. +} +\description{ +Used to verify that the object is one of the known time-based classes in R. +Current time-based objects supported are \code{Date}, \code{POSIXct}, \code{chron}, +\code{yearmon}, \code{yearqtr}, and \code{timeDate}. } -\author{ Jeffrey A. Ryan } \examples{ + timeBased(Sys.time()) timeBased(Sys.Date()) timeBased(200701) + +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/timeBasedSeq.Rd b/man/timeBasedSeq.Rd index 168c775b..9ca68c93 100644 --- a/man/timeBasedSeq.Rd +++ b/man/timeBasedSeq.Rd @@ -1,97 +1,87 @@ -\name{timeBasedSeq} -\alias{timeBasedSeq} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/timeBasedRange.R, R/timeBasedSeq.R +\name{timeBasedRange} \alias{timeBasedRange} -\title{ Create a Sequence or Range of Times } -\description{ -A function to create a vector of time-based objects -suitable for indexing an \emph{xts} object, -given a string conforming to the ISO 8601 time -and date standard for range-based specification. The -resultant series can be of any class supported by -\emph{xts}, including POSIXct, Date, chron, timeDate, -yearmon, and yearqtr. - -\code{timeBasedRange} creates a vector of length 1 or 2 -as seconds since the epoch (1970-01-01) for use -internally. -} +\alias{timeBasedSeq} +\title{Create a Sequence or Range of Times} \usage{ -timeBasedSeq(x, retclass = NULL, length.out = NULL) - timeBasedRange(x, ...) + +timeBasedSeq(x, retclass = NULL, length.out = NULL) } \arguments{ - \item{x}{ a string representing the time-date range desired } - \item{retclass}{ the return class desired } - \item{length.out}{ passed to \code{seq} internally } - \item{\ldots}{ unused } -} -\details{ -Designed to provide uniform creation of valid -time-based objects for use within \emph{xts}, the -interface conforms (mostly) to the ISO recommended -format for specifying ranges. +\item{x}{An ISO-8601 time-date range string.} -In general, the format is a string specifying -a time and/or date \emph{from}, \emph{to}, and -optionally \emph{by} delineated by -either \sQuote{"/"} or \sQuote{"::"}. +\item{\dots}{Unused.} -The first argument need not be quoted, as it is -converted internally if need be. +\item{retclass}{The return class desired.} -The general form is \emph{from/to/by} or -\emph{from::to::by}, where \emph{to} and \emph{by} -are optional if the length.out arg is specified. +\item{length.out}{Passed to \code{seq()} internally.} +} +\value{ +\code{timeBasedSeq()} returns a vector of time-based observations. +\code{timeBasedRange()} returns a one or two element numeric vector representing +the start and end number of seconds since epoch (1970-01-01). -The \code{from} and \code{to} elements of the string -must be left-specified with respect to the standard -\emph{CCYYMMDD HHMMSS} form. All dates-times -specified will be set to either the earliest point (from) -or the latest (to), given the level of specificity. +When \code{retclass = NULL}, the result of \code{timeBasedSeq()} is a named list +containing elements "from", "to", "by" and "length.out". +} +\description{ +A function to create a vector of time-based objects suitable for indexing an +xts object, given a string conforming to the ISO-8601 time and date standard +for range-based specification. The resulting series can be of any class +supported by xts, including POSIXct, Date, chron, timeDate, yearmon, and +yearqtr. +} +\details{ +\code{timeBasedRange()} creates a one or two element numeric vector representing +the start and end number of seconds since epoch (1970-01-01). For internal +use. -For example \sQuote{1999} in the \emph{from} field -would set the start to the beginning of 1999. The opposite -occurs in the \emph{to} field. +\code{timeBasedSeq()} creates sequences of time-based observations using strings +formatted according to the ISO-8601 specification. The general format is +\emph{from/to/by} or \emph{from::to::by}, where \emph{to} and \emph{by} are optional when the +'length.out' argument is specified. -The level of detail in the request is interpretted as the -level of detail in the result. The maximum detail of either -\emph{from} or \emph{to} is the basis of the sequence, unless -the optional \emph{by} element is specified, which will be covered later. +The \emph{from} and \emph{to} elements of the string must be left-specified with +respect to the standard \emph{CCYYMMDD HHMMSS} form. All dates/times specified +will be set to either the earliest point (from) or the latest (to), to the +given the level of specificity. For example, \sQuote{1999} in the \emph{from} +field would set the start to the beginning of 1999. \sQuote{1999} in the +\emph{to} field would set the end to the end of 1999. -To request a yearly series, it is only necessary to -use \sQuote{"1999/2008"}. Alternately, one could -request a monthly series (returned by default as -class \code{yearmon}) with \sQuote{"199901/2008"} or -\sQuote{"1999-01/2008"}, or even \sQuote{"1999/2008-01"}. -As the level of granularity increases, so does the -resultant sequence granularity - as does its length. +The amount of resolution in the result is determined by the resolution of +the \emph{from} and \emph{to} component, unless the optional \emph{by} component is +specified. -Using the optional third \emph{by} field (the third -delimited element to the string), will override the -granularity intepretation and return the requested -periodicity. The acceptable arguments include -\code{Y} for years, \code{m} for months, \code{d} for -days, \code{H} for hours, \code{M} for minutes and \code{S} for -seconds. -} -\value{ -A sequence or range of time-based objects. +For example, \code{timeBasedSeq("1999/2008")} returns a vector of Dates for +January 1st of each year. \code{timeBasedSeq("199501/1996")} returns a yearmon +vector of 24 months in 1995 and 1996. And \code{timeBasedSeq("19950101/1996")} +creates a Date vector for all the days in those two years. -If \code{retclass} is \code{NULL}, the result is a named -list of from, to, by and length.out. +The optional \emph{by} field (the third delimited element to the string), will +the resolution heuristic described above and will use the specified \emph{by} +resolution. The possible values for \emph{by} are: 'Y' (years), 'm' (months), +'d' (days), 'H' (hours), 'M' (minutes), 'S' (seconds). Sub-second +resolutions are not supported. } -\references{ International Organization for Standardization: ISO 8601 - \url{https://www.iso.org}} -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{timeBased}}, \code{\link{xts}} } \examples{ + timeBasedSeq('1999/2008') timeBasedSeq('199901/2008') timeBasedSeq('199901/2008/d') timeBasedSeq('20080101 0830',length=100) # 100 minutes timeBasedSeq('20080101 083000',length=100) # 100 seconds + +} +\references{ +International Organization for Standardization: ISO 8601 +\url{https://www.iso.org} +} +\seealso{ +\code{\link[=timeBased]{timeBased()}}, \code{\link[=xts]{xts()}} +} +\author{ +Jeffrey A. Ryan } -% Add one or more standard keywords, see file 'KEYWORDS' in the -% R documentation directory. -\keyword{ utilities } +\keyword{utilities} diff --git a/man/to.period.Rd b/man/to.period.Rd index de5066fe..426eb895 100644 --- a/man/to.period.Rd +++ b/man/to.period.Rd @@ -1,3 +1,5 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toperiod.R \name{to.period} \alias{to.period} \alias{to_period} @@ -13,122 +15,126 @@ \alias{to.monthly} \alias{to.quarterly} \alias{to.yearly} -\alias{OHLC} -\title{ Convert time series data to an OHLC series } -\description{ -Convert an OHLC or univariate object to a specified periodicity lower -than the given data object. For example, convert a daily -series to a monthly series, or a monthly series to a yearly one, -or a one minute series to an hourly series. +\title{Convert time series data to an OHLC series} +\usage{ +to.period( + x, + period = "months", + k = 1, + indexAt = NULL, + name = NULL, + OHLC = TRUE, + ... +) -The result will contain the open and close for the -given period, as well as the maximum and minimum over the -new period, reflected in the new high and low, respectively. +to.minutes(x, k, name, ...) -If volume for a period was available, the new volume will also be -calculated. -} -\usage{ -to.minutes(x,k,name,...) -to.minutes3(x,name,...) -to.minutes5(x,name,...) -to.minutes10(x,name,...) -to.minutes15(x,name,...) -to.minutes30(x,name,...) -to.hourly(x,name,...) -to.daily(x,drop.time=TRUE,name,...) - -to.weekly(x,drop.time=TRUE,name,...) -to.monthly(x,indexAt='yearmon',drop.time=TRUE,name,...) -to.quarterly(x,indexAt='yearqtr',drop.time=TRUE,name,...) -to.yearly(x,drop.time=TRUE,name,...) - -to.period(x, - period = 'months', - k = 1, - indexAt, - name=NULL, - OHLC = TRUE, - ...) +to.minutes3(x, name, ...) + +to.minutes5(x, name, ...) + +to.minutes10(x, name, ...) + +to.minutes15(x, name, ...) + +to.minutes30(x, name, ...) + +to.hourly(x, name, ...) + +to.daily(x, drop.time = TRUE, name, ...) + +to.weekly(x, drop.time = TRUE, name, ...) + +to.monthly(x, indexAt = "yearmon", drop.time = TRUE, name, ...) + +to.quarterly(x, indexAt = "yearqtr", drop.time = TRUE, name, ...) + +to.yearly(x, drop.time = TRUE, name, ...) } \arguments{ - \item{x}{ a univariate or OHLC type time-series object } - \item{period}{ period to convert to. See details. } - \item{indexAt}{ convert final index to new class or date. See details } - \item{drop.time}{ remove time component of POSIX datestamp (if any) } - \item{k}{ number of sub periods to aggregate on (only for minutes and seconds) } - \item{name}{ override column names } - \item{OHLC}{ should an OHLC object be returned? (only \code{OHLC=TRUE} currently supported) } -% \item{addlast}{ passed to \code{endpoints}. See also. } - \item{\dots}{ additional arguments } -} -\details{ -Essentially an easy and reliable way to convert one periodicity of data -into any new periodicity. It is important to note -that all dates will be aligned to the \emph{end} of each period -by default - with the exception of \code{to.monthly} and \code{to.quarterly}, -which index by \sQuote{yearmon} and \sQuote{yearqtr} from the \pkg{zoo} -package, respectively. - -Valid period character strings include: \code{"seconds"}, -\code{"minutes"}, \code{"hours"}, \code{"days"}, \code{"weeks"}, -\code{"months"}, \code{"quarters"}, and \code{"years"}. These are -calculated internally via \code{endpoints}. See that function's help -page for further details. - -To adjust the final indexing style, it is possible to set -\code{indexAt} to one of the following: \sQuote{yearmon}, -\sQuote{yearqtr}, \sQuote{firstof}, \sQuote{lastof}, -\sQuote{startof}, or \sQuote{endof}. The final index will -then be \code{yearmon}, \code{yearqtr}, the first time of the period, -the last time of the period, the starting time in the data for that -period, or the ending time in the data for that period, respectively. - -It is also possible to pass a single time series, such as -a univariate exchange rate, and return an OHLC object of -lower frequency - e.g. the weekly OHLC of the daily series. - -Setting \code{drop.time} to \code{TRUE} (the default) -will convert a series that includes a time -component into one with just a date index, as the time index -is often of little value in lower frequency series. +\item{x}{A univariate or OHLC type time-series object.} + +\item{period}{Period to convert to. See details.} + +\item{k}{Number of sub periods to aggregate on (only for minutes and +seconds).} + +\item{indexAt}{Convert final index to new class or date. See details.} -It is not possible to convert a series from a lower periodicity -to a higher periodicity - e.g. weekly to daily or -daily to 5 minute bars, as that would -require magic. +\item{name}{Override column names?} + +\item{OHLC}{Should an OHLC object be returned? (only \code{OHLC = TRUE} +currently supported)} + +\item{\dots}{Additional arguments.} + +\item{drop.time}{Remove time component of POSIX datestamp (if any)?} } \value{ An object of the original type, with new periodicity. } +\description{ +Convert an OHLC or univariate object to a specified periodicity lower than +the given data object. For example, convert a daily series to a monthly +series, or a monthly series to a yearly one, or a one minute series to an +hourly series. +} +\details{ +The result will contain the open and close for the given period, as well as +the maximum and minimum over the new period, reflected in the new high and +low, respectively. Aggregate volume will also be calculated if applicable. + +An easy and reliable way to convert one periodicity of data into any new +periodicity. It is important to note that all dates will be aligned to the +\emph{end} of each period by default - with the exception of \code{to.monthly()} and +\code{to.quarterly()}, which use the \pkg{zoo} package's \link[zoo:zoo]{yearmon} and +\link[zoo:zoo]{yearqtr} classes, respectively. + +Valid period character strings include: \code{"seconds"}, \code{"minutes"}, \code{"hours"}, +\code{"days"}, \code{"weeks"}, \code{"months"}, \code{"quarters"}, and \code{"years"}. These are +calculated internally via \code{\link[=endpoints]{endpoints()}}. See that function's help page for +further details. + +To adjust the final indexing style, it is possible to set \code{indexAt} to one +of the following: \sQuote{yearmon}, \sQuote{yearqtr}, \sQuote{firstof}, +\sQuote{lastof}, \sQuote{startof}, or \sQuote{endof}. The final index will +then be \code{yearmon}, \code{yearqtr}, the first time of the period, the last time +of the period, the starting time in the data for that period, or the ending +time in the data for that period, respectively. + +It is also possible to pass a single time series, such as a univariate +exchange rate, and return an OHLC object of lower frequency - e.g. the +weekly OHLC of the daily series. + +Setting \code{drop.time = TRUE} (the default) will convert a series that includes +a time component into one with just a date index, since the time component +is often of little value in lower frequency series. +} \note{ -In order for this function to work properly on OHLC data, it is necessary -that the Open, High, Low and Close columns be names as such; including -the first letter capitalized and the full spelling found. Internally -a call is made to reorder the data into the correct column order, -and then a verification step to make sure that this ordering and naming -has succeeded. All other data formats must be aggregated with functions -such as \code{aggregate} and \code{period.apply}. - -This method should work on almost all time-series-like -objects. Including \sQuote{timeSeries}, \sQuote{zoo}, -\sQuote{ts}, and \sQuote{irts}. It is even likely -to work well for other data structures - including \sQuote{data.frames} -and \sQuote{matrix} objects. - -Internally a call to \code{as.xts} converts the original \code{x} -into the universal \code{xts} format, and then re-converts back -to the original type. - -A special note with respect to \sQuote{ts} objects. As these are -strictly regular they may include \code{NA} values. These are -stripped for aggregation purposes, though replaced before returning. -This inevitably leads to many, many additional \sQuote{NA} values -in the data. It is more beneficial to consider using an \sQuote{xts} -object originally, or converting to one in the function call by means -of \code{as.xts}. +In order for this function to work properly on OHLC data, it is +necessary that the Open, High, Low and Close columns be names as such; +including the first letter capitalized and the full spelling found. +Internally a call is made to reorder the data into the correct column order, +and then a verification step to make sure that this ordering and naming has +succeeded. All other data formats must be aggregated with functions such as +\code{aggregate()} and \code{period.apply()}. + +This method should work on almost all time-series-like objects. Including +\sQuote{timeSeries}, \sQuote{zoo}, \sQuote{ts}, and \sQuote{irts}. It is +even likely to work well for other data structures - including +\sQuote{data.frames} and \sQuote{matrix} objects. + +Internally a call to \code{as.xts()} converts the original \code{x} into the +universal xts format, and then re-converts back to the original type. + +A special note with respect to \sQuote{ts} objects. As these are strictly +regular they may include \code{NA} values. These are removed before aggregation, +though replaced before returning the result. This inevitably leads to many +additional \code{NA} values in the result. Consider using an xts object or +converting to xts using \code{as.xts()}. } \examples{ + data(sample_matrix) samplexts <- as.xts(sample_matrix) @@ -138,7 +144,9 @@ to.monthly(sample_matrix) str(to.monthly(samplexts)) str(to.monthly(sample_matrix)) + +} +\author{ +Jeffrey A. Ryan } -\author{ Jeffrey A. Ryan } - -\keyword{ utilities } +\keyword{utilities} diff --git a/man/tzone.Rd b/man/tzone.Rd index 366f2a8b..44e016fd 100644 --- a/man/tzone.Rd +++ b/man/tzone.Rd @@ -1,70 +1,56 @@ -\name{tzone} -\alias{tzone} -\alias{tzone<-} -\alias{tzone.xts} -\alias{tzone<-.xts} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tzone.R +\name{indexTZ} \alias{indexTZ} +\alias{tzone} \alias{indexTZ<-} -\alias{TimeZone} -\title{ Get or Replace the Timezone of an xts Object's Index } -\description{ -Generic functions to get or replace the timezone of an xts object's index. -} +\alias{tzone<-} +\title{Get or Replace the Timezone of an xts Object's Index} \usage{ -tzone(x, \dots) -tzone(x) <- value +indexTZ(x, ...) -\method{tzone}{xts}(x, \dots) -\method{tzone}{xts}(x) <- value +tzone(x, ...) -##### The functions below are DEPRECATED ##### -indexTZ(x, \dots) indexTZ(x) <- value + +tzone(x) <- value } \arguments{ - \item{x}{ an \code{xts} object } - \item{value}{ a valid timezone value (see \code{OlsonNames()}) } - \item{\dots}{ arguments passed to other methods } +\item{x}{An xts object.} + +\item{\dots}{Arguments passed to other methods.} + +\item{value}{A valid timezone value (see \code{\link[=OlsonNames]{OlsonNames()}}).} +} +\value{ +A one element named vector containing the timezone of the object's +index. +} +\description{ +Generic functions to get or replace the timezone of an xts object's index. } \details{ Internally, an xts object's index is a \emph{numeric} value corresponding to -seconds since the epoch in the UTC timezone. When an xts object is created, all -time index values are converted internally to \code{\link{POSIXct}} (which is -also in seconds since the UNIX epoch), using the underlying OS conventions and -the \env{TZ} environment variable. The \code{xts()} function manages timezone -information as transparently as possible. +seconds since the epoch in the UTC timezone. When an xts object is created, +all time index values are converted internally to \code{\link[=POSIXct]{POSIXct()}} +(which is also in seconds since the UNIX epoch), using the underlying OS +conventions and the \env{TZ} environment variable. The \code{xts()} function +manages timezone information as transparently as possible. -The \code{tzone<-} function \emph{does not} change the internal index values +The \verb{tzone<-} function \emph{does not} change the internal index values (i.e. the index will remain the same time in the UTC timezone). } \note{ -Both \code{indexTZ} and \code{indexTZ<-} are deprecated in favor of -\code{tzone} and \code{tzone<-}, respectively. +Both \code{indexTZ()} and \verb{indexTZ<-} are deprecated in favor of +\code{tzone()} and \verb{tzone<-}, respectively. -Problems may arise when an object that had been created under one timezone are -used in a session using another timezone. This isn't usually a issue, but when -it is a warning is given upon printing or subsetting. This warning may be -suppressed by setting \code{options(xts_check_TZ = FALSE)}. +Problems may arise when an object that had been created under one timezone +are used in a session using another timezone. This isn't usually a issue, +but when it is a warning is given upon printing or subsetting. This warning +may be suppressed by setting \code{options(xts_check_TZ = FALSE)}. } -\value{ -A one element named vector containing the timezone of the object's index. -} -\note{ -Both \code{indexTZ} and \code{indexTZ<-} are deprecated in favor of -\code{tzone} and \code{tzone<-}, respectively. - -Timezones are a difficult issue to manage. It's best to set the system \env{TZ} -environment variable to "GMT" or "UTC" (via \code{Sys.setenv(TZ = "UTC")} at -the beginning of your scripts if you do not need intra-daily resolution. -} -\seealso{ \code{\link{POSIXt}} -\code{\link{index}} has more information on the xts index, -\code{\link{tformat}} describes how the index values are formatted when printed, -and \code{\link{tclass}} provides details how \pkg{xts} handles the class of -the index. -} -\author{ Jeffrey A. Ryan } \examples{ + # Date indexes always have a "UTC" timezone x <- xts(1, Sys.Date()) tzone(x) @@ -94,6 +80,15 @@ head(.index(y)) tzone(y) <- "Europe/London" head(y) # the index prints with hours, but head(.index(y)) # the internal index is not changed! + +} +\seealso{ +\code{\link[=index]{index()}} has more information on the xts index, \code{\link[=tformat]{tformat()}} +describes how the index values are formatted when printed, and \code{\link[=tclass]{tclass()}} +provides details how \pkg{xts} handles the class of the index. +} +\author{ +Jeffrey A. Ryan } \keyword{ts} \keyword{utilities} diff --git a/man/window.xts.Rd b/man/window.xts.Rd index d4a9892f..76b40d7a 100644 --- a/man/window.xts.Rd +++ b/man/window.xts.Rd @@ -1,59 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts.methods.R \name{window.xts} -\Rdversion{1.1} \alias{window.xts} - -\title{Extract time windows from an \code{xts} series} -\description{ -Method for extracting time windows from \code{xts} objects. -} - +\title{Extract Time Windows from xts Objects} \usage{ -\method{window}{xts}(x, index. = NULL, start = NULL, end = NULL, \dots) +\method{window}{xts}(x, index. = NULL, start = NULL, end = NULL, ...) } - \arguments{ - \item{x}{an object.} - \item{index.}{a user defined time index. This defaults to the \code{xts} - index for the series via \code{.index(x)}. When supplied, this is typically - a subset of the dates in the full series.\cr - The \code{index.} must be a set of dates that are convertible to - \code{POSIXct}. If you want fast lookups, then \code{index.} should be - sorted and of class \code{POSIXct}.\cr - If an unsorted \code{index.} is passed in, \code{window} will sort it.} - \item{start}{a start time. Extract \code{xts} rows where \code{index. >= - start}. \code{start} may be any class that is convertible to - \code{POSIXct} such as a character variable in the format - \sQuote{YYYY-MM-DD}.\cr - If \code{start} is \code{NULL} then all \code{index.} dates are matched.} - \item{end}{an end time. Extract \code{xts} rows where \code{index. <= end}. - \code{end} must be convertible to \code{POSIXct}. If \code{end} is - \code{NULL} then all \code{index.} dates are matched.} - \item{\dots}{currently not used.} -} +\item{x}{An xts object.} +\item{index.}{A user defined time index (default \code{.index(x)}).} + +\item{start}{A start time coercible to POSIXct.} + +\item{end}{An end time coercible to POSIXct.} + +\item{\dots}{Unused.} +} \value{ -The matching time window is extracted. +The subset of \code{x} that matches the time window. } - -\details{ -The point of having \code{window} in addition to the regular subset function -is to have a fast way of extracting time ranges from an \code{xts} series. In -particular, this method will convert \code{start} and \code{end} to -\code{POSIXct} then do a binary lookup on the internal \code{xts} index to -quickly return a range of matching dates. With a user supplied \code{index.}, -a similarly fast invocation of \code{findInterval} is used so that large sets -of sorted dates can be retrieved quickly. +\description{ +Method for extracting time windows from xts objects. } +\details{ +The xts \code{window()} method provides an efficient way to subset an xts object +between a start and end date using a binary search algorithm. Specifically, +it converts \code{start} and \code{end} to POSIXct and then does a binary search of +the index to quickly return a subset of \code{x} between \code{start} and \code{end}. -\author{ Corwin Joy } +Both \code{start} and \code{end} may be any class that is convertible to POSIXct, such +as a character string in the format \sQuote{yyyy-mm-dd}. When \code{start = NULL} +the returned subset will begin at the first value of \code{index.}. When +\code{end = NULL} the returned subset will end with the last value of \code{index.}. +Otherwise the subset will contain all timestamps where \code{index.} is between +\code{start} and \code{end}, inclusive. -\seealso{ -\code{\link{subset.xts}}, -\code{\link[base]{findInterval}}, -\code{\link{xts}} +When \code{index.} is specified, \code{\link[=findInterval]{findInterval()}} is used to quickly retrieve +large sets of sorted timestamps. For the best performance, \code{index.} must be +a \emph{sorted} POSIXct vector or a numeric vector of seconds since the epoch. +\code{index.} is typically a subset of the timestamps in \code{x}. } - \examples{ + ## xts example x.date <- as.Date(paste(2003, rep(1:4, 4:1), seq(1,19,2), sep = "-")) x <- xts(matrix(rnorm(20), ncol = 2), x.date) @@ -61,11 +50,18 @@ x window(x, start = "2003-02-01", end = "2003-03-01") window(x, start = as.Date("2003-02-01"), end = as.Date("2003-03-01")) -window(x, index = x.date[1:6], start = as.Date("2003-02-01")) -window(x, index = x.date[c(4, 8, 10)]) +window(x, index. = x.date[1:6], start = as.Date("2003-02-01")) +window(x, index. = x.date[c(4, 8, 10)]) ## Assign to subset -window(x, index = x.date[c(4, 8, 10)]) <- matrix(1:6, ncol = 2) +window(x, index. = x.date[c(4, 8, 10)]) <- matrix(1:6, ncol = 2) x + +} +\seealso{ +\code{\link[=subset.xts]{subset.xts()}}, \code{\link[=findInterval]{findInterval()}}, \code{\link[=xts]{xts()}} +} +\author{ +Corwin Joy } \keyword{ts} diff --git a/man/xts-internals.Rd b/man/xts-internals.Rd index 5ec32ae0..414d9bec 100644 --- a/man/xts-internals.Rd +++ b/man/xts-internals.Rd @@ -1,59 +1,59 @@ -\name{xtsInternals} -\alias{.dimnames.xts} -\alias{dimnames.xts<-} -\title{ Internal Documentation } +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts-package.R +\name{xts-internals} +\alias{xts-internals} +\title{Internal Documentation} \description{ -This help file is to help in development of xts, as well -as provide some clarity and insight into its purpose and implementation. - -Last modified: 2008-08-06 by Jeffrey A. Ryan -Version: 0.5-0 and above - -The \pkg{xts} package xts designed as a drop-in replacement -for the very popular \pkg{zoo} package. Most all functionality -of zoo has been extended or carries into the xts package. - -Notable changes in direction include the use of time-based -indexing, at first explicitely, now implicitely. - -An \code{xts} object consists of data in the form of a matrix, -an index - ordered and increasing, either numeric or integer, and additional -attributes for use internally, or for end-user purposes. - -The current implementation enforces two major rules on -the object. One is that the index must be coercible to numeric, by -way of \code{as.POSIXct}. There are defined types that meet this criteria. -See \code{timeBased} for details. - -The second requirement is that the object cannot have rownames. -The motivation from this comes in part from the work -Matthew Doyle has done in his data.table class, in the package of the -same name. Rownames in \R must be character vectors, and as such -are inefficient in both storage and conversion. By eliminating -the rownames, and providing a numeric index of \R internal type \code{REAL} -or \code{INTEGER}, it is possible to maintain a connection -to standard \R date and time classes via the POSIXct functions, while at -at the same time maximizing efficiencies in data handling. - -User level functions \code{index}, as well as conversion to -other classes proceeds as if there were rownames. The code -for \code{index} automatically converts time to numeric in both extraction -and replacement functionality. This provides a level of -abstraction to facilitate internal, and external package use and inter-operability. - -There is also new work on providing a C-level API to some of the -xts functionality to facilitate external package developers to -utilize the fast utility routines such as subsetting and merges, without -having to call only from \R. Obviously this places far -more burden on the developer to not only understand the -internal xts implementation, but also to understand all of -what is documented for R-internals (and much that isn't). At present the functions -and macros -available can be found in the \sQuote{xts.h} file in the src directory. - -There is no current documentation for this API. The adventure -starts here. Future documentation is planned, not implemented. - +This help file is to help in development of xts, as well as provide some +clarity and insight into its purpose and implementation. +} +\details{ +Last modified: 2008-08-06 by Jeffrey A. Ryan Version: 0.5-0 and above + +The \pkg{xts} package xts designed as a drop-in replacement for the very +popular \pkg{zoo} package. Most all functionality of zoo has been extended +or carries into the xts package. + +Notable changes in direction include the use of time-based indexing, at +first explicitely, now implicitely. + +An xts object consists of data in the form of a matrix, an index - +ordered and increasing, either numeric or integer, and additional attributes +for use internally, or for end-user purposes. + +The current implementation enforces two major rules on the object. One is +that the index must be coercible to numeric, by way of \code{as.POSIXct}. +There are defined types that meet this criteria. See \code{timeBased} for +details. + +The second requirement is that the object cannot have rownames. The +motivation from this comes in part from the work Matthew Doyle has done in +his data.table class, in the package of the same name. Rownames in must be +character vectors, and as such are inefficient in both storage and +conversion. By eliminating the rownames, and providing a numeric index of +internal type \code{REAL} or \code{INTEGER}, it is possible to maintain a +connection to standard date and time classes via the POSIXct functions, +while at at the same time maximizing efficiencies in data handling. + +User level functions \code{index}, as well as conversion to other classes +proceeds as if there were rownames. The code for \code{index} automatically +converts time to numeric in both extraction and replacement functionality. +This provides a level of abstraction to facilitate internal, and external +package use and inter-operability. + +There is also new work on providing a C-level API to some of the xts +functionality to facilitate external package developers to utilize the fast +utility routines such as subsetting and merges, without having to call only +from . Obviously this places far more burden on the developer to not only +understand the internal xts implementation, but also to understand all of +what is documented for R-internals (and much that isn't). At present the +functions and macros available can be found in the \sQuote{xts.h} file in +the src directory. + +There is no current documentation for this API. The adventure starts here. +Future documentation is planned, not implemented. +} +\author{ +Jeffrey A. Ryan } -\author{ Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/xts-package.Rd b/man/xts-package.Rd index 4d90ea81..8fa12fa7 100644 --- a/man/xts-package.Rd +++ b/man/xts-package.Rd @@ -1,31 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts-package.R +\docType{package} \name{xts-package} \alias{xts-package} -\docType{package} -\title{ -xts: extensible time-series -} +\title{xts: extensible time-series} \description{ -Extensible time series class and methods, extending and behaving -like zoo. +Extensible time series class and methods, extending and behaving like zoo. } \details{ -Easily convert one of \R's many time-series (and non-time-series) -classes to a true time-based object which inherits all of zoo's -methods, while allowing for new time-based tools where appropriate. +Easily convert one of \R's many time-series (and non-time-series) classes to a +true time-based object which inherits all of zoo's methods, while allowing +for new time-based tools where appropriate. -Additionally, one may use \pkg{xts} to create new objects which -can contain arbitrary attributes named during creation as name=value -pairs. +Additionally, one may use \pkg{xts} to create new objects which can contain +arbitrary attributes named during creation as name=value pairs. +} +\seealso{ +\code{\link[=xts]{xts()}}, \code{\link[=as.xts]{as.xts()}}, \code{\link[=reclass]{reclass()}}, \code{\link[zoo:zoo]{zoo()}} } \author{ Jeffrey A. Ryan and Joshua M. Ulrich -Maintainer: Joshua M. Ulrich -} -\keyword{ package } -\seealso{ - \code{\link{xts}} - \code{\link{as.xts}} - \code{\link{reclass}} - \code{\link[zoo:zoo]{zoo}} +Maintainer: Joshua M. Ulrich \href{mailto:josh.m.ulrich@gmail.com}{josh.m.ulrich@gmail.com} } +\keyword{package} diff --git a/man/xts.Rd b/man/xts.Rd index 4926ee18..e55ea7f6 100644 --- a/man/xts.Rd +++ b/man/xts.Rd @@ -1,139 +1,138 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts.R \name{xts} \alias{xts} \alias{.xts} \alias{is.xts} -\title{ Create Or Test For An xts Time-Series Object } -\description{ -Constructor function for creating an extensible time-series object. - -\code{xts} is used to create an \code{xts} object from raw data inputs. -} +\title{Create or Test For An xts Time-Series Object} \usage{ -xts(x = NULL, - order.by = index(x), - frequency = NULL, - unique = TRUE, - tzone = Sys.getenv("TZ"), - ...) - -.xts(x = NULL, - index, - tclass = c("POSIXct", "POSIXt"), - tzone = Sys.getenv("TZ"), - check = TRUE, - unique = FALSE, - ...) +xts( + x = NULL, + order.by = index(x), + frequency = NULL, + unique = TRUE, + tzone = Sys.getenv("TZ"), + ... +) + +.xts( + x = NULL, + index, + tclass = c("POSIXct", "POSIXt"), + tzone = Sys.getenv("TZ"), + check = TRUE, + unique = FALSE, + ... +) is.xts(x) } - \arguments{ - \item{x}{ an object containing the time series data } - \item{order.by}{ a corresponding vector of dates/times of a known time-based - class. See Details. } - \item{index}{ a corresponding \emph{numeric} vector specified as seconds - since the UNIX epoch (1970-01-01 00:00:00.000) } - \item{frequency}{ numeric indicating frequency of \code{order.by}. See Details. } - \item{unique}{ check the index for unique timestamps? } - \item{check}{ check that the index is ordered? } - \item{tclass}{ time class to use for the index. See \code{\link{tclass}}. } - \item{tzone}{ time zone of the index (ignored indices without a time - component, e.g. Date, yearmon, yearqtr). See \code{\link{tzone}}. } - \item{\dots}{ additional attributes to be added. See Details. } -} -\details{ -An \code{xts} object extends the S3 class \code{zoo} from the package of the -same name. +\item{x}{An object containing the underlying data.} -The \code{xts()} constructor is the preferred way to create xts objects. It -performs several checks to ensure it returns a well-formed xts object. The -\code{.xts()} constructor is mainly for internal use. It is more efficient than -the regular \code{xts()} constructor because it doesn't perform as many -validity checks. Use it with caution. +\item{order.by}{A corresponding vector of dates/times of a known time-based +class. See Details.} -% TODO: add notes here about the differences between 'empty', 'zero-width', and -% 'zero-length' xts objects. +\item{frequency}{Numeric value indicating the frequency of \code{order.by}. See +details.} -Similar to zoo objects, xts objects must have an ordered index. While zoo -indexes cannot contain duplicate values, xts objects have optionally supported -duplicate index elements since version 0.5-0. The \code{xts} class has one -additional requirement, the index must be a time-based class. Currently -supported classes include: \sQuote{Date}, \sQuote{POSIXct}, \sQuote{timeDate}, -as well as \sQuote{yearmon} and \sQuote{yearqtr} where the index values -remain unique. +\item{unique}{Can the index only include unique timestamps? Ignored when +\code{check = FALSE}.} -The uniqueness requirement was relaxed in version 0.5-0, but is still enforced -by default. Setting \code{unique = FALSE} skips the uniqueness check and only -ensures that the index is ordered via the \code{isOrdered} function. +\item{tzone}{Time zone of the index (ignored for indices without a time +component, e.g. Date, yearmon, yearqtr). See \code{\link[=tzone]{tzone()}}.} -As of version 0.10-0, xts no longer allows missing values in the index. This -is because many xts functions expect all index values to be finite. The most -important of these is \code{merge.xts}, which is used ubiquitously. Missing -values in the index are usually the result of a date-time conversion error (e.g. -incorrect format, non-existent time due to daylight saving time, etc). Because -of how non-finite numbers are represented, a missing timestamp will always be -at the end of the index (except if it is \code{-Inf}, which will be first). +\item{\dots}{Additional attributes to be added. See details.} -Another difference from \pkg{zoo} is that xts object may carry additional -attributes that may be desired in individual time-series handling. -This includes the ability to augment the objects data with -meta-data otherwise not cleanly attachable to a standard zoo object. - -Examples of usage from finance may include the addition of data -for keeping track of sources, last-update times, financial -instrument descriptions or details, etc. - -The idea behind \code{xts} is to offer the user the ability to utilize -a standard zoo object, while providing an mechanism to customize -the object's meta-data, as well as create custom methods to handle -the object in a manner required by the user. - -Many xts-specific methods have been written to better handle the -unique aspects of xts. These include, \sQuote{"["}, merge, cbind, -rbind, c, Ops, lag, diff, coredata, head and tail. Additionally -there are xts specific methods for converting to/from R's different -time-series classes. - -Subsetting via "[" methods offers the ability to specify dates by -range, if they are enclosed in quotes. The style borrows from -python by creating ranges with a double colon \dQuote{"::"} or \dQuote{"/"} operator. Each side of -the operator may be left blank, which would then default to the beginning -and end of the data, respectively. To specify a subset of times, -it is only required that the time specified be in standard ISO format, with -some form of separation between the elements. The time must be \sQuote{left-filled}, -that is to specify a full year one needs only to provide the year, a month would require -the full year and the integer of the month requested - e.g. '1999-01'. -This format would extend all the way down to seconds - e.g. '1999-01-01 08:35:23'. -Leading zeros are not necessary. See the examples for more detail. - -Users may also extend the \code{xts} class to new classes to -allow for method overloading. - -Additional benefits derive from the use of \code{\link{as.xts}} and -\code{\link{reclass}}, which allow for lossless two-way conversion -between common R time-series classes and the \code{xts} object -structure. See those functions for more detail. +\item{index}{A corresponding \emph{numeric} vector specified as seconds since +the UNIX epoch (1970-01-01 00:00:00.000).} +\item{tclass}{Time class to use for the index. See \code{\link[=tclass]{tclass()}}.} +\item{check}{Must the index be ordered? The index cannot contain duplicates +when \code{check = TRUE} and \code{unique = TRUE}.} } \value{ -An S3 object of class \code{xts}. As it inherits and extends -the zoo class, all zoo methods remain valid. Additional -attributes may be assigned and extracted via -\code{xtsAttributes}. +An S3 object of class xts. +} +\description{ +Constructor function for creating an extensible time-series object. } -\references{ \pkg{zoo}: } -\author{ Jeffrey A. Ryan and Joshua M. Ulrich } -\note{ -Most users will benefit the most by using the -\code{as.xts} and \code{reclass} functions to -automagically handle \emph{all} data objects -as one would handle a \code{zoo} object. +\details{ +\code{xts()} is used to create an xts object from raw data inputs. The xts class +inherits from and extends the zoo class, which means most zoo functions can +be used on xts objects. + +The \code{xts()} constructor is the preferred way to create xts objects. It +performs several checks to ensure it returns a well-formed xts object. The +\code{.xts()} constructor is mainly for internal use. It is more efficient then +the regular \code{xts()} constructor because it doesn't perform as many validity +checks. Use it with caution. + +Similar to zoo objects, xts objects must have an ordered index. While zoo +indexes cannot contain duplicate values, xts objects have optionally +supported duplicate index elements since version 0.5-0. The xts class has +one additional requirement: the index must be a time-based class. Currently +supported classes include: \sQuote{Date}, \sQuote{POSIXct}, \sQuote{timeDate}, +as well as \sQuote{yearmon} and \sQuote{yearqtr} where the index values +remain unique. + +The uniqueness requirement was relaxed in version 0.5-0, but is still +enforced by default. Setting \code{unique = FALSE} skips the uniqueness check and +only ensures that the index is ordered via the \code{isOrdered()} function. +As of version 0.10-0, xts no longer allows missing values in the index. This +is because many xts functions expect all index values to be finite. The most +important of these is \code{merge.xts()}, which is used ubiquitously. Missing +values in the index are usually the result of a date-time conversion error +(e.g. incorrect format, non-existent time due to daylight saving time, etc.). +Because of how non-finite numbers are represented, a missing timestamp will +always be at the end of the index (except if it is \code{-Inf}, which will be +first). + +Another difference from \pkg{zoo} is that xts object may carry additional +attributes that may be desired in individual time-series handling. This +includes the ability to augment the objects data with meta-data otherwise +not cleanly attachable to a standard zoo object. These attributes may be +assigned and extracted via \code{\link[=xtsAttributes]{xtsAttributes()}} and \code{\link{xtsAttributes<-}}, +respectively. + +Examples of usage from finance may include the addition of data for keeping +track of sources, last-update times, financial instrument descriptions or +details, etc. + +The idea behind \pkg{xts} is to offer the user the ability to utilize a +standard zoo object, while providing an mechanism to customize the object's +meta-data, as well as create custom methods to handle the object in a manner +required by the user. + +Many xts-specific methods have been written to better handle the unique +aspects of xts. These include, subsetting (\code{[}), \code{merge()}, \code{cbind()}, +\code{rbind()}, \code{c()}, math and logical operations, \code{lag()}, \code{diff()}, +\code{coredata()}, \code{head()}, and \code{tail()}. There are also xts-specific methods +for converting to/from R's different time-series classes. + +Subsetting via \code{[} methods offers the ability to specify dates by range, if +they are enclosed in quotes. The style borrows from python by creating +ranges separated by a double colon \dQuote{"::"} or \dQuote{"/"}. Each side +of the range may be left blank, which would then default to the start and +end of the data, respectively. To specify a subset of times, it is only +required that the time specified be in standard ISO format, with some form +of separation between the elements. The time must be \emph{left-filled}, that is +to specify a full year one needs only to provide the year, a month requires +the full year and the integer of the month requested - e.g. '1999-01'. This +format would extend all the way down to seconds - e.g. '1999-01-01 08:35:23'. +Leading zeros are not necessary. See the examples for more detail. + +Users may also extend the xts class to new classes to allow for method +overloading. + +Additional benefits derive from the use of \code{\link[=as.xts]{as.xts()}} and \code{\link[=reclass]{reclass()}}, +which allow for lossless two-way conversion between common R time-series +classes and the xts object structure. See those functions for more detail. } -\seealso{ \code{\link{as.xts}}, \code{\link{index}}, \code{\link{tclass}}, - \code{\link{tformat}}, \code{\link{tzone}}, \code{\link{xtsAttributes}} } \examples{ + data(sample_matrix) sample.xts <- as.xts(sample_matrix, descr='my new xts object') @@ -149,5 +148,16 @@ sample.xts['2007-03/2007'] # March 2007 to the end of 2007 sample.xts['/'] # the whole data set sample.xts['/2007'] # the beginning of the data through 2007 sample.xts['2007-01-03'] # just the 3rd of January 2007 + +} +\references{ +\pkg{zoo} +} +\seealso{ +\code{\link[=as.xts]{as.xts()}}, \code{\link[=index]{index()}}, \code{\link[=tclass]{tclass()}}, \code{\link[=tformat]{tformat()}}, \code{\link[=tzone]{tzone()}}, +\code{\link[=xtsAttributes]{xtsAttributes()}} +} +\author{ +Jeffrey A. Ryan and Joshua M. Ulrich } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/xtsAPI.Rd b/man/xtsAPI.Rd index e7349566..dd6e4a6e 100644 --- a/man/xtsAPI.Rd +++ b/man/xtsAPI.Rd @@ -1,19 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xts-package.R \name{xtsAPI} \alias{xtsAPI} -\title{ xts C API Documentation } +\title{xts C API Documentation} \description{ -This help file is to help in development of xts, as well -as provide some clarity and insight into its purpose and implementation. - -By Jeffrey A. Ryan, Dirk Eddelbuettel, and Joshua M. Ulrich -Last modified: 2018-05-02 -Version: 0.10-3 and above +This help file is to help in development of xts, as well as provide some +clarity and insight into its purpose and implementation. +} +\details{ +By Jeffrey A. Ryan, Dirk Eddelbuettel, and Joshua M. Ulrich Last modified: +2018-05-02 Version: 0.10-3 and above -At present the \pkg{xts} API has publicly available -interfaces to the following functions (as defined in \code{xtsAPI.h}): +At present the \pkg{xts} API has publicly available interfaces to the +following functions (as defined in \code{xtsAPI.h}): -\preformatted{ -Callable from other R packages: +\preformatted{Callable from other R packages: SEXP xtsIsOrdered(SEXP x, SEXP increasing, SEXP strictly) SEXP xtsNaCheck(SEXP x, SEXP check) SEXP xtsTry(SEXP x) @@ -48,12 +49,16 @@ Callable from R: } } \examples{ + \dontrun{ # some example code to look at file.show(system.file('api_example/README', package="xts")) file.show(system.file('api_example/src/checkOrder.c', package="xts")) } + +} +\author{ +Jeffrey A. Ryan } -\author{ Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/man/xtsAttributes.Rd b/man/xtsAttributes.Rd index c5341f2c..bee3064d 100644 --- a/man/xtsAttributes.Rd +++ b/man/xtsAttributes.Rd @@ -1,38 +1,37 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/coredata.xts.R \name{xtsAttributes} \alias{xtsAttributes} \alias{xtsAttributes<-} -%- Also NEED an '\alias' for EACH other topic documented here. -\title{ Extract and Replace xts Attributes } -\description{ -Extract and replace non-core \code{xts} attributes. -} +\title{Extract and Replace xts Attributes} \usage{ -xtsAttributes(x, user=NULL) +xtsAttributes(x, user = NULL) xtsAttributes(x) <- value } -%- maybe also 'usage' for other objects documented here. \arguments{ - \item{x}{ an xts object } - \item{user}{ logical; should user-defined attributes be returned? - The default of \code{NULL} returns all \code{xts} attributes. } - \item{value}{ a list of new name=value attributes } -} -\details{ -Since \code{xts} objects are S3 objects with special -attributes, a method is necessary to properly assign -and view the user-added attributes. +\item{x}{An xts object.} -A call to \code{attributes} from the \pkg{base} package -will return all attributes, including those specific -to the \code{xts} class. +\item{user}{Should user-defined attributes be returned? The default of +\code{NULL} returns all xts attributes.} + +\item{value}{A list of new \code{name = value} attributes.} } \value{ -A named list of user settable attributes. +A named list of user-defined attributes. +} +\description{ +Extract and replace non-core xts attributes. +} +\details{ +This function allows users to assign custom attributes to the xts objects, +without altering core xts attributes (i.e. tclass, tzone, and tformat). + +\code{\link[=attributes]{attributes()}} returns all attributes, including core attributes of the +xts class. } -\author{ Jeffrey A. Ryan } -\seealso{ \code{\link{attributes}}} \examples{ + x <- xts(matrix(1:(9*6),nc=6), order.by=as.Date(13000,origin="1970-01-01")+1:9, a1='my attribute') @@ -43,5 +42,12 @@ xtsAttributes(x) <- list(a2=2020) xtsAttributes(x) xtsAttributes(x) <- list(a1=NULL) xtsAttributes(x) + +} +\seealso{ +\code{\link[=attributes]{attributes()}} +} +\author{ +Jeffrey A. Ryan } -\keyword{ utilities } +\keyword{utilities} diff --git a/release-checklist.md b/release-checklist.md index cf58e686..f6663c48 100644 --- a/release-checklist.md +++ b/release-checklist.md @@ -6,18 +6,12 @@ ### Package Testing - [ ] Ensure all [*Additional* CRAN checks](https://cran.r-project.org/web/checks/check_results_xts.html) are addressed -- [ ] Run via R-Hub for linux, Windows, Solaris - ```r - platforms <- - c("linux-x86_64-rocker-gcc-san", - "solaris-x86-patched", - "windows-x86_64-devel", - "windows-x86_64-release", - "ubuntu-rchk") - rhub::check("xts_X.Y.Z.tar.gz", platforms) - ``` - [ ] Run R-devel on Win-builder - [ ] Use [Winston's R-debug containers](https://github.com/wch/r-debug) for valgrind, UBSAN, and ASAN + * Start container: `docker run --rm -tiv [pwd]:/opt/xts/ wch1/r-debug:latest` + * Get dependencies: `RDscript -e 'install.packages("xts", dependencies = TRUE)'` + * Run check: `RD CMD check xts_X.Y.Z.tar.gz` + * Install and run check with the remaining builds: `Rsan`, `Rcsan`, `Rvalgrind` - [ ] Run rchk * `docker run --rm -v [pwd]/packages:/rchk/packages kalibera/rchk /rchk/packages/xts_X.Y.Z.tar.gz` diff --git a/src/merge.c b/src/merge.c index 7d2a5349..360f67ad 100644 --- a/src/merge.c +++ b/src/merge.c @@ -32,33 +32,29 @@ SEXP xts_merge_make_colnames (SEXP colnames, SEXP suffixes, SEXP check_names, SE // add suffixes if (R_NilValue != suffixes) { - SEXP s, t; - PROTECT(s = t = allocList(4)); p++; - SET_TYPEOF(s, LANGSXP); - SETCAR(t, install("paste")); t = CDR(t); - SETCAR(t, newcolnames); t = CDR(t); - SETCAR(t, suffixes); t = CDR(t); - SETCAR(t, mkString("")); - SET_TAG(t, install("sep")); + SEXP args = PROTECT(allocList(3)); p++; + SEXP vals = args; + SETCAR(vals, newcolnames); vals = CDR(vals); + SETCAR(vals, suffixes); vals = CDR(vals); + SETCAR(vals, mkString("")); + SET_TAG(vals, install("sep")); - PROTECT(newcolnames = eval(s, env)); p++; + SEXP expr = PROTECT(LCONS(install("paste"), args)); p++; + PROTECT(newcolnames = eval(expr, env)); p++; } // check that names are 'valid R names' if (LOGICAL(check_names)[0]) { - SEXP s, t, unique; - PROTECT(s = t = allocList(3)); p++; - SET_TYPEOF(s, LANGSXP); - PROTECT(unique = ScalarLogical(1)); p++; + SEXP args = PROTECT(allocList(2)); p++; + SEXP vals = args; + SETCAR(vals, newcolnames); vals = CDR(vals); + SETCAR(vals, ScalarLogical(1)); + SET_TAG(vals, install("unique")); - SETCAR(t, install("make.names")); t = CDR(t); - SETCAR(t, newcolnames); t = CDR(t); - SETCAR(t, unique); - SET_TAG(t, install("unique")); - - PROTECT(newcolnames = eval(s, env)); p++; + SEXP expr = PROTECT(LCONS(install("make.names"), args)); p++; + PROTECT(newcolnames = eval(expr, env)); p++; } UNPROTECT(p); @@ -264,8 +260,7 @@ SEXP do_merge_xts (SEXP x, SEXP y, int nrx, ncx, nry, ncy, len; int left_join, right_join; int p = 0; - SEXP xindex, yindex, index, result, attr, len_xindex; - SEXP s, t; + SEXP xindex, yindex, index, result, attr; int *int_index=NULL, *int_xindex=NULL, *int_yindex=NULL; double *real_index=NULL, *real_xindex=NULL, *real_yindex=NULL; @@ -285,17 +280,19 @@ SEXP do_merge_xts (SEXP x, SEXP y, /* convert to xts object if needed */ if (!asInteger(isXts(y))) { - PROTECT(s = t = allocList(4)); p++; - SET_TYPEOF(s, LANGSXP); - SETCAR(t, install("try.xts")); t = CDR(t); - SETCAR(t, y); t = CDR(t); - PROTECT(len_xindex = allocVector(INTSXP, 1)); p++; - INTEGER(len_xindex)[0] = length(xindex); - SETCAR(t, len_xindex); - SET_TAG(t, install("length.out")); t = CDR(t); - SETCAR(t, install(".merge.xts.scalar")); - SET_TAG(t, install("error")); - PROTECT(y = eval(s, env)); p++; + + SEXP args = PROTECT(allocList(3)); p++; + SEXP vals = args; + SETCAR(vals, y); vals = CDR(vals); + + SET_TAG(vals, install("length.out")); + SETCAR(vals, ScalarInteger(length(xindex))); vals = CDR(vals); + + SET_TAG(vals, install("error")); + SETCAR(vals, install(".merge.xts.scalar")); + + SEXP expr = PROTECT(LCONS(install("try.xts"), args)); p++; + PROTECT(y = eval(expr, env)); p++; } if (asInteger(isXts(y))) { @@ -333,7 +330,6 @@ SEXP do_merge_xts (SEXP x, SEXP y, } else { nrx = LENGTH(xindex); ncx = 0; - PROTECT(x = coerceVector(x, TYPEOF(y))); p++; } int return_y_data = LOGICAL(retside)[1]; @@ -360,21 +356,27 @@ SEXP do_merge_xts (SEXP x, SEXP y, } else { nry = LENGTH(yindex); ncy = 0; - PROTECT(y = coerceVector(y, TYPEOF(x))); p++; } /* do the inputs have any data to merge? */ len = nrx + nry; if (len < 1 && ncx < 1 && ncy < 1) { - /* nothing to do, return empty xts object */ - SEXP s, t; - PROTECT(s = t = allocList(1)); p++; - SET_TYPEOF(s, LANGSXP); - SETCAR(t, install("xts")); - SEXP out = PROTECT(eval(s, env)); p++; - SET_TYPEOF(out, TYPEOF(x)); + + /* return empty xts object if there are no rows or columns */ + PROTECT(result = allocVector(TYPEOF(x), 0)); p++; + PROTECT(index = allocVector(TYPEOF(xindex), 0)); p++; + setAttrib(index, xts_IndexTzoneSymbol, getAttrib(xindex, xts_IndexTzoneSymbol)); + setAttrib(index, xts_IndexTclassSymbol, getAttrib(xindex, xts_IndexTclassSymbol)); + setAttrib(index, xts_IndexTformatSymbol, getAttrib(xindex, xts_IndexTformatSymbol)); + setAttrib(result, xts_IndexSymbol, index); + + if (LOGICAL(retclass)[0]) { + setAttrib(result, R_ClassSymbol, getAttrib(x, R_ClassSymbol)); + } + setAttrib(result, xts_ClassSymbol, getAttrib(x, xts_ClassSymbol)); + UNPROTECT(p); - return out; + return result; } /* Ensure both indexes are REAL if they are not the same type. */ diff --git a/src/tryXts.c b/src/tryXts.c index 1f5a48ee..973da5dc 100644 --- a/src/tryXts.c +++ b/src/tryXts.c @@ -28,14 +28,14 @@ SEXP tryXts (SEXP x) { if( !Rf_asInteger(isXts(x)) ) { int P = 0; - SEXP s, t, result, env, str_xts; - PROTECT(s = t = allocList(2)); P++; - SET_TYPEOF(s, LANGSXP); - SETCAR(t, install("try.xts")); t = CDR(t); - SETCAR(t, x); t=CDR(t); + SEXP expr, result, env, str_xts; + PROTECT(str_xts = mkString("xts")); P++; PROTECT(env = R_FindNamespace(str_xts)); P++; - PROTECT(result = eval(s, env)); P++; + + PROTECT(expr = LCONS(install("try.xts"), x)); P++; + PROTECT(result = eval(expr, env)); P++; + if( !Rf_asInteger(isXts(result)) ) { UNPROTECT(P); error("rbind.xts requires xtsible data");