xts
xts copied to clipboard
zero-length versus zero-width
It's quite common to create a zero-width xts object for aligning series or making irregular series regular. A zero-width xts object has an index, but no data.
# zero-width xts object
R> xts(, as.Date("2017-01-01") + 0:9)
Data:
numeric(0)
Index:
Date[1:11], format: "2017-01-01" "2017-01-02" "2017-01-03" "2017-01-04" ...
R> str(xts(, as.Date("2017-01-01") + 0:9))
An 'xts' object of zero-width
But you can also create a "zero-length" xts object by subsetting outside the bounds of the index. For example:
R> x <- xts(1:10, as.Date("2017-01-01") + 0:9)
R> x["1900"]
[,1]
R> str(x["1900"])
An 'xts' object of zero-width
R> unclass(x["1900"])
[,1]
attr(,".indexCLASS")
[1] "Date"
attr(,"tclass")
[1] "Date"
attr(,".indexTZ")
[1] "UTC"
attr(,"tzone")
[1] "UTC"
attr(,"index")
numeric(0)
attr(,"index")attr(,"tzone")
[1] "UTC"
attr(,"index")attr(,"tclass")
[1] "Date"
R> dim(x["1900"])
[1] 0 1
Note that str(x["1900"]) returns "An 'xts' object of zero-width", which isn't true. As you can see from dim(x["1900"]), the "width" is 1 but there are no rows. So I would call x["1900"] a "zero-length xts object". It's not clear to me if/how these should be supported by other functions (e.g. merge), but at minimum str shouldn't say they're zero-width xts objects.
I think that zero-row/length objects are useful when you want to model available observations in a given time frame and no observations are available for some securities. Apart from this, one could rule out them, like a division-by-zero error, but since they are currently legal objects, merge.xts should support them. Also because, given a zero-length x, it seems quite natural to set to NA x column(s) in merge(x,y, all=TRUE) and to output another zero-length xts, from merge(x,y, all=FALSE)
Another function that should be fixed for zero objects is names():
e <- xts(data.frame(p=numeric()), as.Date(character()))
names(e)
# NULL
The result should be "p".
Also, off topic a bit, but speaking of names:
(x <- xts(data.frame(p=1), as.Date(1)))
# p
# 1970-01-02 1
(y <- xts(c(p=1), as.Date(1)))
# [,1]
# 1970-01-02 1
could/should both name the column p.
Thanks for the feedback, @steven001.
There is no names.xts() method, so the names.zoo() method is being called. And it looks like xts behaves the same as zoo in this case.
require(xts)
x1 <- .xts(data.frame(a=1, b=1), 1)
z1 <- as.zoo(x1)
x0 <- .xts(data.frame(a=numeric(), b=numeric()), numeric())
z0 <- as.zoo(x0)
names(x1) # [1] "a" "b"
names(z1) # [1] "a" "b"
names(x0) # NULL
names(z0) # NULL
In your second example, c(p=1) is a named vector; and vectors are column-wise in R, so the names would be row names. That means your y object should not have column names.