为什么单行 xts 对象得不到时区? (为什么它 ignore/override 默认参数)
Why does one-row xts object not get a timezone? (why does it ignore/override the default argument)
对单元测试的抱怨感到沮丧,我将范围缩小到一个 xts
对象的时区设置为 "UTC",另一个对象的时区设置为“”。
然后我进一步缩小范围,似乎是在创建一个只有一行的 xts 对象,而不是 2+ 行:
> str(xts( c(1,2), as.POSIXct("2015-01-01 00:00:00")+0:1))
An ‘xts’ object on 2015-01-01/2015-01-01 00:00:01 containing:
Data: num [1:2, 1] 1 2
Indexed by objects of class: [POSIXct,POSIXt] TZ: UTC
xts Attributes:
NULL
> str(xts( c(1), as.POSIXct("2015-01-01 00:00:01")))
An ‘xts’ object on 2015-01-01 00:00:01/2015-01-01 00:00:01 containing:
Data: num [1, 1] 1
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
NULL
下面是 xts
构造函数。您可以看到 tzone
参数被初始化为 Sys.getenv("TZ")
,计算结果为 "UTC"。所以我很困惑为什么 tzone
会根据 x
.
的内容以“”结尾
function (x = NULL, order.by = index(x), frequency = NULL, unique = TRUE,
tzone = Sys.getenv("TZ"), ...)
{
if (is.null(x) && missing(order.by))
return(structure(.xts(, 0), index = integer()))
if (!timeBased(order.by))
stop("order.by requires an appropriate time-based object")
if (inherits(order.by, "dates"))
tzone <- ""
if (inherits(order.by, "Date")) {
if (!missing(tzone))
warning(paste(sQuote("tzone"), "setting ignored for Date indexes"))
tzone <- "UTC"
}
if (NROW(x) > 0 && NROW(x) != length(order.by))
stop("NROW(x) must match length(order.by)")
orderBy <- class(order.by)
if (inherits(order.by, "Date")) {
order.by <- .POSIXct(unclass(order.by) * 86400, tz = tzone)
}
if (!isOrdered(order.by, strictly = !unique)) {
indx <- order(order.by)
if (!is.null(x)) {
if (NCOL(x) > 1 || is.matrix(x) || is.data.frame(x)) {
x <- x[indx, , drop = FALSE]
}
else x <- x[indx]
}
order.by <- order.by[indx]
}
if (!is.null(x) || length(x) != 0) {
x <- as.matrix(x)
}
else x <- numeric(0)
if (orderBy == "timeDate" && missing(tzone)) {
tzone <- order.by@FinCenter
}
else if (!is.null(attr(order.by, "tzone")) && missing(tzone))
tzone <- attr(order.by, "tzone")
if (inherits(order.by, "dates"))
index <- as.numeric(as.POSIXct(strptime(as.character(order.by),
"(%m/%d/%y %H:%M:%S)")))
else index <- as.numeric(as.POSIXct(order.by))
x <- structure(.Data = x, index = structure(index, tzone = tzone,
tclass = orderBy), class = c("xts", "zoo"), .indexCLASS = orderBy,
tclass = orderBy, .indexTZ = tzone, tzone = tzone, ...)
if (!is.null(attributes(x)$dimnames[[1]]))
dimnames(x) <- dimnames(x)
x
}
这与向 POSIXct 对象添加整数序列时丢失其 tzone
属性有关。如果使用 seq
创建 POSIXct 向量,tzone
属性将被保留。举例说明:
> attributes(as.POSIXct("2015-01-01"))
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
> attributes(as.POSIXct("2015-01-01")+0)
$class
[1] "POSIXct" "POSIXt"
> attributes(seq(as.POSIXct("2015-01-01"), by="sec", length.out=1))
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
我需要多考虑一下这是否是构造函数中的错误。
我认为这不是 xts 构造函数中的错误。问题是构造函数在存在 tzone
属性时尊重它,如果不存在则默认将其设置为 Sys.getenv("TZ")
。将整数序列添加到 POSIXct 对象会删除 tzone
属性,因此这就是为什么您会看到您所做的行为。
如果您希望在索引中使用特定时区并且您是通过 as.POSIXct
创建的,则需要明确设置 tz
参数。例如:
> str(xts(1, as.POSIXct("2015-01-01", tz=Sys.getenv("TZ"))))
An ‘xts’ object on 2015-01-01/2015-01-01 containing:
Data: num [1, 1] 1
Indexed by objects of class: [POSIXct,POSIXt] TZ: UTC
xts Attributes:
NULL
对单元测试的抱怨感到沮丧,我将范围缩小到一个 xts
对象的时区设置为 "UTC",另一个对象的时区设置为“”。
然后我进一步缩小范围,似乎是在创建一个只有一行的 xts 对象,而不是 2+ 行:
> str(xts( c(1,2), as.POSIXct("2015-01-01 00:00:00")+0:1))
An ‘xts’ object on 2015-01-01/2015-01-01 00:00:01 containing:
Data: num [1:2, 1] 1 2
Indexed by objects of class: [POSIXct,POSIXt] TZ: UTC
xts Attributes:
NULL
> str(xts( c(1), as.POSIXct("2015-01-01 00:00:01")))
An ‘xts’ object on 2015-01-01 00:00:01/2015-01-01 00:00:01 containing:
Data: num [1, 1] 1
Indexed by objects of class: [POSIXct,POSIXt] TZ:
xts Attributes:
NULL
下面是 xts
构造函数。您可以看到 tzone
参数被初始化为 Sys.getenv("TZ")
,计算结果为 "UTC"。所以我很困惑为什么 tzone
会根据 x
.
function (x = NULL, order.by = index(x), frequency = NULL, unique = TRUE,
tzone = Sys.getenv("TZ"), ...)
{
if (is.null(x) && missing(order.by))
return(structure(.xts(, 0), index = integer()))
if (!timeBased(order.by))
stop("order.by requires an appropriate time-based object")
if (inherits(order.by, "dates"))
tzone <- ""
if (inherits(order.by, "Date")) {
if (!missing(tzone))
warning(paste(sQuote("tzone"), "setting ignored for Date indexes"))
tzone <- "UTC"
}
if (NROW(x) > 0 && NROW(x) != length(order.by))
stop("NROW(x) must match length(order.by)")
orderBy <- class(order.by)
if (inherits(order.by, "Date")) {
order.by <- .POSIXct(unclass(order.by) * 86400, tz = tzone)
}
if (!isOrdered(order.by, strictly = !unique)) {
indx <- order(order.by)
if (!is.null(x)) {
if (NCOL(x) > 1 || is.matrix(x) || is.data.frame(x)) {
x <- x[indx, , drop = FALSE]
}
else x <- x[indx]
}
order.by <- order.by[indx]
}
if (!is.null(x) || length(x) != 0) {
x <- as.matrix(x)
}
else x <- numeric(0)
if (orderBy == "timeDate" && missing(tzone)) {
tzone <- order.by@FinCenter
}
else if (!is.null(attr(order.by, "tzone")) && missing(tzone))
tzone <- attr(order.by, "tzone")
if (inherits(order.by, "dates"))
index <- as.numeric(as.POSIXct(strptime(as.character(order.by),
"(%m/%d/%y %H:%M:%S)")))
else index <- as.numeric(as.POSIXct(order.by))
x <- structure(.Data = x, index = structure(index, tzone = tzone,
tclass = orderBy), class = c("xts", "zoo"), .indexCLASS = orderBy,
tclass = orderBy, .indexTZ = tzone, tzone = tzone, ...)
if (!is.null(attributes(x)$dimnames[[1]]))
dimnames(x) <- dimnames(x)
x
}
这与向 POSIXct 对象添加整数序列时丢失其 tzone
属性有关。如果使用 seq
创建 POSIXct 向量,tzone
属性将被保留。举例说明:
> attributes(as.POSIXct("2015-01-01"))
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
> attributes(as.POSIXct("2015-01-01")+0)
$class
[1] "POSIXct" "POSIXt"
> attributes(seq(as.POSIXct("2015-01-01"), by="sec", length.out=1))
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
我需要多考虑一下这是否是构造函数中的错误。
我认为这不是 xts 构造函数中的错误。问题是构造函数在存在 tzone
属性时尊重它,如果不存在则默认将其设置为 Sys.getenv("TZ")
。将整数序列添加到 POSIXct 对象会删除 tzone
属性,因此这就是为什么您会看到您所做的行为。
如果您希望在索引中使用特定时区并且您是通过 as.POSIXct
创建的,则需要明确设置 tz
参数。例如:
> str(xts(1, as.POSIXct("2015-01-01", tz=Sys.getenv("TZ"))))
An ‘xts’ object on 2015-01-01/2015-01-01 containing:
Data: num [1, 1] 1
Indexed by objects of class: [POSIXct,POSIXt] TZ: UTC
xts Attributes:
NULL