7

我必须 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?
4

4 回答 4

4

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

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

这个解决方案的问题是,如果ys并且xs有一些不常见的日期,你将在你的最终对象中有重复的索引。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
于 2013-03-17T09:52:06.430 回答
2

What you want => 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
于 2013-03-17T10:08:15.847 回答
1

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

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)
}
于 2013-03-17T13:05:08.303 回答
0

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

于 2015-06-05T20:56:20.373 回答