xts_0.12.1 on CRAN

This is a long-overdue post. I’m trying to get int the habit of posting and announcing each of my package releases. So I’m writing posts this morning for the most recent release of the most popular packages I maintain.

I released an updated version of xts to CRAN on 2020-09-09. I’m also going to include some notes from the prior release (0.12-0), since I didn’t post about that. It has some nifty changes in it too.

I’m going to highlight a handful of the changes:

  1. moving index class and index timezone from the xts object itself to the index,
  2. improvements to time-of-day subsetting (x["T10:00/T13:00"])
  3. user contributions, and
  4. several bug fixes.

Changes to index attributes

The most significant user-facing change in this release is a bug-fix for the functions that would change the tclass of the xts index. This would happen in calls to reclass(), period.apply(), and logical operations on POSIXct indexes. Thanks to Tom Andrews for the report and testing, and to Panagiotis Cheilaris for contributing test cases (#322, #323).

This was a regression due to the main change in version 0.12-0. All the index-attributes were removed from the xts object and are now only attached to the index itself (#245). We took great care to maintain backward compatibility, and throw warnings when deprecated functions are called and when index-attributes are found on the xts object. I apologize for taking this long to get the fix on CRAN.

Time-of-day subsetting

Another change in 0.12-0 is a significant (~200x!) performance improvement to time-of-day subsetting, thanks to StackOverflow user3226167 (#193).

Then Claymore Marshall added many examples of time-of-day subsetting to ?subset.xts. He also fixed a bug in time-of-day subsetting where subsetting by hour only returned wrong results (#304, #326, #328).

User contributions

There were also several more user-contributed changes. I love when the community that uses open source software contributes to the project! It’s so much more fun than working on it by myself. :)

These are in a bulleted list in order to highlight each user’s contribution.

  • Jasen Macike updated plot.xts() to support y-axis labels via the ylab argument (#333, #334).

  • Michael Chirico added an internal isUTC() function that recognizes many UTC-equivalent time zones (#319).

  • Dirk Eddelbuettel updated the C API header to fix the signatures of do_merge_xts() and is_xts, which did not return the required type to be called via .Call(). Thanks to Tomas Kalibera for the report (#317), and to Dirk for the PR (#337).
    This is a breaking change, but it’s only in the C API, and is required to avoid the potential to crash your R session.

  • Harvey Smith fixed the possible values for the major.ticks, minor.ticks, and grid.ticks.on arguments to plot.xts() in the Details section of the documentation (#291).

  • Performance for the period.XYZ() functions (sum, prod, min, max) is much faster (#278). Thanks to Chris Katsulis for the report, and Harvey Smith for several examples.

Bug fixes

first() now operates correctly on non-xts objects when n = -1. Previously it would always return the last two values. Thanks to GitHub user vxg20 for the report (#325).

The .xts() constructor would create an xts object with row names if x had row names. This shouldn’t happen, because xts objects do not have or support row names (#298).

Several binary operations (e.g. +, -, !=, <, etc.) on variations of uncommon xts objects with other xts, matrix, or vector objects, could result in malformed xts objects (#295). Some examples of the types of uncommon xts objects: no dim attribute, zero-width, zero-length.

Calling as.matrix() on an xts object without a dim attribute no longer throws an error (#294).

merge.xts() now honors check.names = FALSE (#293). It also creates shorter column names when passed unnamed objects, consistent with zoo (#248).

as.zoo.xts() is now only registered for zoo versions prior to 1.8-5. Methods to convert an object to another class should reside in the package that implements the target class. Thanks to Kurt Hornik for the report (#287).

.parseISO8601() no longer has a potential length-1 logical error. Thanks to Kurt Hornik for the report (#280).

endpoints() now honors k > 0 when on = "quarters". Thanks to @alkment for the report (#279).


I’m looking forward to your questions and feedback! If you have a question, please ask on Stack Overflow and use the [r] and [xts] tags.  Or you can send an email to the R-SIG-Finance mailing list (you must subscribe to post). Open an issue on GitHub if you find a bug or want to request a feature, but please read the contributing guide first!


If you love using my open-source work (e.g. quantmod, TTR, IBrokers, microbenchmark etc.), you can give back by sponsoring me on GitHub. I truly appreciate anything you’re willing and able to give!