【问题标题】:concatenating/ merging time series (in R)连接/合并时间序列(在 R 中)
【发布时间】:2013-03-05 17:59:13
【问题描述】:

我必须 xts/zoo 对象。每个都在不同的时间跨度内测量不同的变量。我想创建一个包含所有度量的单个时间序列,其中 NA 用于缺少日期/变量组合。我怎么做? 人工示例:

library(xts)
x<-cbind(a=1:3,b=3:1)
rownames(x) = as.character(Sys.Date()-1:3)

y<-cbind(a=5:7,c=3:1)
rownames(y) = as.character(Sys.Date()-5:7)

xs=as.xts(x)
ys=as.xts(y)

#now what?

#desired outcome looks like:
            a  b   c
2013-03-10  7 NA   1
2013-03-11  6 NA   2
2013-03-12  5 NA   3
2013-03-14  3  1  NA
2013-03-15  2  2  NA
2013-03-16  1  3  NA

# regular merge looks like that (adding an a.1 variable)
merge(xs,ys)
            a  b a.1  c
2013-03-10 NA NA   7  1
2013-03-11 NA NA   6  2
2013-03-12 NA NA   5  3
2013-03-14  3  1  NA NA
2013-03-15  2  2  NA NA
2013-03-16  1  3  NA NA

# simple concatenation ignores variable names and looks like that
c(xs,ys)
           a b
2013-03-10 7 1
2013-03-11 6 2
2013-03-12 5 3
2013-03-14 3 1
2013-03-15 2 2
2013-03-16 1 3

# so what should I do?

【问题讨论】:

  • 如果xsys 都具有a 的值会怎样?
  • 就我的目的而言,如果 xs“获胜”,则可以,并且 ys 中的相关数据点被抛出/忽略。我也对其他行为持开放态度。
  • xts 有一个 merge 函数,它执行 innerouterleftright 合并。但是您的问题并非特定于其中的any。你必须编写你自己的函数

标签: r merge concatenation xts


【解决方案1】:

这不是一个通用的解决方案。但适用于这个例子:

cbind(rbind(xs[,1],ys[,1]), cbind(xs[,-1],ys[,-1]))
           a  b  c
2013-03-10 7 NA  1
2013-03-11 6 NA  2
2013-03-12 5 NA  3
2013-03-14 3  1 NA
2013-03-15 2  2 NA
2013-03-16 1  3 NA

请提醒cbind.xts 就是merge.xts。 S 你可以使用merge得到相同的结果

merge(rbind(xs[,1],ys[,1]), merge(xs[,-1],ys[,-1]))
           a  b  c
2013-03-10 7 NA  1
2013-03-11 6 NA  2
2013-03-12 5 NA  3
2013-03-14 3  1 NA
2013-03-15 2  2 NA
2013-03-16 1  3 NA

这个解决方案的问题是,如果ysxs 有一些不常见的日期,你的最终xts 对象中会有重复的索引。例如,如果我们替换 y :

rownames(y) = as.character(Sys.Date()-3:5)

你得到,2013-03-14 的重复索引,所以我不确定它是一个有效的 xts 对象。

merge(rbind(xs[,1],ys[,1]), merge(xs[,-1],ys[,-1]))
           a  b  c
2013-03-12 7 NA  1
2013-03-13 6 NA  2
2013-03-14 3  1  3
2013-03-14 5 NA NA
2013-03-15 2  2 NA
2013-03-16 1  3 NA

编辑解决方案的概括:

inter <- intersect(names(ys), names(xs))
diffx <- setdiff(names(xs),inter)
diffy <- setdiff(names(ys),inter)

merge(rbind(xs[,inter],ys[,inter]), merge(xs[,diffx],ys[,diffy]))


           a  b  c
2013-03-10 7 NA  1
2013-03-11 6 NA  2
2013-03-12 5 NA  3
2013-03-14 3  1 NA
2013-03-15 2  2 NA
2013-03-16 1  3 NA

