xts_0.12.2 on CRAN

An updated version of xts is now on CRAN. This release is a big one, with lots of changes. Plotting functionality got a lot of attention. Another notable change is that merge.xts() now supports suffixes. Plus the obligatory bug fixes and refinements to make xts more robust.

Plotting functionality enhancements and bug fixes

  • You can now omit the data time range from the upper-right portion of a plot by setting main.timespan = FALSE. (#247)

  • plot.xts() gained a yaxis.ticks argument to control the number of y-axis grid lines, instead of always drawing 5 y-axes grid lines. Thanks to Fredrik Wartenberg for the feature request and patch! (#374)

  • Fixed addEventLines() when plotted objects have a ‘yearmon’ index. The ISO-8601 range string was not created correctly. Thanks to @paessens for the report. (#353)

  • The ‘ylim’ argument is now robust against numerical precision issues. Thanks to @bollard for the report, PR, and a ton of help debugging intermediate solutions! (#368)

  • Series added to a panel now extend the panel’s y-axis. Previously the y-axis limits were based on the first series' values and not updated when new series were added. So values of the new series did not appear on the plot if they were outside of the original series' min/max. Thanks to Vitalie Spinu for the report and help debugging and testing! (#360)

  • All series added to any panel of a plot now update the x-axis of all panels. So the entire plot’s x-axis will include every series' time index values within the original plot’s time range. This behavior is consistent with chart_Series(). Thanks to Vitalie Spinu for the report and help debugging and testing! (#360, #216)

  • All y-values are now plotted for series that have duplicate index values, but different data values. Thanks to Vitalie Spinu for the report and help debugging and testing! (#360)

  • Adding a series can now extend the x-axis before/after the plot’s existing time index range by setting extend.xaxis = TRUE. That ensures all of the new series' time index values are included in the plot. extend.xaxis = FALSE by default to maintain backward compatibility. Thanks to Vitalie Spinu for the report and help debugging and testing! (#360)

Other enhancements and bug fixes

  • Ops.xts() no longer changes column names (via make.names()) when the two objects do not have identical indexes. This makes it consistent with Ops.zoo(). Thanks to Anton Antonov for the report! (#114)

  • Subsetting a zero-length xts object now returns an object with the same storage type as the input. It previously always returned a ‘logical’ xts object. (#376)

  • tclass() and tzone() now return the correct values for zero-length xts objects, instead of the defaults from the .xts() constructor. Thanks to Andre Mikulec for the report and suggested patch! (#255)

  • first() and last() now return a zero-length xts object when n = 0. They previously returned the entire object. This is consistent with the default head() and tail() functions, and data.table’s first() and last() functions. Thanks to Ethan B. Smith for the report and patch! (#350)

  • Subsetting a zero-width xts now returns an object with the same class, tclass, tzone, and xtsAttributes as the input. Thanks to @shikokuchuo for the report! (#359)

  • Now endpoints() always returns last observation. Thanks to GitHub user Eluvias for the report. (#300)

  • Now endpoints() errors for every on value when k < 1. It was not throwing an error for k < 1 for on of “years”, “quarters”, or “months”. Thanks to Eluviasfor the report. (#301)

  • Fixed a breaking change (introduced in 0.11.0) in window() for yearmon and yearqtr indexes. In xts < 0.11.0, window.zoo() was dispatched when window() was called on a xts object because there was no window.xts() method. window.zoo() supports additional types of values for the start argument, and possibly other features. Thanks to @annaymj for the report. (#312)

  • Clarified documentation for axTicksByTime() to say that returns index locations (e.g. 1, 2, 3) and not timestamps. Thanks to Gabor Grothendieck for the suggestion and feedback. (#354)

  • Fixed merge.xts() on xts objects containing complex types when fill is provided. It previously threw an error because it treated fill as double instead of complex. Thanks to Gabor Grothendieck for the report. (#346)

  • Added a message to tell the user how to disable the “object timezone is different from the system timezone” warning (set options(xts_check_TZ = FALSE)). Thanks to Jerzy Pawlowski for the nudge. (#113)

  • rbind() now handles xts objects without dim attribute. It previously threw an obscure error if one of the xts objects did not have a dim attribute. (#361)

  • split.xts() now always return a named list, making it consistent with split.zoo(). Thanks to Gabor Grothendieck for the report. (#357)

  • xts objects with a zero-length POSIXct index now have a zero-length POSIXct vector instead of a zero-length integer vector for the index. Thanks to Jasper Schelfhout for the report and PR! (#363, #364)

  • Add supported for suffixes in merge.xts() results. The suffixes are consistent with merge.default() and not merge.zoo(), because merge.zoo() automatically uses “.” as a separator between column names, but the default method doesn’t. Thanks to Alex Chernyakov for the initial report, QiuxiaoMu for testing, and Pierre Lamarche for the nudge. Better late than never? (#38, #371)


You may have noticed that several of these issues have been open a long time. I’ve been revisiting historical issues and deciding whether to implement them or close them. I’ve already implemented some cool ones in the development version of xts.

I’m most excited about open-ended time-of-day subsetting. Now you can do things like:

x["/T1700"]  # start of the day until 5pm
x["T0500/"]  # 5am until the end of the day

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, xts, IBrokers, microbenchmark, etc.), you can give back by sponsoring me on GitHub. I truly appreciate anything you’re willing and able to give!