2013-03-17 31 views
7

Tôi phải đối tượng xts/zoo. mỗi loại có các biến số khác nhau trong một khoảng thời gian khác nhau. Tôi muốn tạo một chuỗi thời gian duy nhất bao gồm tất cả các biện pháp mọi lúc, với NA cho ngày kết hợp/biến bị thiếu. Làm thế nào để làm điều đó? ví dụ nhân tạo:chuỗi thời gian ghép/hợp nhất (trong R)

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? 
+0

điều gì xảy ra nếu 'xs' và' ys' đều có giá trị cho 'a'? –

+0

cho mục đích của tôi thì ok nếu xs" thắng "và điểm dữ liệu có liên quan trong y được ném/bỏ qua. – amit

+0

'xts' có hàm' merge'function có 'inner',' outer', 'left 'và' right' hợp nhất. Nhưng vấn đề của bạn không phải là cụ thể đối với 'bất kỳ 'của chúng. bạn sẽ phải * viết chức năng của riêng bạn *. – Arun

Trả lời

4

Đây không phải là giải pháp chung. Nhưng hoạt động cho ví dụ này:

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 

Chỉ cần nhắc rằng cbind.xts chỉ là merge.xts. S bạn có thể nhận được kết quả tương tự sử dụng 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 

Vấn đề với giải pháp này là nếu ysxs có một số ngày incommon, bạn sẽ phải nhân đôi chỉ số trong trận chung kết xts dụ object.For của bạn, nếu chúng ta thay thế y :

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

Bạn nhận được, một chỉ số trùng lặp cho 2013-03-14, vì vậy, im anot chắc chắn rằng nó sa đối tượng hợp lệ 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 

EDIT một sự tổng quát của giải pháp:

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 
+0

, trường hợp thực sự đằng sau ví dụ đơn giản của tôi, là mỗi chuỗi thời gian chứa nhiều biến số (thậm chí là số biến khác nhau) và tên của chúng là điều tôi không biết trước. Tôi tìm kiếm một cách đơn giản để "ghép nối" các đối tượng đó, mà không chỉ rõ các cột hoặc tên biến một cách rõ ràng, do đó "các giá trị bị thiếu" được cho NA và quan sát các biến tương tự được "xếp chồng" một cách thích hợp – amit

+0

@amit bạn có thể thấy cập nhật. Tôi đã thử một khái quát. Điều này sẽ làm việc. – agstudy

+0

Ok. nó bây giờ trông tốt hơn nhiều.Tôi vẫn hy vọng tìm thấy một cái gì đó đơn giản hơn. Cảm ơn. – amit

2

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

Bạn nên sử dụng data.frame không tên vectơ/ma trận, đây là một giải pháp chung, những gì bạn muốn chỉ là một lớp lót có sự tham gia đầy đủ bên ngoài (xem? hợp nhất)

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 
+0

Ở đây OP đang sử dụng đối tượng 'xts'. Chúng là ma trận. – agstudy

+0

Tất cả cùng ... những gì anh ta muốn là một tham gia ... đó là những gì data.frame được cho – statquant

+0

cảm ơn. Tôi chỉ phát hiện ra rằng đối với dataframes có một giải pháp như bạn đã làm ở trên. thông số "by" cụ thể không đủ chung, nhưng nó hoạt động mà không có. báo trước duy nhất là kết quả không phải là một đối tượng xts, và cần thêm một vài lệnh để chuyển nó trở lại thành xts – amit

1

ok. đã dành thời gian suy nghĩ về điều này. bởi vì cuối cùng tôi cần phải "hợp nhất" nhiều datafram/xts thành một, và không chỉ hợp nhất hai trong số chúng, tôi nghĩ rằng nó có ý nghĩa để làm tất cả điều này trong một bước: tạo một ma trận lớn của tất cả các kết hợp ngày/var. sau đó cắm vào ma trận lớn này tất cả các dữ liệu quan sát, đối tượng của đối tượng. mã trông như sau (sẽ được hạnh phúc để có được ý kiến ​​về nó, và cảm thấy tự do để sử dụng, mà không cần bất kỳ loại bảo hành, tất nhiên):

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) 
} 
0

tôi sẽ nói để chuyển đổi nó vào một mảng số (as.numeric (ts)), nối nó với cbind (ts1, ts2) và sau đó quay trở lại chuỗi thời gian, ts (c (as.numeric (ts1), as.numeric (ts2))

+0

nó hoàn toàn awnsers câu hỏi –