2013-03-17 2 views
7

У меня есть объекты xts/zoo. каждый из них имеет различные переменные в течение другого промежутка времени. Я хочу создать единый временной ряд, включающий все меры во все времена, с NA для отсутствующих дат/переменных комбинаций. как это сделать? искусственный пример:конкатенирование/слияние временных рядов (в 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

Что происходит если 'xs' и' ys' оба имеют значение для 'a'? –

+0

для моих целей - это нормально, если xs« выигрывает », а соответствующая точка данных в ys бросается/игнорируется. Я открыт для других видов поведения . – amit

+0

'xts' имеет функцию' merge', которая выполняет 'inner',' outer', 'left 'и' right' сливается. Но ваша проблема не специфична для них. вам придется * написать свою собственную функцию *. – Arun

ответ

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 есть некоторые даты InCommon, вы дублировали индекс в вашем окончательном xts object.For Например, если мы заменим у :

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

Вы получаете, дублированный индекс для 2013-03-14, поэтому им anot уверен, что это са действительного 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 обобщение решения:

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

Ну, реальный случай, стоящий за моим простым примером, состоит в том, что каждый временной ряд содержит несколько переменных (даже различное количество переменных), а их имена - это то, чего я не знаю заранее. Я ищу простой способ «конкатенировать» эти объекты, не указывая явно столбцы или имена переменных, так что «отсутствующие значения» даны NA, а наблюдения тех же переменных «укладываются» соответственно – amit

+0

@amit вы можете видеть мои Обновить. Я попробовал обобщение. Это должно сработать. – agstudy

+0

Хорошо. теперь он выглядит намного лучше.Я все еще надеялся найти что-то более простое. Благодарю. – amit

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

Здесь OP использует объект 'xts'. Это матрица. – agstudy

+0

Все равно ... что он хочет, это присоединиться ... вот что такое data.frame для – statquant

+0

спасибо. Я только что узнал, что для dataframes есть решение, как вы это делали выше. конкретный параметр «by» не является достаточно общим, но работает без него. единственное предостережение заключается в том, что результат не является объектом xts, и требуется еще несколько команд для его преобразования в xts. – amit

1

ОК. некоторое время размышлял над этим. потому что в конечном итоге мне нужно «объединить» многие такие dataframes/xts в один, а не просто слить два из них, я подумал, что имеет смысл сделать все это за один шаг: создать большую матрицу всех комбинаций date/var. затем вставляя в эту большую матрицу все наблюдаемые данные, объект по объекту. код выглядит следующим образом (будет рад получить комментарии по нему, и чувствовать себя свободно использовать, без каких-либо гарантий, конечно):

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

Я хотел бы сказать, чтобы преобразовать его в числовой массив (as.numeric (ts)), объедините его cbind (ts1, ts2), а затем вернитесь к временному ряду ts (c (as.numeric (ts1), as.numeric (ts2))

+0

он полностью подводит вопрос –

Смежные вопросы