| Version: | 1.8-15 |
| Date: | 2025-12-15 |
| Title: | S3 Infrastructure for Regular and Irregular Time Series (Z'sOrdered Observations) |
| Description: | An S3 class with methods for totally ordered indexed observations. It is particularly aimed at irregular time series of numeric vectors/matrices and factors. zoo's key design goals are independence of a particular index/date/time class and consistency with ts and base R by providing methods to extend standard generics. |
| Depends: | R (≥ 3.1.0), stats |
| Suggests: | AER, coda, chron, ggplot2 (≥ 3.5.0), mondate, scales,stinepack, strucchange, timeDate, timeSeries, tinyplot, tis,tseries, xts |
| Imports: | utils, graphics, grDevices, lattice (≥ 0.20-27) |
| License: | GPL-2 |GPL-3 |
| URL: | https://zoo.R-Forge.R-project.org/ |
| NeedsCompilation: | yes |
| Packaged: | 2025-12-15 12:01:09 UTC; zeileis |
| Author: | Achim Zeileis |
| Maintainer: | Achim Zeileis <Achim.Zeileis@R-project.org> |
| Repository: | CRAN |
| Date/Publication: | 2025-12-15 14:30:02 UTC |
Value Matching
Description
MATCH is a generic function for value matching.
Usage
MATCH(x, table, nomatch = NA, ...)## S3 method for class 'times'MATCH(x, table, nomatch = NA, units = "sec", eps = 1e-10, ...)Arguments
x | an object. |
table | the values to be matched against. |
nomatch | the value to be returned in the case when no match isfound. Note that it is coerced to |
units | See |
eps | See |
... | further arguments to be passed to methods. |
Details
MATCH is a new generic function which aims at providingthe functionality of the non-generic base functionmatchfor arbitrary objects. Currently, there is a default method whichsimply callsmatch and various methods for time/dateobjects.
TheMATCH method forDate objects coerces thetabletoDate as well (if necessary) and then usesmatch(unclass(x), unclass(table), .... Similarly, theMATCHmethods forPOSIXct,POSIXlt, andtimeDate coercebothx andtable toPOSIXct and then match the unclassedobjects.
MATCH.times is used forchron objects.x willmatch any time intable less thanunits away.
See Also
Examples
MATCH(1:5, 2:3)Ordering Permutation
Description
ORDER is a generic function for computing orderingpermutations.
Usage
ORDER(x, ...)## Default S3 method:ORDER(x, ..., na.last = TRUE, decreasing = FALSE)Arguments
x | an object. |
... | further arguments to be passed to methods. |
na.last | for controlling the treatment of |
decreasing | logical. Should the sort order be increasing ordecreasing? |
Details
ORDER is a new generic function which aims at providingthe functionality of the non-generic base functionorderfor arbitrary objects. Currently, there is only a default method whichsimply callsorder. For objects (more precisely ifis.object isTRUE)orderleverages the genericxtfrm. Thus, to assure orderingworks, one can supply either a method toxtfrm or toORDER(or both).
See Also
Examples
ORDER(rnorm(5))Compute Summary Statistics of zoo Objects
Description
Splits a"zoo" object into subsets along a coarser index grid,computes summary statistics for each, and returns the reduced"zoo" object.
Usage
## S3 method for class 'zoo'aggregate(x, by, FUN = sum, ..., regular = NULL, frequency = NULL, coredata = TRUE)Arguments
x | an object of class |
by | index vector of the same length as |
FUN | a function to compute the summary statistics which can be appliedto all subsets. Always needs to return a result of fixed length (typicallyscalar). |
... | further arguments passed to |
regular | logical. Should the aggregated series be coerced to class |
frequency | numeric indicating the frequency of the aggregated series(if a |
coredata | logical. Should only the |
Value
An object of class"zoo" or"zooreg".
Note
Thexts package functionsendpoints,period.applyto.period,to.weekly,to.monthly, etc., can also directly input and output certainzoo objects and so can be used for aggregation tasks in some cases as well.
See Also
Examples
## averaging over values in a month:# x.date is jan 1,3,5,7; feb 9,11,13; mar 15,17,19x.date <- as.Date(paste(2004, rep(1:4, 4:1), seq(1,20,2), sep = "-")); x.datex <- zoo(rnorm(12), x.date); x# coarser dates - jan 1 (4 times), feb 1 (3 times), mar 1 (3 times)x.date2 <- as.Date(paste(2004, rep(1:4, 4:1), 1, sep = "-")); x.date2x2 <- aggregate(x, x.date2, mean); x2# same - uses as.yearmonx2a <- aggregate(x, as.Date(as.yearmon(time(x))), mean); x2a# same - uses by functionx2b <- aggregate(x, function(tt) as.Date(as.yearmon(tt)), mean); x2b# same - uses cutx2c <- aggregate(x, as.Date(cut(time(x), "month")), mean); x2c# almost same but times of x2d have yearmon class rather than Date classx2d <- aggregate(x, as.yearmon, mean); x2d# compare time seriesplot(x)lines(x2, col = 2)## aggregate a daily time series to a quarterly series# create zoo seriestt <- as.Date("2000-1-1") + 0:300z.day <- zoo(0:300, tt)# function which returns corresponding first "Date" of quarterfirst.of.quarter <- function(tt) as.Date(as.yearqtr(tt))# average z over quarters# 1. via "yearqtr" index (regular)# 2. via "Date" index (not regular)z.qtr1 <- aggregate(z.day, as.yearqtr, mean)z.qtr2 <- aggregate(z.day, first.of.quarter, mean)# The last one used the first day of the quarter but suppose# we want the first day of the quarter that exists in the series# (and the series does not necessarily start on the first day# of the quarter).z.day[!duplicated(as.yearqtr(time(z.day)))]# This is the same except it uses the last day of the quarter.# It requires R 2.6.0 which introduced the fromLast= argument.## Not run: z.day[!duplicated(as.yearqtr(time(z.day)), fromLast = TRUE)]## End(Not run)# The aggregated series above are of class "zoo" (because z.day# was "zoo"). To create a regular series of class "zooreg",# the frequency can be automatically chosenzr.qtr1 <- aggregate(z.day, as.yearqtr, mean, regular = TRUE)# or specified explicitelyzr.qtr2 <- aggregate(z.day, as.yearqtr, mean, frequency = 4)## aggregate on month and extend to monthly time seriesif(require(chron)) {y <- zoo(matrix(11:15, nrow = 5, ncol = 2), chron(c(15, 20, 80, 100, 110)))colnames(y) <- c("A", "B")# aggregate by month using first of month as times for coarser series# using first day of month as repesentative timey2 <- aggregate(y, as.Date(as.yearmon(time(y))), head, 1)# fill in missing months by merging with an empty series containing# a complete set of 1st of the monthsyrt2 <- range(time(y2))y0 <- zoo(,seq(from = yrt2[1], to = yrt2[2], by = "month"))merge(y2, y0)}# given daily series keep only first point in each month at# day 21 or morez <- zoo(101:200, as.Date("2000-01-01") + seq(0, length = 100, by = 2))zz <- z[as.numeric(format(time(z), "%d")) >= 21]zz[!duplicated(as.yearmon(time(zz)))]# same except times are of "yearmon" classaggregate(zz, as.yearmon, head, 1)# aggregate POSIXct seconds data every 10 minutesSys.setenv(TZ = "GMT")tt <- seq(10, 2000, 10)x <- zoo(tt, structure(tt, class = c("POSIXt", "POSIXct")))aggregate(x, time(x) - as.numeric(time(x)) %% 600, mean)# aggregate weekly series to a series with frequency of 52 per yearsuppressWarnings(RNGversion("3.5.0"))set.seed(1)z <- zooreg(1:100 + rnorm(100), start = as.Date("2001-01-01"), deltat = 7)# new.freq() converts dates to a grid of freq points per year# yd is sequence of dates of firsts of years# yy is years of the same sequence# last line interpolates so dates, d, are transformed to year + frac of year# so first week of 2001 is 2001.0, second week is 2001 + 1/52, third week# is 2001 + 2/52, etc.new.freq <- function(d, freq = 52) { y <- as.Date(cut(range(d), "years")) + c(0, 367) yd <- seq(y[1], y[2], "year") yy <- as.numeric(format(yd, "%Y")) floor(freq * approx(yd, yy, xout = d)$y) / freq}# take last point in each periodaggregate(z, new.freq, tail, 1)# or, take mean of all points in eachaggregate(z, new.freq, mean)# example of taking means in the presence of NAsz.na <- zooreg(c(1:364, NA), start = as.Date("2001-01-01"))aggregate(z.na, as.yearqtr, mean, na.rm = TRUE)# Find the sd of all days that lie in any Jan, all days that lie in# any Feb, ..., all days that lie in any Dec (i.e. output is vector with# 12 components)aggregate(z, format(time(z), "%m"), sd)Coercion from and to zoo
Description
Methods for coercing"zoo" objects to other classes anda generic functionas.zoo for coercing objects to class"zoo".
Usage
as.zoo(x, ...)Arguments
x | an object, |
... | further arguments passed to |
Details
as.zoo currently has a default method and methods forts,fts (currently archived on CRAN),irts,mcmc,tis,xts objects (andzoo objects themselves).
Methods for coercing objects of class"zoo" to other classescurrently include:as.ts,as.matrix,as.vector,as.data.frame,as.list (the latter also being availablefor"ts" objects). Furthermore,fortify.zoo can transform"zoo"series to"data.frame" including the time index and optionally melting a wide seriesinto a long data frame.
In the conversion betweenzoo andts, thezooreg class isalways used.
Value
as.zoo returns azoo object.
See Also
zoo,fortify.zoo,zooreg,ts,irts,tis,mcmc,xts.
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)## coercion to zoo:## default methodas.zoo(rnorm(5))## method for "ts" objectsas.zoo(ts(rnorm(5), start = 1981, freq = 12))## coercion from zoo:x.date <- as.POSIXct(paste("2003-", rep(1:4, 4:1), "-", sample(1:28, 10, replace = TRUE), sep = ""))x <- zoo(matrix(rnorm(24), ncol = 2), x.date)as.matrix(x)as.vector(x)as.data.frame(x)as.list(x)Extracting/Replacing the Core Data of Objects
Description
Generic functions for extracting the core data contained ina (more complex) object and replacing it.
Usage
coredata(x, ...)coredata(x) <- valueArguments
x | an object. |
... | further arguments passed to methods. |
value | a suitable value object for use with |
Value
Inzoo, there are currentlycoredata methods for time seriesobjects of class"zoo","ts","its","irts", all ofwhich strip off the index/time attributes and return only the observations.The are also corresponding replacement methods for these classes.
See Also
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)x.date <- as.Date(paste(2003, rep(1:4, 4:1), seq(1,20,2), sep = "-"))x <- zoo(matrix(rnorm(20), ncol = 2), x.date)## the full time seriesx## and only matrix of observationscoredata(x)## change the observationscoredata(x) <- matrix(1:20, ncol = 2)xReplacing the Index of Objects
Description
Generic function for replacing the frequency of an object.
Usage
frequency(x) <- valueArguments
x | an object. |
value | a frequency. |
Details
frequency<- is a generic function for replacing (or assigning)the frequency of an object. Currently, there is a"zooreg" anda"zoo" method. In both cases, thevalue is assignedto the"frequency" of the object if it complies with theindex(x).
See Also
Examples
z <- zooreg(1:5)zas.ts(z)frequency(z) <- 3zas.ts(z)Convenience Functions for Plotting zoo Objects with ggplot2
Description
fortify.zoo takes a zoo object and converts it into a data frame(intended for ggplot2).autoplot.zoo takes a zoo object and returns aggplot2 object. It essentially uses the mappingaes(x = Time, y = Value, group = Series)and addscolour = Series in the case of a multivariate series withfacets = NULL.
Usage
## S3 method for class 'zoo'autoplot(object, geom = "line", facets, ...) ## S3 method for class 'zoo'fortify(model, data, names = c("Index", "Series", "Value"),melt = FALSE, sep = NULL, ...) facet_free(facets = Series ~ ., margins = FALSE, scales = "free_y", ...) yearmon_trans(format = "%b %Y", n = 5) scale_x_yearmon(..., format = "%b %Y", n = 5) scale_y_yearmon(..., format = "%b %Y", n = 5) yearqtr_trans(format = "%Y-%q", n = 5) scale_x_yearqtr(..., format = "%Y-%q", n = 5) scale_y_yearqtr(..., format = "%Y-%q", n = 5)Arguments
object | an object of class |
geom | character (e.g., |
facets | specification of |
... | further arguments passed to |
model | an object of class |
data | not used (required by generic |
names | (list of) character vector(s). New names given to index/time column,series indicator (if melted), and value column (if melted). If onlya subset of characters should be changed, either NAs can be usedor a named vector. |
sep | If specified then the Series column is split into multiple columns using sep as the split character. |
melt | Should the resulting data frame be in long format ( |
margins | As in |
scales | As in |
format | A format acceptable toformat.yearmon orformat.yearqtr. |
n | Approximate number of axis ticks. |
Details
Convenience interface for visualizing zoo objects with ggplot2.autoplot.zoo usesfortify.zoo (withmelt = TRUE)to convert the zoo object into a data frame and then uses a suitableaes() mapping to visiualize the series.
Value
fortify.zoo returns adata.frame either in long format(melt = TRUE) or in wide format (melt = FALSE). Thelong format has three columns: the timeIndex, afactor indicating theSeries, and the correspondingValue.The wide format simply has the timeIndex plus all columnsofcoredata(model).
autoplot.zoo returns aggplot object.
Author(s)
Trevor L. Davistrevor.l.davis@gmail.com, Achim Zeileis
See Also
Examples
if(require("ggplot2") && require("scales")) {suppressWarnings(RNGversion("3.5.0"))set.seed(1)## example datax.Date <- as.Date(paste(2003, 02, c(1, 3, 7, 9, 14), sep = "-"))x <- zoo(rnorm(5), x.Date)xlow <- x - runif(5)xhigh <- x + runif(5)z <- cbind(x, xlow, xhigh)## univariate plottingautoplot(x)## by handggplot(aes(x = Index, y = Value), data = fortify(x, melt = TRUE)) + geom_line() + xlab("Index") + ylab("x")## adding series one at a timelast_plot() + geom_line(aes(x = Index, y = xlow), colour = "red", data = fortify(xlow))## add ribbon for high/low bandggplot(aes(x = Index, y = x, ymin = xlow, ymax = xhigh), data = fortify(x)) + geom_ribbon(fill = "darkgray") + geom_line()## multivariate plotting in multiple or single panelsautoplot(z) ## multiple without color/linetypeautoplot(z, facets = Series ~ .) ## multiple with series-dependent color/linetypeautoplot(z, facets = NULL) ## single with series-dependent color/linetype## by hand with color/linetype and with/without facetsggz <- ggplot(aes(x = Index, y = Value, group = Series, colour = Series, linetype = Series), data = fortify(z, melt = TRUE)) + geom_line() + xlab("Index") + ylab("")ggzggz + facet_grid(Series ~ .)## variationsautoplot(z, geom = "point")autoplot(z, facets = NULL) + geom_point()autoplot(z, facets = NULL) + scale_colour_grey() + theme_bw()## for "ts" series via coercionautoplot(as.zoo(EuStockMarkets))autoplot(as.zoo(EuStockMarkets), facets = NULL)autoplot(z) + aes(colour = NULL, linetype = NULL) +facet_grid(Series ~ ., scales = "free_y")autoplot(z) + aes(colour = NULL, linetype = NULL) + facet_free() # samez.yq <- zooreg(rnorm(50), as.yearqtr("2000-1"), freq = 4)autoplot(z.yq)## mimic matplotdata <- cbind(A = c(6, 1, NA, NA), B = c(16, 4, 1, NA), C = c(25, 7, 2, 1))autoplot(zoo(data), facet = NULL) + geom_point()## with different line typesautoplot(zoo(data), facet = NULL) + geom_point() + aes(linetype = Series)## illustrate just fortify() methodz <- zoo(data)fortify(z)fortify(z, melt = TRUE)fortify(z, melt = TRUE, names = c("Time", NA, "Data"))fortify(z, melt = TRUE, names = c(Index = "Time"))## with/without splittingz <- zoo(cbind(a.A = 1:2, a.B = 2:3, b.A = 3:4, c.B = 4:5))fortify(z)fortify(z, melt = TRUE, sep = ".", names = list(Series = c("Lower", "Upper")))## scale_x_yearmon with custom discrete breaksdf <- data.frame(dates = as.yearmon("2018-08") + 0:6/12, values = c(2:6, 0, 1))ggdf <- ggplot(df, aes(x = dates, y = values)) + geom_bar(position = "dodge", stat = "identity") + theme_light() + xlab("Month") + ylab("Values")ggdf ## with default scale_x_yearmonggdf + scale_x_yearmon(breaks = df$dates) ## with custom discrete breaks}Extracting/Replacing the Index of Objects
Description
Generic functions for extracting the index of an objectand replacing it.
Usage
index(x, ...)index(x) <- valueArguments
x | an object. |
... | further arguments passed to methods. |
value | an ordered vector of the same lengthas the |
Details
index is a generic function for extracting the indexof objects, currently it has a default method and a methodforzoo objects which is the same as thetime method forzoo objects.Another pair of generic functions provides replacingtheindex ortime attribute. Methods are available for"zoo" objects only, see examples below.
The start and end of the index/time can be queried by usingthe methods ofstart andend.
See Also
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)x.date <- as.Date(paste(2003, 2, c(1, 3, 7, 9, 14), sep = "-"))x <- zoo(rnorm(5), x.date)## query index/time of a zoo objectindex(x)time(x)## change class of index from Date to POSIXct## relative to current time zonexindex(x) <- as.POSIXct(format(time(x)),tz="")x## replace index/time of a zoo objectindex(x) <- 1:5xtime(x) <- 6:10x## query start and end of a zoo objectstart(x)end(x)## query index of a usual matrixxm <- matrix(rnorm(10), ncol = 2)index(xm)Check Regularity of a Series
Description
is.regular is a regular function for checking whether a series of ordered observationshas an underlying regularity or is even strictly regular.
Usage
is.regular(x, strict = FALSE)Arguments
x | an object (representing a series of ordered observations). |
strict | logical. Should strict regularity be checked? See details. |
Details
A time series can either be irregular (unequally spaced), strictly regular (equally spaced)or have an underlying regularity, i.e., be created from a regular series byomitting some observations. Here, the latter property is calledregular.Consequently, regularity follows from strict regularity but not vice versa.
is.regular is a generic function for checking regularity (default) orstrict regularity. Currently, it has methods for"ts" objects (which arealways strictly regular),"zooreg" objects (which are at least regular),"zoo" objects (which can be either irregular, regular or even strictly regular)and a default method. The latter coercesx to"zoo" before checkingits regularity.
Value
A logical is returned indicating whetherx is (strictly) regular.
See Also
Examples
## checking of a strictly regular zoo seriesz <- zoo(1:10, seq(2000, 2002.25, by = 0.25), frequency = 4)zclass(z)frequency(z) ## extraction of frequency attributeis.regular(z)is.regular(z, strict = TRUE)## by omitting observations, the series is not strictly regularis.regular(z[-3])is.regular(z[-3], strict = TRUE)## checking of a plain zoo series without frequency attribute## which is in fact regularz <- zoo(1:10, seq(2000, 2002.25, by = 0.25))zclass(z)frequency(z) ## data driven computation of frequencyis.regular(z)is.regular(z, strict = TRUE)## by omitting observations, the series is not strictly regularis.regular(z[-3])is.regular(z[-3], strict = TRUE)suppressWarnings(RNGversion("3.5.0"))set.seed(1)## checking of an irregular zoo seriesz <- zoo(1:10, rnorm(10))zclass(z)frequency(z) ## attempt of data-driven frequency computationis.regular(z)is.regular(z, strict = TRUE)Lags and Differences of zoo Objects
Description
Methods for computing lags and differences of"zoo" objects.
Usage
## S3 method for class 'zoo'lag(x, k = 1, na.pad = FALSE, ...)## S3 method for class 'zoo'diff(x, lag = 1, differences = 1, arithmetic = TRUE, na.pad = FALSE, log = FALSE, ...)Arguments
x | a |
k,lag | For |
differences | an integer indicating the order of the difference. |
arithmetic | logical. Should arithmetic (or geometric) differences be computed? |
na.pad | logical. If |
log | logical. Should the differences of the log series be computed? |
... | currently not used. |
Details
These methods for"zoo" objects behave analogously to the defaultmethods. The only additional arguments arearithmetic andlog indiffandna.pad in bothlag.zoo anddiff.zoo.Also,"k" can be a vector of lags in which case the names of"k", if any, are used in naming the result.
Value
The lagged or differenced"zoo" object.
Note
Note the sign ofk: a series lagged by a positivekis shiftedearlier in time.
lag.zoo andlag.zooreg can give different results.For a lag of 1lag.zoo moves points to the adjacent time pointwhereaslag.zooreg moves the time bydeltat. Thisimplies that a point in azoo series cannot be lagged to a time point that is not already in the series whereas this is possible forazooreg series.
See Also
Examples
x <- zoo(11:21)lag(x, k = 1)lag(x, k = -1)# this pairs each value of x with the next or future valuemerge(x, lag1 = lag(x, k=1))diff(x^3)diff(x^3, -1)diff(x^3, na.pad = TRUE)Make a List from a Parameter Specification
Description
Process parameters so that a list of parameterspecifications is returned (used byplot.zoo andxyplot.zoo).
Usage
make.par.list(nams, x, n, m, def, recycle = sum(unnamed) > 0)Arguments
nams | character vector with names of variables. |
x | list or vector of parameter specifications, see details. |
n | numeric, number of rows. |
m | numeric, number of columns. (Only determines whether |
def | default parameter value. |
recycle | logical. If |
Details
This function is currently intended for internal use. It is currently used byplot.zoo andxyplot.zoo but might also be used in the futureto create additional new plotting routines.It creates a new list which uses the named variables fromxand then assigns the unnamed in order. For the remaining variablesassign them the default value if!recycle or recycle theunnamed variables ifrecycle.
Value
A list of parameters, see details.
Examples
make.par.list(letters[1:5], 1:5, 3, 5)suppressWarnings( make.par.list(letters[1:5], 1:4, 3, 5, 99) )make.par.list(letters[1:5], c(d=3), 3, 5, 99)make.par.list(letters[1:5], list(d=1:2, 99), 3, 5)make.par.list(letters[1:5], list(d=1:2, 99, 100), 3, 5)Merge Two or More zoo Objects
Description
Merge two zoo objects by common indexes (times), or do otherversions of databasejoin operations.
Usage
## S3 method for class 'zoo'merge(..., all = TRUE, fill = NA, suffixes = NULL, check.names = FALSE, retclass = c("zoo", "list", "data.frame"), drop = TRUE, sep = ".")Arguments
... | two or more objects, usually of class |
all | logical vector having the same length as the number of |
fill | an element for filling gaps in merged |
suffixes | character vector of the same length as the number of |
check.names | See |
retclass | character that specifies the class of the returned result.It can be |
drop | logical. If a |
sep | character. Separator character that should be used whenpasting |
Details
Themerge method for"zoo" objects combines the columnsof several objects along the union of the dates forall = TRUE, the default,or the intersection of their dates forall = FALSEfilling up the created gaps (if any) with thefill pattern.
The first argument must be azoo object. If any of the remainingarguments are plain vectors or matrices with the same length or numberof rows as the first argument then such arguments are coerced to"zoo"usingas.zoo. If they are plain but have length 1 then they aremerged after all non-scalars such that their column is filled with thevalue of the scalar.
all can be a vector of the same length as the number of"zoo"objects to merged (if not, it is expanded): All indexes(times) of the objects corresponding toTRUE are included, for thosecorresponding toFALSE only the indexes present in all objects areincluded. This allows intersection, union and left and right joins to be expressed.
Ifretclass is"zoo" (the default) a single merged"zoo"object is returned. If it is set to"list" a list of"zoo"objects is returned. Ifretclass = NULL then instead of returning a value it updates eachargument (if it is a variable rather than an expression) inplace so as to extend or reduce it to use the common index vector.
The indexes of different"zoo" objects can be of different classes and are coerced toone class in the resulting object (with a warning).
The defaultcbind method is essentially the defaultmergemethod, but does not support theretclass argument.Therbindmethod combines the dates of the"zoo" objects (duplicate dates arenot allowed) and combines the rows of the objects. Furthermore, thec method is identical to therbind method.
Value
An object of class"zoo" ifretclass="zoo", an object ofclass"list" ifretclass="list" or modified arguments asexplained above ifretclass=NULL. If the result is an objectof class"zoo" then its frequency is the common frequency of itszoo arguments, if they have a common frequency.
See Also
Examples
## simple mergingx.date <- as.Date(paste(2003, 02, c(1, 3, 7, 9, 14), sep = "-"))x <- zoo(rnorm(5), x.date)y1 <- zoo(matrix(1:10, ncol = 2), 1:5)y2 <- zoo(matrix(rnorm(10), ncol = 2), 3:7)## using arguments `fill' and `suffixes'merge(y1, y2, all = FALSE)merge(y1, y2, all = FALSE, suffixes = c("a", "b"))merge(y1, y2, all = TRUE)merge(y1, y2, all = TRUE, fill = 0)## if different index classes are merged, as in## the next merge example then ## a warning is issued and ### the indexes are coerced.## It is up to the user to ensure that the result makes sense.merge(x, y1, y2, all = TRUE)## extend an irregular series to a regular one:# create a constant seriesz <- zoo(1, seq(4)[-2])# create a 0 dimensional zoo seriesz0 <- zoo(, 1:4)# do the extensionmerge(z, z0)# same but with zero fillmerge(z, z0, fill = 0)merge(z, coredata(z), 1)## merge multiple series represented in a long form data frame ## into a multivariate zoo series and plot, one series for each site.## Additional examples can be found here:## https://stat.ethz.ch/pipermail/r-help/2009-February/187094.html## https://stat.ethz.ch/pipermail/r-help/2009-February/187096.html##m <- 5 # no of yearsn <- 6 # no of sitessites <- LETTERS[1:n]suppressWarnings(RNGversion("3.5.0"))set.seed(1)DF <- data.frame(site = sites, year = 2000 + 1:m, data = rnorm(m*n))tozoo <- function(x) zoo(x$data, x$year) Data <- do.call(merge, lapply(split(DF, DF$site), tozoo))plot(Data, screen = 1, col = 1:n, pch = 1:n, type = "o", xlab = "")legend("bottomleft", legend = sites, lty = 1, pch = 1:n, col = 1:n)## for each index value in x merge it with the closest index value in y## but retaining x's times.x<-zoo(1:3,as.Date(c("1992-12-13", "1997-05-12", "1997-07-13")))y<-zoo(1:5,as.Date(c("1992-12-15", "1992-12-16", "1997-05-10","1997-05-19", "1997-07-13")))f <- function(u) which.min(abs(as.numeric(index(y)) - as.numeric(u)))ix <- sapply(index(x), f)cbind(x, y = coredata(y)[ix])## this merges each element of x with the closest time point in y at or## after x's time point (whereas in previous example it could be before## or after)window(na.locf(merge(x, y), fromLast = TRUE), index(x))## c() can combine several zoo series, e.g., zoo series with Date indexz <- zoo(1:5, as.Date("2000-01-01") + 0:4)z2 <- zoo(6:7, time(z)[length(z)] + 1:2)## c() combines these in a single seriesc(z, z2)## the order does not matterc(z2, z)## note, however, that combining a zoo series with an unclassed vector## of observations would try to coerce the indexes first## which might either give an unexpected result or an error in R >= 4.1.0## c(z, 6:7)Fill NA or specified positions.
Description
Generic function for fillingNA values using seasonal Kalman filter.
Usage
na.StructTS(object, ...)## S3 method for class 'ts'na.StructTS(object, ..., na.rm = FALSE, maxgap = Inf)## S3 method for class 'zoo'na.StructTS(object, ..., na.rm = FALSE, maxgap = Inf)Arguments
object | an object. |
... | other arguments passed to methods. |
na.rm | logical. Whether to remove end portions or fill them with NA. |
maxgap | Runs of more than |
Details
Interpolate with seasonal Kalman filter, usingStructTS,followed bytsSmooth. The input object shouldbe a regular time series and have a frequency. It is assumed the cycle length is 1.
See Also
Examples
z <- zooreg(rep(10 * seq(8), each = 4) + rep(c(3, 1, 2, 4), times = 8), start = as.yearqtr(2000), freq = 4)z[25] <- NAzout <- na.StructTS(z)plot(cbind(z, zout), screen = 1, col = 1:2, type = c("l", "p"), pch = 20)Replace NA by Aggregation
Description
Generic function for replacing eachNA with aggregatedvalues. This allows imputing by the overall mean, by monthly means,etc.
Usage
na.aggregate(object, ...)## Default S3 method:na.aggregate(object, by = 1, ..., FUN = mean, na.rm = FALSE, maxgap = Inf)Arguments
object | an object. |
by | a grouping variable corresponding to |
... | further arguments passed to |
FUN | function to apply to the non-missing values in each groupdefined by |
na.rm | logical. Should any remaining |
maxgap | maximum number of consecutive |
Value
An object in which eachNA in the input object is replacedby the mean (or other function) of its group, defined byby. This is done for each series in a multi-column object. Commonchoices for the aggregation group are a year, a month, all calendarmonths, etc.
If a group has no non-missing values, the default aggregation functionmean will returnNaN. Specifyna.rm = TRUE toomit such remaining missing values.
See Also
Examples
z <- zoo(c(1, NA, 3:9), c(as.Date("2010-01-01") + 0:2, as.Date("2010-02-01") + 0:2, as.Date("2011-01-01") + 0:2))## overall meanna.aggregate(z)## group by monthsna.aggregate(z, as.yearmon)## group by calendar monthsna.aggregate(z, months)## group by yearsna.aggregate(z, format, "%Y")Replace NA by Interpolation
Description
Generic functions for replacing eachNA with interpolatedvalues.
Usage
na.approx(object, ...) ## S3 method for class 'zoo'na.approx(object, x = index(object), xout, ..., na.rm = TRUE, maxgap = Inf, along)## S3 method for class 'zooreg'na.approx(object, ...) ## S3 method for class 'ts'na.approx(object, ...)## Default S3 method:na.approx(object, x = index(object), xout, ..., na.rm = TRUE, maxgap = Inf, along) na.spline(object, ...) ## S3 method for class 'zoo'na.spline(object, x = index(object), xout, ..., na.rm = TRUE, maxgap = Inf, along)## S3 method for class 'zooreg'na.spline(object, ...) ## S3 method for class 'ts'na.spline(object, ...)## Default S3 method:na.spline(object, x = index(object), xout, ..., na.rm = TRUE, maxgap = Inf, along)Arguments
object | object in which |
x,xout | Variables to be used for interpolation as in |
na.rm | logical. If the result of the (spline) interpolationstill results in leading and/or trailing |
maxgap | maximum number of consecutive |
along | deprecated. |
... | further arguments passed to methods. The |
Details
Missing values (NAs) are replaced by linear interpolation viaapprox or cubic spline interpolation viaspline,respectively.
It can also be used for series disaggregation by specifyingxout.
By default the index associated withobject is usedfor interpolation. Note, that if this callsindex.defaultthis gives an equidistant spacing1:NROW(object). Ifobjectis a matrix or data.frame, the interpolation is done separately foreach column.
Ifobj is a plain vector thenna.approx(obj, x, y, xout, ...)returnsapprox(x = x[!na], y = coredata(obj)[!na], xout = xout, ...)(wherena indicates observations withNA) such thatxoutdefaults tox. Note that if there are less than two non-NAs thenapprox() cannot be applied and thus noNAs can be replaced.
Ifobj is azoo,zooreg orts object itscoredata value is processed as described and its time index isxout ifspecified andindex(obj) otherwise. Ifobj is two dimensionalthen the above is applied to each column separately. For examples, see below.
Ifobj has more than one column, the above strategy is applied toeach column.
Value
An object of similar structure asobject withNAs replaced byinterpolation. Forna.approx only the internalNAs are replaced andleading or trailingNAs are omitted ifna.rm = TRUE or notreplaced ifna.rm = FALSE.
See Also
zoo,approx,na.contiguous,na.locf,na.omit,na.trim,spline,stinterp
Examples
z <- zoo(c(2, NA, 1, 4, 5, 2), c(1, 3, 4, 6, 7, 8))## use underlying time scale for interpolationna.approx(z) ## use equidistant spacingna.approx(z, 1:6)# with and without na.rm = FALSEzz <- c(NA, 9, 3, NA, 3, 2)na.approx(zz, na.rm = FALSE)na.approx(zz)d0 <- as.Date("2000-01-01")z <- zoo(c(11, NA, 13, NA, 15, NA), d0 + 1:6)# NA fill, drop or keep leading/trailing NAsna.approx(z)na.approx(z, na.rm = FALSE)# extrapolate to point outside of range of time points# (a) drop NA, (b) keep NA, (c) extrapolate using rule = 2 from approx()na.approx(z, xout = d0 + 7)na.approx(z, xout = d0 + 7, na.rm = FALSE)na.approx(z, xout = d0 + 7, rule = 2)# use splines - extrapolation handled differentlyz <- zoo(c(11, NA, 13, NA, 15, NA), d0 + 1:6)na.spline(z)na.spline(z, na.rm = FALSE)na.spline(z, xout = d0 + 1:6)na.spline(z, xout = d0 + 2:5)na.spline(z, xout = d0 + 7)na.spline(z, xout = d0 + 7, na.rm = FALSE)## using na.approx for disaggregationzy <- zoo(1:3, 2000:2001)# yearly to monthly serieszmo <- na.approx(zy, xout = as.yearmon(2000+0:13/12))zmo# monthly to daily seriessq <- seq(as.Date(start(zmo)), as.Date(end(zmo), frac = 1), by = "day")zd <- na.approx(zmo, x = as.Date, xout = sq)head(zd)# weekly to daily serieszww <- zoo(1:3, as.Date("2001-01-01") + seq(0, length = 3, by = 7))zwwzdd <- na.approx(zww, xout = seq(start(zww), end(zww), by = "day"))zdd# The lines do not show up because of the NAsplot(cbind(z, z), type = "b", screen = 1)# use na.approx to force lines to appearplot(cbind(z, na.approx(z)), type = "b", screen = 1)# Workaround where less than 2 NAs can appear in a columnza <- zoo(cbind(1:5, NA, c(1:3, NA, 5), NA)); zaix <- colSums(!is.na(za)) > 0za[, ix] <- na.approx(za[, ix]); za# using na.approx to create regularly spaced series# z has points at 10, 20 and 40 minutes while output also has a point at 30if(require("chron")) { tt <- as.chron("2000-01-01 10:00:00") + c(1, 2, 4) * as.numeric(times("00:10:00")) z <- zoo(1:3, tt) tseq <- seq(start(z), end(z), by = times("00:10:00")) na.approx(z, xout = tseq)}Fill NA or specified positions.
Description
Generic function for fillingNA values or specified positions.
Usage
na.fill(object, fill, ...)## S3 method for class 'ts'na.fill(object, fill, ix, ...)## S3 method for class 'zoo'na.fill(object, fill, ix, ...)## Default S3 method:na.fill(object, fill, ix, ...)na.fill0(object, fill, ix = !is.na(object))Arguments
object | an object. |
fill | a three component list or a vector that is coerced to a list. Shorter objects are recycled. The three components represent the fill value to the left of the data, within theinterior of the data and to the right of the data,respectively. The value of any component may be the keyword |
ix | logical. Should be the same length as the number of time points.Indicates which time points not to fill. This defaults to the non-NA values. |
... | further arguments passed to methods. |
Details
na.fill is a generic function for fillingNA or indicated values.It currently has methods for the time series classes"zoo" and"ts"and a default method based on the"zoo" method.
Furthermore,na.fill0 works with plain vectors and"Date" objects.It also works with"zoo" objects provided that nofill component isNULL.
See Also
Examples
z <- zoo(c(NA, 2, NA, 1, 4, 5, 2, NA))na.fill(z, "extend")na.fill(z, c("extend", NA))na.fill(z, -(1:3))na.fill(z, list(NA, NULL, NA))Last Observation Carried Forward
Description
Generic function for replacing eachNA with the most recentnon-NA prior to it.
Usage
na.locf(object, na.rm = TRUE, ...)## Default S3 method:na.locf(object, na.rm = TRUE, fromLast, rev, maxgap = Inf, rule = 2, ...)na.locf0(object, fromLast = FALSE, maxgap = Inf, coredata = NULL)Arguments
object | an object. |
na.rm | logical. Should leading |
fromLast | logical. Causes observations to be carried backward ratherthan forward. Default is |
rev | Use |
maxgap | Runs of more than |
rule | See |
... | further arguments passed to methods. |
coredata | logical. Should LOCF be applied to the core dataof a (time series) object and then assigned to the original objectagain? By default, this strategy is applied to time series classes(e.g., |
Value
An object in which eachNA in the input object is replacedby the most recent non-NA prior to it. If there are no earlier non-NAs then theNA is omitted (ifna.rm = TRUE) or it is not replaced (ifna.rm = FALSE).
The argumentsx andxout can be used in which case they havethe same meaning as inapprox.
Note that if a multi-column zoo object has a column entirely composed ofNA then withna.rm = TRUE, the default,the above implies that the resulting object will havezero rows. Usena.rm = FALSE to preserve theNA values instead.
The functionna.locf0 is the workhorse function underlying the defaultna.locf method. It has more limited capabilities but is faster for thespecial cases it covers. Implicitly, it usesna.rm=FALSE.
See Also
Examples
az <- zoo(1:6)bz <- zoo(c(2,NA,1,4,5,2))na.locf(bz)na.locf(bz, fromLast = TRUE)cz <- zoo(c(NA,9,3,2,3,2))na.locf(cz)# generate and fill in missing datesz <- zoo(c(0.007306621, 0.007659046, 0.007681013,0.007817548, 0.007847579, 0.007867313),as.Date(c("1993-01-01", "1993-01-09", "1993-01-16","1993-01-23", "1993-01-30", "1993-02-06")))g <- seq(start(z), end(z), "day")na.locf(z, xout = g)# similar but use a 2 second gridz <- zoo(1:9, as.POSIXct(c("2010-01-04 09:30:02", "2010-01-04 09:30:06", "2010-01-04 09:30:07", "2010-01-04 09:30:08", "2010-01-04 09:30:09", "2010-01-04 09:30:10", "2010-01-04 09:30:11", "2010-01-04 09:30:13", "2010-01-04 09:30:14")))g <- seq(start(z), end(z), by = "2 sec")na.locf(z, xout = g)## get 5th of every month or most recent date prior to 5th if 5th missing.## Result has index of the date actually used.z <- zoo(c(1311.56, 1309.04, 1295.5, 1296.6, 1286.57, 1288.12, 1289.12, 1289.12, 1285.33, 1307.65, 1309.93, 1311.46, 1311.28, 1308.11, 1301.74, 1305.41, 1309.72, 1310.61, 1305.19, 1313.21, 1307.85, 1312.25, 1325.76), as.Date(c(13242, 13244, 13245, 13248, 13249, 13250, 13251, 13252, 13255, 13256, 13257, 13258, 13259, 13262, 13263, 13264, 13265, 13266, 13269, 13270, 13271, 13272, 13274)))# z.na is same as z but with missing days added (with NAs)# It is formed by merging z with a zero with series having all the dates.rng <- range(time(z))z.na <- merge(z, zoo(, seq(rng[1], rng[2], by = "day")))# use na.locf to bring values forward picking off 5th of monthna.locf(z.na)[as.POSIXlt(time(z.na))$mday == 5]## this is the same as the last one except instead of always using the## 5th of month in the result we show the date actually used# idx has NAs wherever z.na does but has 1, 2, 3, ... instead of# z.na's data values (so idx can be used for indexing)idx <- coredata(na.locf(seq_along(z.na) + (0 * z.na)))# pick off those elements of z.na that correspond to 5thz.na[idx[as.POSIXlt(time(z.na))$mday == 5]]## only fill single-day gapsmerge(z.na, filled1 = na.locf(z.na, maxgap = 1))## fill NAs in first column by inflating the most recent non-NA## by the growth in second column. Note that elements of x-x## are NA if the corresponding element of x is NA and zero elsem <- zoo(cbind(c(1, 2, NA, NA, 5, NA, NA), seq(7)^2), as.Date(1:7))r <- na.locf(m[,1]) * m[,2] / na.locf(m[,2] + (m[,1]-m[,1]))cbind(V1 = r, V2 = m[,2])## repeat a quarterly value every month## preserving NAszq <- zoo(c(1, NA, 3, 4), as.yearqtr(2000) + 0:3/4)tt <- as.yearmon(start(zq)) + seq(0, len = 3 * length(zq))/12na.locf(zq, xout = tt, maxgap = 0)## na.locf() can also be mimicked with ave()x <- c(NA, 10, NA, NA, 20, NA)f <- function(x) x[1]ave(x, cumsum(!is.na(x)), FUN = f)## by replacing f() with other functions various generalizations can be## obtained, e.g.,f <- function(x) if (length(x) > 3) x else x[1] # like maxgapf <- function(x) replace(x, 1:min(length(x)), 3) # replace up to 2 NAsf <- function(x) if (!is.na(x[1]) && x[1] > 0) x[1] else x # only positve numbersTrim Leading/Trailing Missing Observations
Description
Generic function for removing leading and trailingNAs.
Usage
na.trim(object, ...)## Default S3 method:na.trim(object, sides = c("both", "left", "right"), is.na = c("any", "all"), maxgap = Inf, ...)Arguments
object | an object. |
sides | character specifying whether |
is.na | If "any" then a row will be regarded as |
maxgap | maximum number of consecutive |
... | further arguments passed to methods. |
Value
An object in which leading and/or trailingNAs have been removed.
See Also
na.approx,na.contiguous,na.locf,na.omit,na.spline,stinterp,zoo
Examples
# examples of na.trimx <- zoo(c(1, 4, 6), c(2, 4, 6))xx <- zoo(matrix(c(1, 4, 6, NA, 5, 7), 3), c(2, 4, 6))na.trim(x)na.trim(xx)# using na.trim for alignment# cal defines the legal dates# all dates within the date range of x should be presentcal <- zoo(,c(1, 2, 3, 6, 7))x <- zoo(c(12, 16), c(2, 6))na.trim(merge(x, cal))Plotting zoo Objects
Description
Plotting method for objects of class"zoo".
Usage
## S3 method for class 'zoo'plot(x, y = NULL, screens, plot.type, panel = lines, xlab = "Index", ylab = NULL, main = NULL, xlim = NULL, ylim = NULL, xy.labels = FALSE, xy.lines = NULL, yax.flip = FALSE, oma = c(6, 0, 5, 0), mar = c(0, 5.1, 0, if(yax.flip) 5.1 else 2.1), col = 1, lty = 1, lwd = 1, pch = 1, type = "l", log = "", nc, widths = 1, heights = 1, ...)## S3 method for class 'zoo'lines(x, y = NULL, type = "l", ...)## S3 method for class 'zoo'points(x, y = NULL, type = "p", ...)Arguments
x | an object of class |
y | an object of class |
screens | factor (or coerced to factor) whose levels specify whichgraph each series is to be plotted in. |
plot.type | for multivariate zoo objects, "multiple" plots theseries on multiple plots and "single" superimposes them on a singleplot. Default is "single" if |
panel | a |
ylim | if |
xy.labels | logical, indicating if |
xy.lines | logical, indicating if |
yax.flip | logical, indicating if the y-axis (ticks and numbering)should flip from side 2 (left) to 4 (right) from series to serieswhen |
xlab,ylab,main,xlim,oma,mar | graphical arguments, see |
col,lty,lwd,pch,type | graphical arguments that can be vectors or (named) lists. See the details for more information. |
log | specification of log scales as |
nc | the number of columns to use when |
widths,heights | widths and heights for individual graphs, see |
... | additional graphical arguments. |
Details
The methods forplot andlines are very similarto the correspondingts methods. However, the handling ofseveral graphical parameters is more flexible for multivariate series.These parameters can be vectors of the same length as the number ofseries plotted or are recycled if shorter. They can also be (partially)named list, e.g.,list(A = c(1,2), c(3,4)) in whichc(3, 4)is the default value andc(1, 2) the value only for seriesA.Thescreens argument can be specified in a similar way.Ifplot.type andscreens conflict then multiple plotswill be assumed. Also see the examples.
In the case of a custom panel the panel can referenceparent.frame$panel.number in order to determine whichframe the panel is being called from. See examples.
par(mfrow=...) andAxis can be used in conjunction with single panel plots in the same way as with other classic graphics.
For multi-panel graphics,plot.zoo takes over the layout sopar(mfrow=...) cannot be used.Axis can be used withinthe panels themselves but not outside the panel. See examples.Also,par(new = TRUE) is not supported for multi-panel graphics.
In addition to classical time series line plots, there is also asimplebarplot method for"zoo" series. Additionally,there is aboxplot method that visualizes thecoredataof the"zoo" series with a box plot.
See Also
zoo,plot.ts,barplot,boxplot,xyplot.zoo
Examples
## example datesx.Date <- as.Date(paste(2003, 02, c(1, 3, 7, 9, 14), sep = "-"))## univariate plottingx <- zoo(rnorm(5), x.Date)x2 <- zoo(rnorm(5, sd = 0.2), x.Date)plot(x)lines(x2, col = 2)## multivariate plottingz <- cbind(x, x2, zoo(rnorm(5, sd = 0.5), x.Date))plot(z, type = "b", pch = 1:3, col = 1:3, ylab = list(expression(mu), "b", "c"))colnames(z) <- LETTERS[1:3]plot(z, screens = 1, col = list(B = 2))plot(z, type = "b", pch = 1:3, col = 1:3)plot(z, type = "b", pch = list(A = 1:5, B = 3), col = list(C = 4, 2))plot(z, type = "b", screen = c(1,2,1), col = 1:3)# right axis is for broken linesplot(x)opar <- par(usr = c(par("usr")[1:2], range(x2)))lines(x2, lty = 2)# axis(4)axis(side = 4)par(opar)## Custom x axis labelling using a custom panel.# 1. test dataz <- zoo(c(21, 34, 33, 41, 39, 38, 37, 28, 33, 40), as.Date(c("1992-01-10", "1992-01-17", "1992-01-24", "1992-01-31", "1992-02-07", "1992-02-14", "1992-02-21", "1992-02-28", "1992-03-06", "1992-03-13")))zz <- merge(a = z, b = z+10)# 2. axis tick for every point. Also every 3rd point labelled.my.panel <- function(x, y, ..., pf = parent.frame()) { fmt <- "%b-%d" # format for axis labels lines(x, y, ...) # if bottom panel if (with(pf, length(panel.number) == 0 || panel.number %% nr == 0 || panel.number == nser)) { # create ticks at x values and then label every third tick axis(side = 1, at = x, labels = FALSE) ix <- seq(1, length(x), 3) labs <- format(x, fmt) axis(side = 1, at = x[ix], labels = labs[ix], tcl = -0.7, cex.axis = 0.7) }}# 3. plotplot(zz, panel = my.panel, xaxt = "n")# with a single panel plot a fancy x-axis is just the same# procedure as for the ordinary plot commandplot(zz, screen = 1, col = 1:2, xaxt = "n")# axis(1, at = time(zz), labels = FALSE)tt <- time(zz)axis(side = 1, at = tt, labels = FALSE)ix <- seq(1, length(tt), 3)fmt <- "%b-%d" # format for axis labelslabs <- format(tt, fmt)# axis(1, at = time(zz)[ix], labels = labs[ix], tcl = -0.7, cex.axis = 0.7)axis(side = 1, at = tt[ix], labels = labs[ix], tcl = -0.7, cex.axis = 0.7)legend("bottomright", colnames(zz), lty = 1, col = 1:2)## plot a mulitple ts series with nice x-axis using panel functiontab <- ts(cbind(A = 1:24, B = 24:1), start = c(2006, 1), freq = 12)pnl.xaxis <- function(...) { lines(...) panel.number <- parent.frame()$panel.number nser <- parent.frame()$nser # if bottom panel if (!length(panel.number) || panel.number == nser) { tt <- list(...)[[1]] ym <- as.yearmon(tt) mon <- as.numeric(format(ym, "%m")) yy <- format(ym, "%y") mm <- substring(month.abb[mon], 1, 1) if (any(mon == 1)) # axis(1, tt[mon == 1], yy[mon == 1], cex.axis = 0.7) axis(side = 1, at = tt[mon == 1], labels = yy[mon == 1], cex.axis = 0.7) # axis(1, tt[mon > 1], mm[mon > 1], cex.axis = 0.5, tcl = -0.3) axis(side = 1, at = tt[mon > 1], labels = mm[mon > 1], cex.axis = 0.5, tcl = -0.3) }}plot(as.zoo(tab), panel = pnl.xaxis, xaxt = "n", main = "Fancy X Axis")## Another example with a custom axis# test dataz <- zoo(matrix(1:25, 5), c(10,11,20,21))colnames(z) <- letters[1:5]plot(zoo(coredata(z)), xaxt = "n", panel = function(x, y, ..., Time = time(z)) { lines(x, y, ...) # if bottom panel pf <- parent.frame() if (with(pf, panel.number %% nr == 0 || panel.number == nser)) { axis(side = 1, at = x, labels = Time) }})## plot with left and right axes## modified from http://www.mayin.org/ajayshah/KB/R/html/g6.htmlsuppressWarnings(RNGversion("3.5.0"))set.seed(1)z <- zoo(cbind(A = cumsum(rnorm(100)), B = cumsum(rnorm(100, mean = 0.2))))opar <- par(mai = c(.8, .8, .2, .8))plot(z[,1], type = "l", xlab = "x-axis label", ylab = colnames(z)[1])par(new = TRUE)plot(z[,2], type = "l", ann = FALSE, yaxt = "n", col = "blue")# axis(4)axis(side = 4)legend(x = "topleft", bty = "n", lty = c(1,1), col = c("black", "blue"), legend = paste(colnames(z), c("(left scale)", "(right scale)")))usr <- par("usr")# if you don't care about srt= in text then mtext is shorter:# mtext(colnames(z)[2], 4, 2, col = "blue")text(usr[2] + .1 * diff(usr[1:2]), mean(usr[3:4]), colnames(z)[2], srt = -90, xpd = TRUE, col = "blue")par(opar)## another plot with left and right axes## modified from https://stat.ethz.ch/pipermail/r-help/2014-May/375293.htmld1 <- c(38.2, 18.1, 83.2, 42.7, 22.8, 48.1, 81.8, 129.6, 52.0, 110.3)d2 <- c(2.2, 0.8, 0.7, 1.6, 0.9, 0.9, 1.1, 2.8, 5.1, 2.1)z1 <- zooreg(d1, start = as.POSIXct("2013-01-01 00:00:01"), frequency = 0.0000006)z2 <- zooreg(d2, start = as.POSIXct("2013-01-01 00:00:20"), frequency = 0.0000006)zt <- zooreg(rnorm(1050), start = as.POSIXct("2013-01-01 00:00:01"), frequency = 0.00007)z <- merge(zt, z1, z2, all = TRUE)z <- na.spline(z[,2:3], na.rm = FALSE)## function to round up to a number divisible by n (2011 by Owen Jones)roundup <- function(x, n) ceiling(ceiling(x)/n) * n## plot how to match secondary y-axis ticks to primary onesplot(z$z1, ylim = c(0, signif(max(na.omit(z$z1)), 2)), xlab = "")## use multiplication for even tick numbers and fake sekondary y-axismax.yl <- roundup(max(na.omit(z$z2)), par("yaxp")[3])multipl.yl <- max(na.omit(z$z2)) / max.ylmultipl.z2 <- signif(max(na.omit(z$z1) * 1.05), 2)/max.yllines(z$z2 * multipl.z2, lty = 2)at4 <- axTicks(4)axis(4, at = at4, seq(0, max.yl, length.out = par("yaxp")[3] + 1))# automatically placed point labels## Not run: library("maptools")pointLabel(time(z), coredata(z[,2]), labels = format(time(z)), cex = 0.5)## End(Not run)## plot one zoo series against the other.plot(x, x2)plot(x, x2, xy.labels = TRUE)plot(x, x2, xy.labels = 1:5, xy.lines = FALSE)## shade a portion of a plot and make axis fancierv <- zooreg(rnorm(50), start = as.yearmon(2004), freq = 12)plot(v, type = "n")u <- par("usr")rect(as.yearmon("2007-8"), u[3], as.yearmon("2009-11"), u[4], border = 0, col = "grey")lines(v)axis(1, floor(time(v)), labels = FALSE, tcl = -1)## shade certain times to show recessions, etc.v <- zooreg(rnorm(50), start = as.yearmon(2004), freq = 12)plot(v, type = "n")u <- par("usr")rect(as.yearmon("2007-8"), u[3], as.yearmon("2009-11"), u[4], border = 0, col = "grey")lines(v)axis(1, floor(time(v)), labels = FALSE, tcl = -1)## fill area under plotpnl.xyarea <- function(x, y, fill.base = 0, col = 1, ...) { lines(x, y, ...) panel.number <- parent.frame()$panel.number col <- rep(col, length = panel.number)[panel.number] polygon(c(x[1], x, tail(x, 1), x[1]), c(fill.base, as.numeric(y), fill.base, fill.base), col = col)}plot(zoo(EuStockMarkets), col = rainbow(4), panel = pnl.xyarea)## barplotx <- zoo(cbind(rpois(5, 2), rpois(5, 3)), x.Date)barplot(x, beside = TRUE)## boxplotboxplot(x)## 3d plot## The persp function in R (not part of zoo) works with zoo objects.## The following example is by Enrico Schumann.## https://stat.ethz.ch/pipermail/r-sig-finance/2009q1/003710.htmlnC <- 10 # columnsnO <- 100 # observationsdataM <- array(runif(nC * nO), dim=c(nO, nC))zz <- zoo(dataM, 1:nO)persp(1:nO, 1:nC, zz)# interactive plotting## Not run: library("TeachingDemos")tke.test1 <- list(Parameters = list(lwd = list("spinbox", init = 1, from = 0, to = 5, increment = 1, width = 5),lty = list("spinbox", init = 1, from = 0, to = 6, increment = 1, width = 5)))z <- zoo(rnorm(25))tkexamp(plot(z), tke.test1, plotloc = "top")## End(Not run)# setting ylim on a multi-panel plot - 2nd panel y axis range is 1-50data("anscombe", package = "datasets")ans6 <- zoo(anscombe[, 1:6])screens <- c(1, 1, 2, 2, 3, 3)ylim <- unname(tapply(as.list(ans6), screens, range))ylim[[2]] <- 1:50 # or ylim[[2]] <- c(1, 50)plot(ans6, screens = screens, ylim = ylim)Reading and Writing zoo Series
Description
read.zoo andwrite.zoo are convenience functions for readingand writing"zoo" series from/to text files. They are convenienceinterfaces toread.table andwrite.table, respectively.To employread.csv,read.csv2,read.delim,read.delim2 instead ofread.table additional functionsread.csv.zoo etc. are provided.
Usage
read.zoo(file, format = "", tz = "", FUN = NULL, regular = FALSE, index.column = 1, drop = TRUE, FUN2 = NULL, split = NULL, aggregate = FALSE, ..., text, read = read.table) write.zoo(x, file = "", index.name = "Index", row.names = FALSE, col.names = NULL, FUN = format, ...)read.csv.zoo(..., read = read.csv)read.csv2.zoo(..., read = read.csv2)read.delim.zoo(..., read = read.delim)read.delim2.zoo(..., read = read.delim2)Arguments
file | character string or strings giving the name of the file(s) which the dataare to be read from/written to. See |
format | date format argument passed to |
tz | time zone argument passed to |
FUN | a function for processing the time index. In |
regular | logical. Should the series be coerced to class |
index.column | numeric vector or list. The column names or numbers of the data frame in which the index/time is stored. If the |
drop | logical. If the data frame contains just a single data column, shouldthe second dimension be dropped? |
x | a |
index.name | character with name of the index column in the writtendata file. |
row.names | logical. Should row names be written? Default is |
col.names | logical. Should column names be written? Default is towrite column names only if |
FUN2 | function. It is applied to the time index after |
split | NULL or column number or name or vector of numbers or names. If not NULL then the data is assumed to be in long format and is split according to the indicated columns. See theR |
aggregate | logical or function. If set to |
... | further arguments passed to other functions. In the |
text | character. If |
read | function. The function for reading |
Details
read.zoo is a convenience function which should make it easierto read data from a text file and turn it into a"zoo" series immediately.read.zoo reads the data file viaread.table(file, ...).The columnindex.column (by default the first) of the resulting data isinterpreted to be the index/time, the remaining columns the corresponding data.(If the file only has only column then that is assumed to be the data column and1, 2, ... are used for the index.) To assign the appropriate classto the index,FUN can be specified and is applied to the first column.
To process the index,read.zoo callsFUN with the index as thefirst argument. IfFUN is not specified, the following default is employed:
(a) Iffile is a data frame with a singleindex column that appears to be a time index already, thenFUN = identity is used.The conditions for a readily produced time index are: It is notcharacter orfactor (and the argumentstz andformat must not be specified).
(b) If the conditions from (a) do not hold then the following strategy is used.If there are multiple index columns they are pasted together with a space between each.Using the (pasted) index column: (1) Iftz is specified then theindex column is converted toPOSIXct. (2) Ifformat is specifiedthen the index column is converted toDate. (3) Otherwise, a heuristicattempts to decide between"numeric","POSIXct", and"Date" bytrying them in that order (which may not always succeed though). By default,only the standard date/time format is used. Hence, supplyingformat and/ortzis necessary if some date/time format is used that is not the default. And evenif the default format is appropriate for the index, explicitly supplyingFUN or at leastformat and/ortz typically leads to morereliable results than the heuristic.
Ifregular is set toTRUE and the resulting series has an underlying regularity, it is coerced to a"zooreg" series.
To employ other functions thanread.table to read the initial data,further convenience interfacesread.csv.zoo etc. are provided.
write.zoo is a convenience function for writing"zoo" seriesto text files. It first coerces its argument to a"data.frame", addsa column with the index and then callswrite.table.
See alsovignette("zoo-read", package = "zoo") for detailed examples.
Value
read.zoo returns an object of class"zoo" (or"zooreg").
Note
read.zoo works by first reading the data in usingread.tableand then processing it. This implies that if the index field is entirely numeric the default is to pass it toFUNor the built-in date conversion routinea number, rather than a character string. Thus, a date field such as09122007 intendedto represent September 12, 2007 would be seen as9122007and interpreted as the 91st day thereby generating an error.
This comment also applies to trailing decimals so that if2000.10 were intended to represent the 10th month of 2000 in factit would receive2000.1 and regard it as the first month of 2000unless similar precautions were taken.
In the above cases the index field should be specified to be"character" so that leading or trailing zerosare not dropped. This can be done by specifying a"character"index column in the"colClasses" argument, which is passed toread.table, as shown in the examples below.
See Also
Examples
## this manual page provides a few typical examples, many more cases## are covered in vignette("zoo-read", package = "zoo")## read text lines with a single date columnLines <- "2013-12-24 22013-12-25 32013-12-26 8"read.zoo(text = Lines, FUN = as.Date) # explicit coercionread.zoo(text = Lines, format = "%Y-%m-%d") # sameread.zoo(text = Lines) # same, via heuristic## read text lines with date/time in separate columnsLines <- "2013-11-24 12:41:21 22013-12-25 12:41:22.25 32013-12-26 12:41:22.75 8"read.zoo(text = Lines, index = 1:2, FUN = paste, FUN2 = as.POSIXct) # explicit coercionread.zoo(text = Lines, index = 1:2, tz = "") # sameread.zoo(text = Lines, index = 1:2) # same, via heuristic## read text lines with month/year in separate columnsLines <- "Jan 1998 4.36Feb 1998 4.34"read.zoo(text = Lines, index = 1:2, FUN = paste, FUN2 = as.yearmon)## read directly from a data.frame (artificial and built-in BOD)dat <- data.frame(date = paste("2000-01-", 10:15, sep = ""), a = sin(1:6), b = cos(1:6))read.zoo(dat)data("BOD", package = "datasets")read.zoo(BOD)## Not run: ## descriptions of typical examples## turn *numeric* first column into yearmon index## where number is year + fraction of year represented by monthz <- read.zoo("foo.csv", sep = ",", FUN = as.yearmon)## first column is of form yyyy.mm## (Here we use format in place of as.character so that final zero ## is not dropped in dates like 2001.10 which as.character would do.)f <- function(x) as.yearmon(format(x, nsmall = 2), "%Y.%m")z <- read.zoo("foo.csv", header = TRUE, FUN = f)## turn *character* first column into "Date" index## Assume lines look like: 12/22/2007 1 2z <- read.zoo("foo.tab", format = "%m/%d/%Y")# Suppose lines look like: 09112007 1 2 and there is no headerz <- read.zoo("foo.txt", format = "%d%m%Y")## csv file with first column of form YYYY-mm-dd HH:MM:SS## Read in times as "chron" class. Requires chron 2.3-22 or later.z <- read.zoo("foo.csv", header = TRUE, sep = ",", FUN = as.chron)## same but with custom format. Note as.chron uses POSIXt-style ## Read in times as "chron" class. Requires chron 2.3-24 or later.z <- read.zoo("foo.csv", header = TRUE, sep = ",", FUN = as.chron, format = "## same file format but read it in times as "POSIXct" class.z <- read.zoo("foo.csv", header = TRUE, sep = ",", tz = "")## csv file with first column mm-dd-yyyy. Read times as "Date" class.z <- read.zoo("foo.csv", header = TRUE, sep = ",", format = "%m-%d-%Y")## whitespace separated file with first column of form YYYY-mm-ddTHH:MM:SS## and no headers. T appears literally. Requires chron 2.3-22 or later.z <- read.zoo("foo.csv", FUN = as.chron)# read in all csv files in the current directory and merge themread.zoo(Sys.glob("*.csv"), header = TRUE, sep = ",")# We use "NULL" in colClasses for those columns we don't need but in # col.names we still have to include dummy names for them. Of what # is left the index is the first three columns (1:3) which we convert # to chron class times in FUN and then truncate to 5 seconds in FUN2. # Finally we use aggregate = mean to average over the 5 second intervals.library("chron")Lines <- "CVX 20070201 9 30 51 73.25 81400 0CVX 20070201 9 30 51 73.25 100 0CVX 20070201 9 30 51 73.25 100 0CVX 20070201 9 30 51 73.25 300 0CVX 20070201 9 30 51 73.25 81400 0CVX 20070201 9 40 51 73.25 100 0CVX 20070201 9 40 52 73.25 100 0CVX 20070201 9 40 53 73.25 300 0"z <- read.zoo(text = Lines, colClasses = c("NULL", "NULL", "numeric", "numeric", "numeric", "numeric", "numeric", "NULL"), col.names = c("Symbol", "Date", "Hour", "Minute", "Second", "Price", "Volume", "junk"), index = 1:3, # do not count columns that are "NULL" in colClasses FUN = function(h, m, s) times(paste(h, m, s, sep = ":")), FUN2 = function(tt) trunc(tt, "00:00:05"), aggregate = mean)## End(Not run)Apply Rolling Functions
Description
A generic function for applying a function to rolling margins of an array.
Usage
rollapply(data, ...)## S3 method for class 'ts'rollapply(data, ...)## S3 method for class 'zoo'rollapply(data, width, FUN, ..., by = 1, by.column = TRUE, fill = if (na.pad) NA, na.pad = FALSE, partial = FALSE, align = c("center", "left", "right"), coredata = TRUE)## Default S3 method:rollapply(data, ...)rollapplyr(..., align = "right")Arguments
data | the data to be used (representing a series of observations). |
width | numeric vector or list. In the simplest case this is an integerspecifying the window width (in numbers of observations) which is alignedto the original sample according to the |
FUN | the function to be applied. |
... | optional arguments to |
by | calculate FUN at every |
by.column | logical. If |
fill | a three-component vector or list (recycled otherwise) providingfilling values at the left/within/to the right of the data range.See the |
na.pad | deprecated. Use |
partial | logical or numeric. If |
align | specifyies whether the index of the resultshould be left- or right-aligned or centered (default) comparedto the rolling window of observations. This argument is only used if |
coredata | logical. Should only the |
Details
Ifwidth is a plain numeric vector its elements are regarded as widthsto be interpreted in conjunction withalign whereas ifwidth is a listits components are regarded as offsets. In the above cases if the length ofwidth is 1 thenwidth is recycled for everyby-th point.Ifwidth is a list its components represent integer offsets such that the i-th component of the list refers to time points at positionsi + width[[i]]. If any of these points are below 1 or above the length ofindex(data) thenFUN is not evaluated for thatpoint unlesspartial = TRUE and in that case only the validpoints are passed.
The rolling function can also be applied to partial windows by settingpartial = TRUEFor example, ifwidth = 3, align = "right" then for the first pointjust that point is passed toFUN since the two points to itsleft are out of range. For the same example, ifpartial = FALSE thenFUN is notinvoked at all for the first two points. Ifpartial is a numeric then itspecifies the minimum number of offsets that must be within range. Negativepartial is interpreted asFALSE.
Ifwidth is a scalar thenpartial = TRUE andfill = NA aremutually exclusive but if offsets are specified for thewidth and 0 is notamong the offsets then the output will be shorter than the input evenifpartial = TRUE is specified. In that case it may still be usefulto specifyfill in addition topartial.
IfFUN ismean,max ormedian andby.column isTRUE and width is a plain scalar and there are no other argumentsthen special purpose code is used to enhance performance.Also in the case ofmean such special purpose code is only invoked if thedata argument has noNA values.Seerollmean,rollmax androllmedianfor more details.
Currently, there are methods for"zoo" and"ts" seriesand"default" method for ordinary vectors and matrices.
rollapplyr is a wrapper aroundrollapply that uses a defaultofalign = "right".
Ifdata is of length 0,data is returned unmodified.
Value
A object of the same class asdata with the results of the rolling function.
See Also
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)## rolling meanz <- zoo(11:15, as.Date(31:35))rollapply(z, 2, mean)## non-overlapping meansz2 <- zoo(rnorm(6))rollapply(z2, 3, mean, by = 3) # means of nonoverlapping groups of 3aggregate(z2, c(3,3,3,6,6,6), mean) # same## optimized vs. customized versionsrollapply(z2, 3, mean) # uses rollmean which is optimized for meanrollmean(z2, 3) # samerollapply(z2, 3, (mean)) # does not use rollmean## rolling regression:## set up multivariate zoo series with## number of UK driver deaths and lags 1 and 12seat <- as.zoo(log(UKDriverDeaths))time(seat) <- as.yearmon(time(seat))seat <- merge(y = seat, y1 = lag(seat, k = -1), y12 = lag(seat, k = -12), all = FALSE)## run a rolling regression with a 3-year time window## (similar to a SARIMA(1,0,0)(1,0,0)_12 fitted by OLS)rr <- rollapply(seat, width = 36, FUN = function(z) coef(lm(y ~ y1 + y12, data = as.data.frame(z))), by.column = FALSE, align = "right")## plot the changes in coefficients## showing the shifts after the oil crisis in Oct 1973## and after the seatbelt legislation change in Jan 1983plot(rr)## rolling mean by time window (e.g., 3 days) rather than## by number of observations (e.g., when these are unequally spaced):### - test datatt <- as.Date("2000-01-01") + c(1, 2, 5, 6, 7, 8, 10)z <- zoo(seq_along(tt), tt)## - fill it out to a daily series, zm, using NAs## using a zero width zoo series g on a gridg <- zoo(, seq(start(z), end(z), "day"))zm <- merge(z, g)## - 3-day rolling meanrollapply(zm, 3, mean, na.rm = TRUE, fill = NA)#### - without expansion to regular grid: find interval widths## that encompass the previous 3 days for each Datew <- seq_along(tt) - findInterval(tt - 3, tt)## a solution to computing the widths 'w' that is easier to read but slower## w <- sapply(tt, function(x) sum(tt >= x - 2 & tt <= x))#### - rolling sum from 3-day windows## without vs. with expansion to regular gridrollapplyr(z, w, sum)rollapplyr(zm, 3, sum, partial = TRUE, na.rm = TRUE)## rolling weekly sums (with some missing dates)z <- zoo(1:11, as.Date("2016-03-09") + c(0:7, 9:10, 12))weeksum <- function(z) sum(z[time(z) > max(time(z)) - 7])zs <- rollapplyr(z, 7, weeksum, fill = NA, coredata = FALSE)merge(value = z, weeksum = zs)## replicate cumsum with either 'partial' or vector width 'k'cumsum(1:10)rollapplyr(1:10, 10, sum, partial = TRUE)rollapplyr(1:10, 1:10, sum)## different values of rule argumentz <- zoo(c(NA, NA, 2, 3, 4, 5, NA))rollapply(z, 3, sum, na.rm = TRUE)rollapply(z, 3, sum, na.rm = TRUE, fill = NULL)rollapply(z, 3, sum, na.rm = TRUE, fill = NA)rollapply(z, 3, sum, na.rm = TRUE, partial = TRUE)# this will exclude time points 1 and 2# It corresponds to align = "right", width = 3rollapply(zoo(1:8), list(seq(-2, 0)), sum)# but this will include points 1 and 2rollapply(zoo(1:8), list(seq(-2, 0)), sum, partial = 1)rollapply(zoo(1:8), list(seq(-2, 0)), sum, partial = 0)# so will thisrollapply(zoo(1:8), list(seq(-2, 0)), sum, fill = NA)# by = 3, align = "right"L <- rep(list(NULL), 8)L[seq(3, 8, 3)] <- list(seq(-2, 0))str(L)rollapply(zoo(1:8), L, sum)rollapply(zoo(1:8), list(0:2), sum, fill = 1:3)rollapply(zoo(1:8), list(0:2), sum, fill = 3)L2 <- rep(list(-(2:0)), 10)L2[5] <- list(NULL)str(L2)rollapply(zoo(1:10), L2, sum, fill = "extend")rollapply(zoo(1:10), L2, sum, fill = list("extend", NULL))rollapply(zoo(1:10), L2, sum, fill = list("extend", NA))rollapply(zoo(1:10), L2, sum, fill = NA)rollapply(zoo(1:10), L2, sum, fill = 1:3)rollapply(zoo(1:10), L2, sum, partial = TRUE)rollapply(zoo(1:10), L2, sum, partial = TRUE, fill = 99)rollapply(zoo(1:10), list(-1), sum, partial = 0)rollapply(zoo(1:10), list(-1), sum, partial = TRUE)rollapply(zoo(cbind(a = 1:6, b = 11:16)), 3, rowSums, by.column = FALSE)# these two are the samerollapply(zoo(cbind(a = 1:6, b = 11:16)), 3, sum)rollapply(zoo(cbind(a = 1:6, b = 11:16)), 3, colSums, by.column = FALSE)# these two are the samerollapply(zoo(1:6), 2, sum, by = 2, align = "right")aggregate(zoo(1:6), c(2, 2, 4, 4, 6, 6), sum)# these two are the samerollapply(zoo(1:3), list(-1), c)lag(zoo(1:3), -1)# these two are the samerollapply(zoo(1:3), list(1), c)lag(zoo(1:3))# these two are the samerollapply(zoo(1:5), list(c(-1, 0, 1)), sum)rollapply(zoo(1:5), 3, sum)# these two are the samerollapply(zoo(1:5), list(0:2), sum)rollapply(zoo(1:5), 3, sum, align = "left")# these two are the samerollapply(zoo(1:5), list(-(2:0)), sum)rollapply(zoo(1:5), 3, sum, align = "right")# these two are the samerollapply(zoo(1:6), list(NULL, NULL, -(2:0)), sum)rollapply(zoo(1:6), 3, sum, by = 3, align = "right")# these two are the samerollapply(zoo(1:5), list(c(-1, 1)), sum)rollapply(zoo(1:5), 3, function(x) sum(x[-2]))# these two are the samerollapply(1:5, 3, rev)embed(1:5, 3)# these four are the samex <- 1:6rollapply(c(0, 0, x), 3, sum, align = "right") - xrollapply(x, 3, sum, partial = TRUE, align = "right") - xrollapply(x, 3, function(x) sum(x[-3]), partial = TRUE, align = "right")rollapply(x, list(-(2:1)), sum, partial = 0)# same as Matlab's buffer(x, n, p) for valid non-negative p# See http://www.mathworks.com/help/toolbox/signal/buffer.htmlx <- 1:30; n <- 7; p <- 3t(rollapply(c(rep(0, p), x, rep(0, n-p)), n, by = n-p, c))# these three are the samey <- 10 * seq(8); k <- 4; d <- 2# 1# from http://ucfagls.wordpress.com/2011/06/14/embedding-a-time-series-with-time-delay-in-r-part-ii/Embed <- function(x, m, d = 1, indices = FALSE, as.embed = TRUE) { n <- length(x) - (m-1)*d X <- seq_along(x) if(n <= 0) stop("Insufficient observations for the requested embedding") out <- matrix(rep(X[seq_len(n)], m), ncol = m) out[,-1] <- out[,-1, drop = FALSE] + rep(seq_len(m - 1) * d, each = nrow(out)) if(as.embed) out <- out[, rev(seq_len(ncol(out)))] if(!indices) out <- matrix(x[out], ncol = m) out}Embed(y, k, d)# 2rollapply(y, list(-d * seq(0, k-1)), c)# 3rollapply(y, d*k-1, function(x) x[d * seq(k-1, 0) + 1])## mimic convolve() using rollapplyr()A <- 1:4B <- 5:8## convolve(..., type = "open")cross <- function(x) x rollapplyr(c(A, 0*B[-1]), length(B), cross, partial = TRUE)convolve(A, B, type = "open")# convolve(..., type = "filter")rollapplyr(A, length(B), cross)convolve(A, B, type = "filter")# weighted sum including partials near ends, keeping## alignment with wts correctpoints <- zoo(cbind(lon = c(11.8300715, 11.8296697, 11.8268708, 11.8267236, 11.8249612, 11.8251062), lat = c(48.1099048, 48.10884, 48.1067431, 48.1066077, 48.1037673, 48.103318), dist = c(46.8463805878941, 33.4921440879536, 10.6101735030534, 18.6085009578724, 6.97253109610173, 9.8912817449265)))mysmooth <- function(z, wts = c(0.3, 0.4, 0.3)) { notna <- !is.na(z) sum(z[notna] * wts[notna]) / sum(wts[notna])}points2 <- pointspoints2[, 1:2] <- rollapply(rbind(NA, coredata(points)[, 1:2], NA), 3, mysmooth)points2Rolling Means/Maximums/Medians/Sums
Description
Generic functions for computing rolling means, maximums, medians, and sums of ordered observations.
Usage
rollmean(x, k, fill = if (na.pad) NA, na.pad = FALSE, align = c("center", "left", "right"), ...)rollmax(x, k, fill = if (na.pad) NA, na.pad = FALSE, align = c("center", "left", "right"), ...)rollmedian(x, k, fill = if (na.pad) NA, na.pad = FALSE, align = c("center", "left", "right"), ...)rollsum(x, k, fill = if (na.pad) NA, na.pad = FALSE, align = c("center", "left", "right"), ...)rollmeanr(..., align = "right")rollmaxr(..., align = "right")rollmedianr(..., align = "right")rollsumr(..., align = "right")Arguments
x | an object (representing a series of observations). |
k | integer width of the rolling window. Must be odd for |
fill | a three-component vector or list (recycled otherwise) providingfilling values at the left/within/to the right of the data range.See the |
na.pad | deprecated. Use |
align | character specifying whether the index of the resultshould be left- or right-aligned or centered (default) comparedto the rolling window of observations. |
... | Further arguments passed to methods. |
Details
These functions compute rolling means, maximums, medians, and sums respectivelyand are thus similar torollapply but areoptimized for speed.
Currently, there are methods for"zoo" and"ts" series anddefault methods. The default method ofrollmedianis an interface torunmed.The default methods ofrollmean androllsum do not handle inputs that containNAs. In such cases, userollapply instead.
Ifx is of length 0,x is returned unmodified.
Value
An object of the same class asx with the rolling mean/max/median/sum.
See Also
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)x.Date <- as.Date(paste(2004, rep(1:4, 4:1), sample(1:28, 10), sep = "-"))x <- zoo(rnorm(12), x.Date)## rolling operations for univariate seriesrollmean(x, 3)rollmax(x, 3)rollmedian(x, 3)rollsum(x, 3)## rolling operations for multivariate seriesxm <- zoo(matrix(1:12, 4, 3), x.Date[1:4])rollmean(xm, 3)rollmax(xm, 3)rollmedian(xm, 3)rollsum(xm, 3)## rollapply vs. dedicated rollmeanrollapply(xm, 3, mean) # uses rollmeanrollapply(xm, 3, function(x) mean(x)) # does not use rollmeanPlotting zoo Objects with tinyplot
Description
The approach is similar to that inautoplot.zoo(based on ggplot2) and usesfortify.zoo (withmelt = TRUE)to convert the zoo object into a data frame and then uses a suitableformula to visiualize the series.
Usage
## S3 method for class 'zoo'tinyplot(object, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...)Arguments
object | an object of class |
facet | specification of |
type,facet.args,ylab,... | further arguments passed to |
Details
Convenience interface for visualizing zoo objects with tinyplot.
See Also
Examples
if(require("tinyplot")) {suppressWarnings(RNGversion("3.5.0"))set.seed(1)## example datax.Date <- as.Date(paste(2003, 02, c(1, 3, 7, 9, 14), sep = "-"))x <- zoo(rnorm(5), x.Date)xlow <- x - runif(5)xhigh <- x + runif(5)z <- cbind(x, xlow, xhigh)## univariate plottingtinyplot(x)## multivariate plotting in multiple or single panelstinyplot(z) ## multiple without color/linetype with free scalestinyplot(z, facet.args = NULL) ## multiple without color/linetype with same scaletinyplot(z, facet = ~ Series) ## multiple with series-dependent color/linetypetinyplot(z, facet = NULL) ## single with series-dependent color/linetype## by hand with color/linetype and with/without facetsd <- fortify.zoo(z, melt = TRUE)tinyplot(Value ~ Index | Series, data = d, type = "l")tinyplot(Value ~ Index | Series, facet = "by", data = d, type = "l")tinyplot(Value ~ Index | Series, facet = "by", data = d, type = "l", facet.args = list(free = TRUE))## EuStockMarkets data (coerced from "ts")eusm <- as.zoo(EuStockMarkets)tinyplot(eusm)tinytheme("clean2")tinyplot(eusm, facet = NULL)tinyplot(eusm, facet = ~ Series)tinyplot(eusm, facet = ~ Series, facet.args = NULL)tinytheme() ## reset}Extract/Replacing the Time Windows of Objects
Description
Methods for extracting time windowsof"zoo" objects and replacing it.
Usage
## S3 method for class 'zoo'window(x, index. = index(x), start = NULL, end = NULL, ...)## S3 replacement method for class 'zoo'window(x, index. = index(x), start = NULL, end = NULL, ...) <- valueArguments
x | an object. |
index. | the index/time window which should be extracted. |
start | an index/time value. Only the indexes in |
end | an index/time value. Only the indexes in |
value | a suitable value object for use with |
... | currently not used. |
Value
Either the time window of the object is extracted (and hence return a"zoo"object) or it is replaced.
See Also
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)## zoo examplex.date <- as.Date(paste(2003, rep(1:4, 4:1), seq(1,19,2), sep = "-"))x <- zoo(matrix(rnorm(20), ncol = 2), x.date)xwindow(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[c(4, 8, 10)]) <- matrix(1:6, ncol = 2)x## for classes that support comparisons with "character" variables## start and end may be "character".window(x, start = "2003-02-01")## zooreg example (with plain numeric index)z <- zooreg(rnorm(10), start = 2000, freq = 4)window(z, start = 2001.75)window(z, start = c(2001, 4))## replace data at times of d0 which are in dnd1 <- d0 <- zoo(1:10) + 100dn <- - head(d0, 4)window(d1, time(dn)) <- coredata(dn)## if the underlying time index is a float, note that the index may## print in the same way but actually be different (e.g., differing## by 0.1 second in this example)zp <- zoo(1:4, as.POSIXct("2000-01-01 00:00:00") + c(-3600, 0, 0.1, 3600))## and then the >= start and <= end may not select all intended## observations and adding/subtracting some "fuzz" may be neededwindow(zp, end = "2000-01-01 00:00:00")window(zp, end = as.POSIXct("2000-01-01 00:00:00") + 0.5)Plot contiguous blocks along x axis.
Description
Plot contiguous blocks along x axis. A typical use would be tohighlight events or periods of missing data.
Usage
xblocks(x, ...)## Default S3 method:xblocks(x, y, ..., col = NULL, border = NA, ybottom = par("usr")[3], ytop = ybottom + height, height = diff(par("usr")[3:4]), last.step = median(diff(tail(x))))## S3 method for class 'zoo'xblocks(x, y = x, ...)## S3 method for class 'ts'xblocks(x, y = x, ...)Arguments
x,y | In the default method, If The |
... | In the default method, further arguments are graphical parameterspassed on to |
col | if |
border | border color. |
ybottom,ytop,height | y axis position of the blocks. The default it to fill the whole plotregion, but by setting these values one can draw blocks along thetop of bottom of the plot. Note that |
last.step | width (in native units) of the final block. Defaults to the median ofthe last 5 time steps (assuming steps are regular). |
Details
Blocks are drawn forward in "time" from the specified x locations,up until the following value. Contiguous blocks are calculated usingrle.
Author(s)
Felix Andrewsfelix@nfrac.org
See Also
Examples
## example time series:suppressWarnings(RNGversion("3.5.0"))set.seed(0)flow <- ts(filter(rlnorm(200, mean = 1), 0.8, method = "r"))## highlight values above and below thresholds.## this draws on top using semi-transparent colors.rgb <- hcl(c(0, 0, 260), c = c(100, 0, 100), l = c(50, 90, 50), alpha = 0.3)plot(flow)xblocks(flow > 30, col = rgb[1]) ## high values redxblocks(flow < 15, col = rgb[3]) ## low value bluexblocks(flow >= 15 & flow <= 30, col = rgb[2]) ## the rest gray## same thing:plot(flow)xblocks(time(flow), cut(flow, c(0,15,30,Inf), labels = rev(rgb)))## another approach is to plot blocks underneath without transparency.plot(flow)## note that 'ifelse' keeps its result as class 'ts'xblocks(ifelse(flow < mean(flow), hcl(0, 0, 90), hcl(0, 80, 70)))## need to redraw data series on top:lines(flow)box()## for single series only: plot.default has a panel.first argumentplot(time(flow), flow, type = "l", panel.first = xblocks(flow > 20, col = "lightgray"))## (see also the 'panel' argument for use with multiple series, below)## insert some missing valuesflow[c(1:10, 50:80, 100)] <- NA## the default plot shows data coverage## (most useful when displaying multiple series, see below)plot(flow)xblocks(flow)## can also show gaps:plot(flow, type = "s")xblocks(time(flow), is.na(flow), col = "gray")## Example of alternating colors, here showing calendar monthsflowdates <- as.Date("2000-01-01") + as.numeric(time(flow))flowz <- zoo(coredata(flow), flowdates)plot(flowz)xblocks(flowz, months, ## i.e. months(time(flowz)), col = gray.colors(2, start = 0.7), border = "slategray")lines(flowz)## Example of multiple series.## set up example dataz <- ts(cbind(A = 0:5, B = c(6:7, NA, NA, 10:11), C = c(NA, 13:17)))## show data coverage only (highlighting gaps)plot(z, panel = function(x, ...) xblocks(x, col = "darkgray"))## draw gaps in darkgrayplot(z, type = "s", panel = function(x, ...) { xblocks(time(x), is.na(x), col = "darkgray") lines(x, ...); points(x)})## Example of overlaying blocks from a different series.## Are US presidential approval ratings linked to sunspot activity?## Set block height to plot blocks along the bottom.plot(presidents)xblocks(sunspot.year > 50, height = 2)Plot zoo Series with Lattice
Description
xyplot methods for time series objects (of class"zoo","its", or"tis").
Usage
## S3 method for class 'zoo'xyplot(x, data, ...)## S3 method for class 'zoo'llines(x, y = NULL, ...)## S3 method for class 'zoo'lpoints(x, y = NULL, ...)## S3 method for class 'zoo'ltext(x, y = NULL, ...)panel.segments.zoo(x0, x1, ...)panel.rect.zoo(x0, x1, ...)panel.polygon.zoo(x, ...)Arguments
x,x0,x1 | time series object of class |
y | numeric vector or matrix. |
data | not used. |
... | arguments are passed to Some of the commonly used arguments are:
|
Details
xyplot.zoo plots a"zoo","its" or"tis"object usingxyplot.ts fromlattice. Series of other classes are coerced to"zoo"first.
The handling of several graphical parameters is moreflexible for multivariate series. These parameters can bevectors of the same length as the number of series plotted orare recycled if shorter. They can also be (partially) named list, e.g.,list(A = c(1,2), c(3,4)) in whichc(3, 4) is thedefault value andc(1, 2) the value only for seriesA.Thescreens argument can be specified in a similar way.
Note that sincezoo 1.6-3plot.panel.default andplot.panel.custom are no longer necessary, as normal panelfunctions (panel.xyplot by default) will work.
Similarly, there are now methods for the genericlattice drawingfunctionsllines,lpoints, andltext. These can also be called aspanel.lines,panel.points, andpanel.text,respectively. The old interfaces (panel.lines.zoo,panel.points.zoo, andpanel.text.zoo), will beremoved in future versions.panel.polygon.zoo may also beremoved.
Value
Invisibly returns a"trellis" class object. Printing thisobject usingprint will display it.
See Also
xyplot.ts,zoo,plot.ts,barplot,plot.zoo
Examples
if(require("lattice") & require("grid")) {suppressWarnings(RNGversion("3.5.0"))set.seed(1)z <- zoo(cbind(a = 1:5, b = 11:15, c = 21:25) + rnorm(5))# plot z using same Y axis on all plotsxyplot(z, scales = list(y = list(relation = "same", alternating = FALSE))) # plot a double-line-width running mean on the panel of b.# Also add a grid.# We show two ways to do it. # change strip background to levels of grey# If you like the defaults, this can be omitted.strip.background <- trellis.par.get("strip.background")trellis.par.set(strip.background = list(col = grey(7:1/8)))# Number 1. Using trellis.focus.print( xyplot(z) )trellis.focus("panel", 1, 2, highlight = FALSE)# (or just trellis.focus() for interactive use)z.mean <- rollmean(z, 3)panel.lines(z.mean[,2], lwd = 2)panel.grid(h = 10, v = 10, col = "grey", lty = 3)trellis.unfocus()# Number 2. Using a custom panel routine.xyplot(z, panel = function(x, y, ...) { if (packet.number() == 2) { panel.grid(h = 10, v = 10, col = "grey", lty = 3) panel.lines(rollmean(zoo(y, x), 3), lwd = 2) } panel.xyplot(x, y, ...)})# plot a light grey rectangle "behind" panel btrellis.focus("panel", 1, 2)grid.rect(x = 2, w = 1, default.units = "native", gp = gpar(fill = "light grey"))# do.call("panel.xyplot", trellis.panelArgs())do.call("panel.lines", trellis.panelArgs()[1:2])trellis.unfocus()# a better method is to use a custom panel function.# see also panel.xblocks() and layer() in the latticeExtra package.# same but make first panel twice as large as otherslopt <- list(layout.heights = list(panel = list(x = c(2,1,1))))xyplot(z, lattice.options = lopt)# add a gridupdate(trellis.last.object(), type = c("l", "g"))# Plot all in one panel.xyplot(z, screens = 1)# Same with default styles and auto.key:xyplot(z, superpose = TRUE)# Plot first two columns in first panel and third column in second panel.# Plot first series using points, second series using lines and third# series via overprinting both lines and points# Use colors 1, 2 and 3 for the three series (1=black, 2=red, 3=green)# Make 2nd (lower) panel 3x the height of the 1st (upper) panel# Also make the strip background orange.p <- xyplot(z, screens = c(1,1,2), type = c("p", "l", "o"), col = 1:3, par.settings = list(strip.background = list(col = "orange")))print(p, panel.height = list(y = c(1, 3), units = "null"))# Example of using a custom axis# Months are labelled with smaller ticks for weeks and even smaller# ticks for days.Days <- seq(from = as.Date("2006-1-1"), to = as.Date("2006-8-8"), by = "day")z1 <- zoo(seq(length(Days))^2, Days)Months <- Days[format(Days, "%d") == "01"]Weeks <- Days[format(Days, "%w") == "0"]print( xyplot(z1, scales = list(x = list(at = Months))) )trellis.focus("panel", 1, 1, clip.off = TRUE)panel.axis("bottom", check.overlap = TRUE, outside = TRUE, labels = FALSE, tck = .7, at = as.numeric(Weeks))panel.axis("bottom", check.overlap = TRUE, outside = TRUE, labels = FALSE, tck = .4, at = as.numeric(Days))trellis.unfocus()trellis.par.set(strip.background = strip.background)# separate the panels and suppress the ticks on very topxyplot(z, between = list(y = 1), scales = list(tck = c(1,0)))# left strips but no top stripsxyplot(z, screens = colnames(z), strip = FALSE, strip.left = TRUE)# plot list of zoo objects using different x scalesz.l <- list(zoo(cbind(a = rnorm(10), b = rnorm(10)), as.Date("2006-01-01") + 0:9),zoo(cbind(c = rnorm(10), d = rnorm(10)), as.Date("2006-12-01") + 0:9))zm <- do.call(merge, z.l)xlim <- lapply(zm, function(x) range(time(na.omit(x))))xyplot(zm, xlim = xlim, scale = list(relation = "free"))# to avoid merging see xyplot.list() in the latticeExtra package.}## Not run: ## playwith (>= 0.9)library("playwith")z3 <- zoo(cbind(a = rnorm(100), b = rnorm(100) + 1), as.Date(1:100))playwith(xyplot(z3), time.mode = TRUE)# hold down Shift key and drag to zoom in to a time period.# then use the horizontal scroll bar.# set custom labels; right click on points to view or add labelslabs <- paste(round(z3,1), index(z3), sep = "@")trellis.par.set(user.text = list(cex = 0.7))playwith(xyplot(z3, type = "o"), labels = labs)# this returns indexes into times of clicked points ids <- playGetIDs()z3[ids,]## another example of using playwith with zoo# set up datadat <- zoo(matrix(rnorm(100*100),ncol=100), Sys.Date()+1:100)colnames(dat) <- paste("Series", 1:100)# This will give you a spin button to choose the column to plot,# and a button to print out the current series number.playwith(xyplot(dat[,c(1,i)]), parameters = list(i = 1:100, do_something = function(playState) print(playState$env$i))## End(Not run)An Index Class for Monthly Data
Description
"yearmon" is a class for representing monthly data.
Usage
yearmon(x)Arguments
x | numeric (interpreted as being “in years”). |
Details
The"yearmon" class is used to represent monthly data. Internally it holdsthe data as year plus 0 for January, 1/12 for February, 2/12 for Marchand so on in order that its internal representation is the same asts class withfrequency = 12. Ifx is not in thisformat it is rounded viafloor(12*x + .0001)/12.
There are coercion methods available for various classes including:default coercion to"yearmon" (which coerces to"numeric" first)and coercions to and from"yearmon" to"Date" (see below),"POSIXct","POSIXlt","numeric","character" and"jul". The last one is from the"tis" package available on CRAN.In the case ofas.yearmon.POSIXt the conversion is with respect toGMT. (Useas.yearmon(format(...)) for other time zones.)In the case ofas.yearmon.character theformat argument uses the samepercent code as"Date". These are described instrptime. Unlike"Date" one can specify a year and month with no day. Default formats of"%Y-%m","%Y-%m-%d" and"%b %Y".
There is anis.numeric method which returnsFALSE.
as.Date.yearmon andas.yearmon.yearqtr each has an optionalsecond argument of"frac" which is a number between 0 and 1 inclusivethat indicates the fraction of the way through the period that the resultrepresents. The default is 0 which means the beginning of the period.
There is also adate method foras.yearmon usable with objectscreated with packagedate.
Sys.yearmon() returns the current year/month and methods formin,max andrange are defined (by defining a method forSummary).
Ayearmonmean method is also defined.
Value
Returns its argument converted to classyearmon.
See Also
Examples
Sys.setenv(TZ = "GMT")x <- as.yearmon(2000 + seq(0, 23)/12)xas.yearmon("mar07", "%b%y")as.yearmon("2007-03-01")as.yearmon("2007-12")# returned Date is the fraction of the way through# the period given by frac (= 0 by default)as.Date(x)as.Date(x, frac = 1)as.POSIXct(x)# given a Date, x, return the Date of the next Fridaynextfri <- function(x) 7 * ceiling(as.numeric(x - 1)/7) + as.Date(1)# given a Date, d, return the same Date in the following month# Note that as.Date.yearmon gives first Date of the month.d <- as.Date("2005-1-1") + seq(0,90,30)next.month <- function(d) as.Date(as.yearmon(d) + 1/12) + as.numeric(d - as.Date(as.yearmon(d)))next.month(d)# 3rd Friday in last month of the quarter of Date x## first day of last month of quartery <- as.Date(zoo::as.yearmon(zoo::as.yearqtr(x), frac = 1))## number of days to first Fridayn <- sapply(y, function(z) which(format(z + 0:6, "%w") == "5")) - 1## add number of days to third Fridayy + n + 14suppressWarnings(RNGversion("3.5.0"))set.seed(1)z <- zoo(rnorm(24), x, frequency = 12)zas.ts(z)## convert data fram to multivariate monthly "ts" series## 1.read raw dataLines.raw <- "ID Date Count123 20 May 1999 1123 21 May 1999 3222 1 Feb 2000 2222 3 Feb 2000 4"DF <- read.table(text = Lines.raw, skip = 1, col.names = c("ID", "d", "b", "Y", "Count"))## 2. fix raw dateDF$yearmon <- as.yearmon(paste(DF$b, DF$Y), "%b %Y")## 3. aggregate counts over months, convert to zoo and merge over IDsag <- function(DF) aggregate(zoo(DF$Count), DF$yearmon, sum)z <- do.call("merge.zoo", lapply(split(DF, DF$ID), ag))## 4. convert to "zooreg" and then to "ts"frequency(z) <- 12as.ts(z)xx <- zoo(seq_along(x), x)## aggregating over year as.year <- function(x) as.numeric(floor(as.yearmon(x)))aggregate(xx, as.year, mean)An Index Class for Quarterly Data
Description
"yearqtr" is a class for representing quarterly data.
Usage
yearqtr(x)as.yearqtr(x, ...)## S3 method for class 'character'as.yearqtr(x, format, ...)## S3 method for class 'yearqtr'format(x, format = "%Y Q%q", ...)Arguments
x | for |
format | character string specifying format. For coercing to |
... | arguments passed ot other methods. |
Details
The"yearqtr" class is used to represent quarterly data. Internally it holdsthe data as year plus 0 for Quarter 1, 1/4 for Quarter 2and so on in order that its internal representation is the same asts class withfrequency = 4. Ifx is not in thisformat it is rounded viafloor(4*x + .0001)/4.
as.yearqtr.character uses a default format of"%Y Q%q","%Y q%q" or"%Y-%q" according to whichever matches.%q accepts the numbers 1-4 (possibly with leading zeros). Due tothis%q does not match to single digits only and consequentlyformats such asas.yearqtr("Q12000", "Q%q%Y") are ambiguous anddo not work (i.e., result inNA).
There are coercion methods available for various classes including:default coercion to"yearqtr" (which coerces to"numeric" first)and coercion from"yearqtr" to"Date" (see below),"POSIXct","POSIXlt","numeric","character" and"jul". The last one is from theframe package on CRAN.
There is anis.numeric method which returnsFALSE.
There is also adate method foras.yearqtr usable with objectscreated with packagedate.
Sys.yearqtr() returns the current year/month and methods formin,max andrange are defined (by defining a method forSummary).
Ayearqtrmean method is also defined.
Certain methods support afrac argument. Seeyearmon.
Value
yearqtr andas.yearqtr return the first argument converted to classyearqtr.Theformat method returns a character string representation ofits argument first argument.
See Also
yearmon,zoo,zooreg,ts,strptime.
Examples
Sys.setenv(TZ = "GMT")x <- as.yearqtr(2000 + seq(0, 7)/4)xformat(x, "%Y Quarter %q")as.yearqtr("2001 Q2")as.yearqtr("2001 q2") # sameas.yearqtr("2001-2") # same# returned Date is the fraction of the way through# the period given by frac (= 0 by default)dd <- as.Date(x)format.yearqtr(dd)as.Date(x, frac = 1)as.POSIXct(x)suppressWarnings(RNGversion("3.5.0"))set.seed(1)zz <- zoo(rnorm(8), x, frequency = 4)zzas.ts(zz)Z's Ordered Observations
Description
zoo is the creator for an S3 class of indexedtotally ordered observations which includes irregulartime series.
Usage
zoo(x = NULL, order.by = index(x), frequency = NULL, calendar = getOption("zoo.calendar", TRUE))## S3 method for class 'zoo'print(x, style = , quote = FALSE, ...)Arguments
x | a numeric vector, matrix or a factor. |
order.by | an index vector with unique entries by which theobservations in |
frequency | numeric indicating frequency of |
calendar | logical. If |
style | a string specifying the printing style which can be |
quote | logical. Should characters be quoted? |
... | further arguments passed to the print methods ofthe data and the index. |
Details
zoo provides infrastructure for ordered observationswhich are stored internally in a vector or matrix with anindex attribute (of arbitrary class, see below). The indexmust have the same length asNROW(x) except in the case of a zero length numeric vector in which case the indexlength can be any length. Emphasis hasbeen given to make all methods independent of the index/time class(given inorder.by). In principle, the datax could alsobe arbitrary, but currently there is only support for vectors and matricesand partial support for factors.
zoo is particularly aimed at irregular time series of numericvectors/matrices, but it also supports regular time series (i.e.,series with a certainfrequency).zoo's key design goals are independence of a particularindex/date/time class and consistency withts and baseR by providing methods to standard generics. Therefore,standard functions can be used to work with"zoo" objects and memorization of new commands is reduced.
When creating a"zoo" object with the functionzoo,the vector of indexesorder.by can be of (a single) arbitrary class(ifx is shorter or longer thanorder.by it isexpanded accordingly),but it is essential thatORDER(order.by) works. For otherfunctions it is assumed thatc(),length(),MATCH() and subsetting[, work. If this is not the casefor a particular index/date/time class, then methods for these generic functions should be created by the user. Note, that to achieve this,new generic functionsORDER andMATCH are created inthezoo package with default methods corresponding tothe non-generic base functionsorder andmatch. Note that theorder and hence the defaultORDER typically work if there is axtfrm method. Furthermore, for certain (but not for all)operations the index class should have anas.numeric method (in particular for regular series) and anas.character method might improveprinted output (see also below).
The index observationsorder.by should typically be unique, such thatthe observations can be totally ordered. Nevertheless,zoo() is able to create"zoo" objects with duplicated indexes (with a warning) and simple methods such asplot()orsummary() will typically work for such objects. However, this isnot formally supported as the bulk of functionality provided inzoo requiresunique index observations/time stamps. See below for an example how to removeduplicated indexes.
If afrequency is specified when creating a series viazoo, theobject returned is actually of class"zooreg" which inherits from"zoo".This is a subclass of"zoo" which relies on having a"zoo" serieswith an additional"frequency" attribute (which has to comply with theindex of that series). Regular"zooreg" series can also be created byzooreg, thezoo analogue ofts. See the respective help page andis.regular for further details.
Methods to standard generics for"zoo" objects currentlyinclude:print (see above),summary,str,head,tail,[ (subsetting),rbind,cbind,merge(seemerge.zoo),aggregate (seeaggregate.zoo),rev,split (seeaggregate.zoo),barplot,plot andlines (seeplot.zoo). For multivariate"zoo" series with column names the$ extractor is available,behaving similar as for"data.frame" objects. Methods are alsoavailable formedian andquantile.
ifelse.zoo is not a method (becauseifelse is not a generic) but must be written out including the.zoo suffix.
To “prettify” printed output of"zoo" series the generic functionindex2char is used for turning index values into charactervalues. It defaults to usingas.character but can be customizedif a different printed display should be used (although this should notbe necessary, usually).
The subsetting method[ work essentially like thecorresponding functions for vectors or matrices respectively, i.e., takesindexes of type"numeric","integer" or"logical". Butadditionally, it can be used to index with observations from the index class ofthe series. If the index class of the series is one of the three classes above,the corresponding index has to be encapsulated inI() to enforce usage ofthe index class (see examples). Subscripting by a zoo object whosedata contains logical values is undefined.
Additionally,zoo provides several generic functions and methodsto work (a) on the data contained in a"zoo" object, (b) theindex (or time) attribute associated to it, and (c) on both data andindex:
(a) The data contained in"zoo" objects can be extracted bycoredata (strips off all"zoo"-specific attributes) and modifiedusingcoredata<-. Both are new generic functions with methods for"zoo" objects, seecoredata.
(b) The index associated with a"zoo" object can be extractedbyindex and modified byindex<-. As the interpretationof the index as “time” in time series applications is more natural,there are also synonymous methodstime andtime<-. Thestart and the end of the index/time vector can be queried bystart andend. Seeindex.
(c) To work on both data and index/time,zoo provides methodslag,diff (seelag.zoo) andwindow,window<- (seewindow.zoo).
In addition to standard group generic function (seeOps),the following mathematical operations are available as methods for"zoo" objects: transposet which coerces to a matrix first, andcumsum,cumprod,cummin,cummaxwhich are applied column wise.
Coercion to and from"zoo" objects is available for objects ofvarious classes, in particular"ts","irts" and"its"objects can be coerced to"zoo", the reverse is available for"its" and for"irts" (the latter in packagetseries).Furthermore,"zoo" objects can be coerced to vectors, matrices andlists and data frames (dropping the index/time attribute). Seeas.zoo.
Several methods are available forNA handling in the data of"zoo" objects:na.aggregate which uses group means to fill inNAvalues,na.approx which uses linear interpolation to fill inNA values.na.contiguous which extracts the longest consecutive stretch of non-missing values in a"zoo" object,na.fill which uses fixed specified values to replaceNAvalues,na.locf whichreplacesNAs by the last previous non-NA,na.omit which returns a"zoo"object with incomplete observations removed,na.spline which uses spline interpolation to fill inNA values andna.StructTS which uses a seasonal Kalman filter to fill inNA values,na.trim which trims runs ofNAs off the beginning andend but not in the interior. Yet anotherNA routine can be found inthestinepack package wherena.stinterpperforms Stineman interpolation.
A typical task to be performed on ordered observations is to evaluate somefunction, e.g., computing the mean, in a window of observations that is movedover the full sample period. The generic functionrollapplyprovides this functionality for arbitrary functions and more efficient versionsrollmean,rollmax,rollmedian areavailable for the mean, maximum and median respectively.
Thezoo package has anas.Datenumeric methodwhich is similar to the one in the core ofR except that theorigin argument defaults to January 1, 1970 (whereas the onein the core ofR has no default).
Note that sincezoo uses date/time classes from baseR and other packages, it may inherit bugs or problems with those date/time classes.Currently, there is one such known problem with thec method forthePOSIXct class in baseR:Ifx andy arePOSIXct objects withtzoneattributes, the attribute will always be dropped inc(x, y), evenif it is the same across bothx andy. Although this is documentedatc.POSIXct, one may want to employ a workaroundas shown athttps://stat.ethz.ch/pipermail/r-devel/2010-August/058112.html.
Value
A vector or matrix with an"index" attribute of the samedimension (NROW(x)) by whichx is ordered.
References
Achim Zeileis and Gabor Grothendieck (2005).zoo: S3 Infrastructure for Regular and Irregular Time Series.Journal of Statistical Software,14(6), 1-27.doi:10.18637/jss.v014.i06 and available asvignette("zoo").
Ajay Shah, Achim Zeileis and Gabor Grothendieck (2005).zoo Quick Reference.Package vignette available asvignette("zoo-quickref").
See Also
zooreg,plot.zoo,index,merge.zoo
Examples
suppressWarnings(RNGversion("3.5.0"))set.seed(1)## simple creation and plottingx.Date <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14) - 1x <- zoo(rnorm(5), x.Date)plot(x)time(x)## subsetting with numeric indexesx[c(2, 4)]## subsetting with index classx[as.Date("2003-02-01") + c(2, 8)]## different classes of indexes/times can be used, e.g. numeric vectorx <- zoo(rnorm(5), c(1, 3, 7, 9, 14))## subsetting with numeric indexes then uses observation numbersx[c(2, 4)]## subsetting with index class can be enforced by I()x[I(c(3, 9))]## visualizationplot(x)## or POSIXcty.POSIXct <- ISOdatetime(2003, 02, c(1, 3, 7, 9, 14), 0, 0, 0)y <- zoo(rnorm(5), y.POSIXct)plot(y)## create a constant seriesz <- zoo(1, seq(4)[-2])## create a 0-dimensional zoo seriesz0 <- zoo(, 1:4)## create a 2-dimensional zoo seriesz2 <- zoo(matrix(1:12, 4, 3), as.Date("2003-01-01") + 0:3)## create a factor zoo objectfz <- zoo(gl(2,5), as.Date("2004-01-01") + 0:9)## create a zoo series with 0 columnsz20 <- zoo(matrix(nrow = 4, ncol = 0), 1:4)## arithmetic on zoo objects intersects them firstx1 <- zoo(1:5, 1:5)x2 <- zoo(2:6, 2:6)10 * x1 + x2## $ extractor for multivariate zoo series with column namesz <- zoo(cbind(foo = rnorm(5), bar = rnorm(5)))z$fooz$xyz <- zoo(rnorm(3), 2:4)z## add comments to a zoo objectcomment(x1) <- c("This is a very simple example of a zoo object.", "It can be recreated using this R code: example(zoo)")## comments are not output by default but are still therex1comment(x1)# ifelse does not work with zoo but this works# to create a zoo object which equals x1 at# time i if x1[i] > x1[i-1] and 0 otherwise(diff(x1) > 0) * x1## zoo series with duplicated indexesz3 <- zoo(1:8, c(1, 2, 2, 2, 3, 4, 5, 5))plot(z3)## remove duplicated indexes by averaginglines(aggregate(z3, index(z3), mean), col = 2)## or by using the last observationlines(aggregate(z3, index(z3), tail, 1), col = 4)## x1[x1 > 3] is not officially supported since## x1 > 3 is of class "zoo", not "logical".## Use one of these instead:x1[which(x1 > 3)]x1[coredata(x1 > 3)]x1[as.logical(x1 > 3)]subset(x1, x1 > 3)## any class supporting the methods discussed can be used## as an index class. Here are examples using complex numbers## and letters as the time class.z4 <- zoo(11:15, complex(real = c(1, 3, 4, 5, 6), imag = c(0, 1, 0, 0, 1)))merge(z4, lag(z4))z5 <- zoo(11:15, letters[1:5])merge(z5, lag(z5))# index values relative to 2001Q1zz <- zooreg(cbind(a = 1:10, b = 11:20), start = as.yearqtr(2000), freq = 4)zz[] <- mapply("/", as.data.frame(zz), coredata(zz[as.yearqtr("2001Q1")]))## even though time index must be unique zoo (and read.zoo)## will both allow creation of such illegal objects with## a warning (rather than ana error) to give the user a ## chance to fix them up. Extracting and replacing times## and aggregate.zoo will still work.## Not run: # this gives a warning# and then creates an illegal zoo objectz6 <- zoo(11:15, c(1, 1, 2, 2, 5))z6# fix it up by averaging duplicatesaggregate(z6, identity, mean)# or, fix it up by taking last in each set of duplicatesaggregate(z6, identity, tail, 1)# fix it up via interpolation of duplicate timestime(z6) <- na.approx(ifelse(duplicated(time(z6)), NA, time(z6)), na.rm = FALSE)# if there is a run of equal times at end they# wind up as NAs and we cannot have NA timesz6 <- z6[!is.na(time(z6))]z6x1. <- x1 <- zoo (matrix (1:12, nrow = 3), as.Date("2008-08-01") + 0:2)colnames (x1) <- c ("A", "B", "C", "D")x2 <- zoo (matrix (1:12, nrow = 3), as.Date("2008-08-01") + 1:3)colnames (x2) <- c ("B", "C", "D", "E")both.dates = as.Date (intersect (index (t1), index (t2)))both.cols = intersect (colnames (t1), colnames (t2))x1[both.dates, both.cols]## there is "[.zoo" but no "[<-.zoo" however four of the following## five examples work## wrong## x1[both.dates, both.cols] <- x2[both.dates, both.cols]# 4 correct alternatives# #1window(x1, both.dates)[, both.cols] <- x2[both.dates, both.cols]# #2. restore x1 and show a different wayx1 <- x1.window(x1, both.dates)[, both.cols] <- window(x2, both.dates)[, both.cols]# #3. restore x1 and show a different wayx1 <- x1.x1[time(x1) # #4. restore x1 and show a different wayx1 <- x1.x1[time(x1) ## End(Not run)Regular zoo Series
Description
zooreg is the creator for the S3 class"zooreg"for regular"zoo" series. It inherits from"zoo"and is the analogue tots.
Usage
zooreg(data, start = 1, end = numeric(), frequency = 1, deltat = 1, ts.eps = getOption("ts.eps"), order.by = NULL, calendar = getOption("zoo.calendar", TRUE))Arguments
data | a numeric vector, matrix or a factor. |
start | the time of the first observation. Either a single number ora vector of two integers, which specify a natural time unitand a (1-based) number of samples into the time unit. |
end | the time of the last observation, specified in the same wayas |
frequency | the number of observations per unit of time. |
deltat | the fraction of the sampling period between successiveobservations; e.g., 1/12 for monthly data. Only one of |
ts.eps | time series comparison tolerance. Frequencies are consideredequal if their absolute difference is less than |
order.by | a vector by which the observations in |
calendar | logical. Should |
Details
Strictly regular series are those whose time points are equally spaced.Weakly regular series are strictly regular time series in which someof the points may have been removed but still have the originalunderlying frequency associated with them."zooreg" is a subclass of"zoo" that is used to represent both weaklyand strictly regular series. Internally, it is the same as"zoo" except it also has a"frequency" attribute. Its index class is more restricted than"zoo". The index: 1. must be numeric or a class which can be coercedviaas.numeric (such asyearmon,yearqtr,Date,POSIXct,tis,xts, etc.). 2. when converted to numericmust be expressible as multiples of 1/frequency. 3.group generic functionsOps should be defined, i.e.,adding/subtracting a numeric to/from the index class should produce the correctvalue of the index class again.
zooreg is thezoo analogue tots. The argumentsare almost identical, only in the case whereorder.by is specified,zoo is called withzoo(data, order.by, frequency). Itcreates a regular series of class"zooreg" which inherits from"zoo".It is essentially a"zoo" series with an additional"frequency"attribute. In the creation of"zooreg" objects (viazoo,zooreg, or coercion functions) it is always check whether theindex specified complies with the frequency specified.
The class"zooreg" offers two advantages over code"ts": 1. Theindex does not have to be plain numeric (although that is the default), it justmust be coercible to numeric, thus printing and plotting can be customized.2. This class can not only represent strictly regular series, but also serieswith an underlying regularity, i.e., where some observations from a regular gridare omitted.
Hence,"zooreg" is a bridge between"ts" and"zoo" andcan be employed to coerce back and forth between the two classes. The coercionfunctionas.zoo.ts returns therefore an object of class"zooreg"inheriting from"zoo". Coercion between"zooreg" and"zoo"is also available and drops or tries to add a frequency respectively.
For checking whether a series is strictly regular or does have an underlyingregularity the generic functionis.regular can be used.
Methods to standard generics for regular series such asfrequency,deltat andcycle are available for both"zooreg"and"zoo" objects. In the latter case, it is checked first (in a data-driven way)whether the series is in fact regular or not.
as.zooreg.tis has aclass argument whose value represents theclass of the index of thezooreg object into which thetisobject is converted. The default value is"ti". Note that the frequency of thezooreg object will not necessarily be the sameas the frequency of thetis object that it is converted from.
Value
An object of class"zooreg" which inherits from"zoo".It is essentially a"zoo" series with a"frequency"attribute.
See Also
Examples
## equivalent specifications of a quarterly series## starting in the second quarter of 1959.zooreg(1:10, frequency = 4, start = c(1959, 2))as.zoo(ts(1:10, frequency = 4, start = c(1959, 2)))zoo(1:10, seq(1959.25, 1961.5, by = 0.25), frequency = 4)## use yearqtr class for indexing the same seriesz <- zoo(1:10, yearqtr(seq(1959.25, 1961.5, by = 0.25)), frequency = 4)zz[-(3:4)]## create a regular series with a "Date" indexzooreg(1:5, start = as.Date("2000-01-01"))## or with "yearmon" indexzooreg(1:5, end = yearmon(2000))## lag and diff (as diff is defined in terms of lag)## act differently on zoo and zooreg objects!## lag.zoo moves a point to the adjacent time whereas## lag.zooreg moves a point by deltatx <- c(1, 2, 3, 6)zz <- zoo(x, x)zr <- as.zooreg(zz)lag(zz, k = -1)lag(zr, k = -1)diff(zz)diff(zr)## lag.zooreg wihtout and with na.padlag(zr, k = -1)lag(zr, k = -1, na.pad = TRUE)## standard methods available for regular seriesfrequency(z)deltat(z)cycle(z)cycle(z[-(3:4)])zz <- zoo(1:6, as.Date(c("1960-01-29", "1960-02-29", "1960-03-31", "1960-04-29", "1960-05-31", "1960-06-30")))# this converts zz to "zooreg" and then to "ts" expanding it to a daily# series which is 154 elements long, most with NAs.## Not run: length(as.ts(zz)) # 154## End(Not run)# probably a monthly "ts" series rather than a daily one was wanted.# This variation of the last line gives a result only 6 elements long.length(as.ts(aggregate(zz, as.yearmon, c))) # 6zzr <- as.zooreg(zz)dd <- as.Date(c("2000-01-01", "2000-02-01", "2000-03-01", "2000-04-01"))zrd <- as.zooreg(zoo(1:4, dd))