【问题标题】:Subsetting zoo series by a time that is not in the series按不在系列中的时间对动物园系列进行子集
【发布时间】:2013-12-25 10:18:49
【问题描述】:

R 中是否有一个好的包允许按不在时间序列中的时间对时间序列进行子集(即索引)? 例如。对于金融应用程序,按不在数据库中的时间戳索引价格系列,应返回时间戳之前的最新可用价格。

在代码中,这就是我想要的

n =15
full.dates = seq(Sys.Date(), by = 'day', length = n)
series.dates = full.dates[c(1:10, 12, 15)] 
require(zoo)
series=zoo(rep(1,length(series.dates)), series.dates)
series[full.dates[11]]

这会返回

Data:
numeric(0)

Index:
character(0)

但是,我希望它返回 full.dates[11] 之前的最后一个现有日期的值,即 full.dates[10]:

series[full.dates[10]]
2014-01-03 
     1 

谢谢

【问题讨论】:

  • 除了@Henrik给出的答案,还要检查来自zoo的na.locf()。

标签: r zoo


【解决方案1】:

您可以使用index 提取zoo 对象中的观察索引。然后可以使用索引来设置对象的子集。一步一步展示逻辑(如果我理解正确,你只需要最后一步):

# the index of the observations, here dates
index(series)

# are the dates smaller than your reference date?
index(series) < full.dates[11]

# subset observations: dates less than reference date
series[index(series) < full.dates[11]]

# select last observation before reference date:
tail(series[index(series) < full.dates[11]], 1)

# 2014-01-03 
#          1

一种可能的替代方法是扩展您的时间序列并使用na.locfxout 参数“用最近的非NA 替换[e] 每个NA”(另请参见?na.locf?approxthis answer)

# expand time series to the range of dates in 'full.dates'
series2 <- na.locf(series, xout = full.dates)
series2

# select observation at reference date
series2[full.dates[10]]
# 2014-01-03 
#          1

如果您希望将不完整系列中的缺失值替换为“向后进行的下一个观察”,您需要使用包含所需连续日期范围的“虚拟”动物园对象 merge 您的系列。

series3 <- merge(series, zoo(, full.dates))
na.locf(series3, fromLast = TRUE)

【讨论】:

  • 非常感谢,但是没有一个包已经包含了这个非常自然的功能吗?
  • 如果没有,您能否建议正确的语法来覆盖 zoo 中的方法 [ ] 以包含此内容?我在包吸墨纸中使用动物园对象,它破坏了我的脚本,我无法在不属于原始索引的时间索引动物园对象。如果我可以将此功能添加到动物园中,我认为吸墨纸功能(例如 updatePortfolio)将开始神奇地工作(或者我希望如此)。再次非常感谢!
  • @user3134270,我已经用替代解决方案更新了我的答案
  • 我认为您需要澄清“不能在不属于原始索引的时间索引动物园对象”的意思。我的第一个答案不是表明这是可能的吗?抱歉,如果我忽略了一些明显的事情。干杯。
  • 您的解决方案不是我需要的最佳解决方案。我还有其他使用 [ ] 来对动物园系列进行子集化的包和功能(即 blogger / updatePortfolio)。
【解决方案2】:

na.locf(x, xout = newdate) 似乎并不比下标差多少,但无论如何,我们在这里定义了一个名为"zoo2""zoo" 的子类,其中[ 使用na.locf。这是一个未经测试的最小实现,但可以扩展:

as.zoo2 <- function(x) UseMethod("as.zoo2")
as.zoo2.zoo <- function(x) structure(x, class = c("zoo2", setdiff(class(x), "zoo2")))
"[.zoo2" <- function(x, i, ...) {
    if (!missing(i) && inherits(i, class(index(x)))) {
        zoo:::`[.zoo`(na.locf(x, xout = i),, ...)
    } else as.zoo2(zoo:::`[.zoo`(x, i, ...))
}

这给出了:

> series2 <- as.zoo2(series)
> series2[full.dates[11]]
2014-01-04 
         1 

【讨论】:

    【解决方案3】:

    我强烈认为如果所需的索引值不存在,子集函数应该返回前一行。子集函数应该返回用户请求的内容;他们不应该假设用户想要的东西与他们所要求的不同。

    如果这是想要的,您可以使用if 语句相当轻松地处理它。

    series.subset <- series[full.dates[11]]
    if(NROW(series.subset)==0) {
      # merge series with an empty zoo object
      # that contains the index value you want
      prior <- merge(series, zoo(,full.dates[11]))
      # lag *back* one period so the NA is on the prior value
      prior <- lag(prior, 1)
      # get the index value at the prior value
      prior <- index(prior)[is.na(prior)]
      # subset again
      series.subset <- series[prior]
    }
    

    【讨论】:

    • 太棒了,太棒了,谢谢你教我基本的 R 语法。有人可以教我一些更高级的东西 - 如何创建我自己的类(或者它在 R 中叫什么)zoo1,它派生自动物园(?),其中上述功能是 [] 运算符的一部分。这就是我想要的。对于 [ ] 返回数据。无需向该类的用户公开其他语法。真的非常感谢。
    • @user3134270:正如我在回答中所说,这是一个非常糟糕的主意。你会感到失望,因为创建一个 Zoo 的子类,将你描述的子集划分为子类,它可能会破坏而不是修复它。另外,blotter 使用 xts,而不是 zoo。如果您不了解吸墨纸包的工作原理,那么您不应该期望它在您更改其基本组件之一的行为时不会中断。这个问题你有两个答案。就您尝试解决的实际问题提出一个新问题,而不是您尝试解决的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多