【问题标题】:How do I lookup a value in another zoo object?如何在另一个动物园对象中查找值?
【发布时间】:2019-09-09 17:56:31
【问题描述】:

我正在尝试找到一种在另一个动物园对象中查找值的方法。假设我有以下时间序列:

a <- read.zoo(data.frame(date=as.Date('2011-12-31') + 0:8, reldt=c(rep(as.Date("2012-02-01"),3), rep(as.Date("2012-03-01"),3), rep(as.Date("2012-01-01"),3)), col2=seq(11,19)), FUN = as.Date)
a
           reldt      col2
2011-12-31 2012-02-01 11  
2012-01-01 2012-02-01 12  
2012-01-02 2012-02-01 13  
2012-01-03 2012-03-01 14  
2012-01-04 2012-03-01 15  
2012-01-05 2012-03-01 16  
2012-01-06 2012-01-01 17  
2012-01-07 2012-01-01 18  
2012-01-08 2012-01-01 19  

mon <- read.zoo(data.frame(date=c(as.Date('2012-01-01'), as.Date('2012-02-01'), as.Date('2012-03-01')), mc=letters[1:3], mc2=c(100,200,300)LETTERS[1:3]), FUN = as.Date)
mon
           mc mc2
2012-01-01 a  100
2012-02-01 b  200
2012-03-01 c  300

对于a 中的每个reldt,我想在mon.mc2 列中查找值。换句话说,我想将mon.mc2 列中的相应值附加到a,这样我就有一个与a.reldt=index(mon) 匹配的a.mc2

这是我尝试过的(我知道这适用于 data.frame 但似乎不适用于动物园对象)。 由于某些原因无法正确对齐(我怀疑动物园对象不遵守match(...) 返回的索引顺序):

a$mc2 <- as.numeric(coredata(mon[match(as.Date(coredata(a$reldt)), as.Date(index(mon)))]$mc2))

这是我要输出的动物园对象:

          reldt      col2 mc2
2011-12-31 2012-02-01 11   200
2012-01-01 2012-02-01 12   200
2012-01-02 2012-02-01 13   200
2012-01-03 2012-03-01 14   300
2012-01-04 2012-03-01 15   300
2012-01-05 2012-03-01 16   300
2012-01-06 2012-01-01 17   100
2012-01-07 2012-01-01 18   100
2012-01-08 2012-01-01 19   100

注意:我更喜欢使用 zoo 的基本 R 解决方案,但它会是 看看其他可能有用的软件包很有趣

【问题讨论】:

  • 动物园对象必须是所有相同类型,如果您尝试混合类型,如问题所示,它将使用最小公分母,因此您的两个动物园对象都是字符对象。
  • @G.Grothendieck:我同意。这只是一个例子。关于如何在不降级到 data.frame 的情况下正确进行匹配的任何想法?我真的只是在寻找如何正确地进行比赛....

标签: r join dplyr time-series zoo


【解决方案1】:

正如 cmets 中所述,amon 都是不寻常的角色动物园对象;但是,我们仍然可以通过将a$reldt 匹配到as.character(time(mon)) 来做到这一点。从中创建一个新的动物园对象mc2 并将其与a 合并。

 mc2 <- zoo( coredata(mon$mc2)[match(a$reldt, as.character(time(mon)))], time(a) )
 cbind(a, mc2)

【讨论】:

    【解决方案2】:

    我建议首先使用数据框并加入它们,然后转换为动物园对象(如果你真的想要的话)。 使用dplyr 包可以轻松完成连接。在下面的代码中,a2mon2amon 的data.frame 版本。

    a2 <- data.frame(date=as.Date('2011-12-31') + 0:8, reldt=c(rep(as.Date("2012-02-01"),3), rep(as.Date("2012-03-01"),3), rep(as.Date("2012-01-01"),3)), col2=seq(11,19))
    
    mon2 <- data.frame(date = c(as.Date('2012-01-01'), as.Date('2012-02-01'), as.Date('2012-03-01')), mc=letters[1:3], 
                      mc2=c(100,200,300))
    
    library(dplyr)
    library(zoo)
    left_join(a2, mon2 %>% select(-mc), by = c("reldt" = "date")) %>%
      read.zoo(FUN = as.Date)
    
               reldt      col2 mc2
    2011-12-31 2012-02-01 11   200
    2012-01-01 2012-02-01 12   200
    2012-01-02 2012-02-01 13   200
    2012-01-03 2012-03-01 14   300
    2012-01-04 2012-03-01 15   300
    2012-01-05 2012-03-01 16   300
    2012-01-06 2012-01-01 17   100
    2012-01-07 2012-01-01 18   100
    2012-01-08 2012-01-01 19   100
    

    【讨论】:

    • 是的,如果我降级到 data.frame,我的问题解决方案将起作用。我想这是一种方式,但想知道我是否可以将其保留为动物园对象
    • 您还可以通过索引连接两个动物园对象。但是,在您的情况下,您不想加入索引和列,这对于时间序列对象来说非常罕见。
    • 可以从 xts 包中查看 merge.xts
    猜你喜欢
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多