【讨论】:

  • 好吧,我这个简单示例背后的真实情况是,每个时间序列都包含多个变量(甚至是不同数量的变量),而它们的名称是我提前不知道的。我寻找一种简单的方法来“连接”这些对象,而无需明确指定列或变量名称,以便为“缺失值”提供 NA,并且对相同变量的观察结果适当地“堆叠”
  • @amit 你可以看到我的更新。我尝试了一个概括。这应该有效。
  • 好的。现在看起来好多了。我仍然希望找到更简单的东西。谢谢。
  • 我也是。我希望你能得到一些更简单的东西。也许如果@JoshuaUlrich 看到这个答案,他可以提出更好的解决方案。
  • 作为一个简单但现实的案例——一打(每个月一个以获得一整年的数据)。更一般地说,我可能有一些罕见的重叠,并且 xts 可能有不规则的日期。但总的来说,我尝试将一些 xts 对象,这些对象在一年内的不同(很少重叠)日期集上测量不同但重叠的变量集,并将其放入一个表示该年所有变量的所有测量值的对象中。跨度>
【解决方案2】:

What you want =&gt; merge(data.frame(x,d),data.frame(y,d),by=c("d","a"),all=T)

你应该使用 data.frame 而不是命名向量/矩阵,这是一个通用的解决方案,你想要的只是一个带有完整外连接的单行(查看 ?merge)

x<-cbind(a=1:3,b=3:1)
d= as.character(Sys.Date()-1:3)
DT1 = data.frame(x,d)
#DT1
#   a b          d
#1: 1 3 2013-03-16
#2: 2 2 2013-03-15
#3: 3 1 2013-03-14

y<-cbind(a=5:7,c=3:1)
d = as.character(Sys.Date()-5:7)
DT2 = data.frame(y,d)
#DT2
#   a b          d
#1: 1 3 2013-03-12
#2: 2 2 2013-03-11
#3: 3 1 2013-03-10
merge(DT1,DT2,by=c("d","a"),all=T)
#           d a  b  c
#1 2013-03-10 7 NA  1
#2 2013-03-11 6 NA  2
#3 2013-03-12 5 NA  3
#4 2013-03-14 3  1 NA
#5 2013-03-15 2  2 NA
#6 2013-03-16 1  3 NA

【讨论】:

  • 这里 OP 使用 xts 对象。它们是矩阵。
  • 都一样......他想要的是一个连接......这就是data.frame的用途
  • 谢谢。我刚刚发现对于数据框有一个解决方案,就像您在上面所做的那样。特定的“by”参数不够通用,但没有它也可以。唯一需要注意的是,结果不是 xts 对象,需要更多命令才能将其转换回 xts
  • by 尽可能通用,如果名称不同且它们是动态的,您可以指定 by.xby.y。结果是data.frame 与您想要的任何类型相距一行...
【解决方案3】:

好的。花了一些时间思考这个问题。因为最终我需要将许多这样的数据帧/xts“合并”为一个,而不仅仅是合并其中的两个,我认为一步完成所有这些是有意义的:创建一个包含所有日期/变量组合的大矩阵。然后将所有观察到的数据逐个对象插入这个大矩阵。代码如下所示(很高兴在上面安装 cmets,并且可以随意使用,当然没有任何形式的保证):

alltogether = function(dlist) {
    all.vars = unique(unlist(lapply(dlist,colnames)))
    all.obs = unique(unlist(lapply(dlist,rownames)))    
    res = array(NA,dim=c(length(all.obs),length(all.vars)),
          dimnames=list(all.obs,all.vars))
    for(d in dlist) {
            res[rownames(d),colnames(d)]=d
    }
    return(res)
}

alltogether.xts = function(xlist) {
    dlist = lapply(xlist,as.matrix)
    res = alltogether(dlist)
    xres = as.xts(res)
    return(xres)
}

【讨论】:

    【解决方案4】:

    我会说将其转换为数值数组 (as.numeric(ts)),将其与 cbind(ts1,ts2) 连接,然后返回到时间序列 ts(c(as.numeric (ts1),as.numeric(ts2))

    【讨论】:

    • 它完全解决了这个问题
    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 2014-10-01
    • 2022-08-18
    • 2021-02-28
    • 2011-10-28
    • 2014-05-29
    相关资源
    最近更新 更多