【问题标题】:Why does one-row xts object not get a timezone? (why does it ignore/override the default argument)为什么单行 xts 对象没有时区? (为什么它忽略/覆盖默认参数)
【发布时间】:2016-04-12 07:58:31
【问题描述】:

对单元测试的抱怨感到沮丧,我将其缩小到一个 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
}

【问题讨论】:

  • 你的sessionInfo()Sys.timezone() 是什么?

标签: r xts


【解决方案1】:

这与向 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

【讨论】:

  • 谢谢。使用as.POSIXct("2015-01-01 00:00:01")+0 是在我的单元测试中修复它的最简单方法。我同意这不是 xts 构造函数中的错误。不过,在我看来,这确实是 POSIXct add-integer 代码中的一个错误:在完成添加时删除您的时区是意料之外的。 (此外,POSIXct 将 tzone 默认为“”而不是 Sys.getenv(“TZ”),如果未指定,这是令人惊讶的行为;但我想现在更改它已经太成熟了。)
猜你喜欢
  • 2011-08-30
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多