2016-01-03 20 views
5

Verilen çeşitli tek satır XTS nesneler:Xts nesnelerini biraz farklı sütunlarla birleştirmek nasıl?

z1 = xts(t(c("9902"=0,"9903"=0,"9904"=0,"9905"=2,"9906"=2)),as.Date("2015-01-01")) 
z2 = xts(t(c("9902"=3,"9903"=4,"9905"=6,"9906"=5,"9908"=8)),as.Date("2015-01-02")) 
z3 = xts(t(c("9901"=1,"9903"=3,"9905"=5,"9906"=6,"9907"=7,"9909"=9)),as.Date("2015-01-03")) 

Ben tek XTS nesne içine birleştirmek istiyorum. Ama cbind(z1,z2,z3) verir: ne bekliyoruz

  X9902 X9903 X9904 X9905 X9906 X9902.1 X9903.1 X9905.1 X9906.1 X9908 X9901 X9903.2 X9905.2 X9906.2 X9907 X9909 
2015-01-01  0  0  0  2  2  NA  NA  NA  NA NA NA  NA  NA  NA NA NA 
2015-01-02 NA NA NA NA NA  3  4  6  5  8 NA  NA  NA  NA NA NA 
2015-01-03 NA NA NA NA NA  NA  NA  NA  NA NA  1  3  5  6  7  9 

Oysa:

  9901 9902 9903 9904 9905 9906 9907 9908 9909 
2015-01-01 0 0 0 0 2 2 0 0 0 
2015-01-02 0 3 4 0 6 5 0 8 0 
2015-01-03 1 0 3 0 5 6 7 0 9 

(. Ben UA'lar yani cbind(z1,z2,z3,fill=0), fill=0 vererek sıfır olarak değiştirildi alabilirsiniz)

rbind(z1,z2,z3)

satır şikayet farklı sayıda sütun var. Ancak, eğer eksik sütunlar her xts nesnesine önceden eklendiyse, bunun iyi bir yaklaşım olacağına inanıyorum.

Gerçek verilerde 1000 satırlık satır ve birkaç yüz sütun (bir kez birleştirildi) olabilir, bu nedenle verimliliğe bir göz atıyorum.

+0

'merge.xts' ve' sen ('cbind' veya)' merge' kullanarak istenen sonucu alamayan bu yüzden sadece, dizine göre birleştirme merge.zoo'. Yani 'rbind' ihtiyacım var gibi görünüyor, ama (dediğiniz gibi) tüm nesnelerin aynı sırayla aynı sayıda sütunlara sahip olmasını gerektirecektir. –

cevap

4

Benim yorumumda belirtildiği gibi, merge.xts (ve merge.zoo) yalnızca dizine göre birleştirilmiştir, böylece merge (veya cbind) kullanarak istediğiniz sonucu elde edemezsiniz. Yani, rbind'a ihtiyacınız var gibi görünüyor, ancak (dediğiniz gibi), tüm nesnelerin aynı sırayla aynı sayıda sütuna sahip olmasını gerektirecektir.

Nesneleri işlemeye yardımcı olmak için aşağıdaki iki işlevi oluşturdum, böylece istediğiniz sonucu oluşturmak için rbind yapabilirsiniz.

# put all xts objects in a list for easier processing 
x <- list(z1, z2, z3) 

# function to create template xts object 
template <- function(xlist) { 
    # find set of unique column names from all objects 
    cn <- unique(unlist(lapply(xlist, colnames))) 
    # create template xts object 
    # using a date that doesn't occur in the actual data 
    minIndex <- do.call(min, lapply(xlist, function(x) index(x[1L,]))) 
    # template object 
    xts(matrix(0,1,length(cn)), minIndex-1, dimnames=list(NULL, sort(cn))) 
} 

# function to apply to each xts object 
proc <- function(x, template) { 
    # columns we need to add 
    neededCols <- !(colnames(template) %in% colnames(x)) 
    # merge this object with template object, filling w/zeros 
    out <- merge(x, template[,neededCols], fill=0) 
    # reorder columns (NB: merge.xts always uses make.names) 
    # and remove first row (from template) 
    out <- out[-1L,make.names(colnames(template))] 
    # set column names back to desired values 
    # (using attr<- because dimnames<-.xts copies) 
    attr(out, "dimnames") <- list(NULL, colnames(template)) 
    # return object 
    out 
} 
(res <- do.call(rbind, lapply(x, proc, template=template(x)))) 
#   9901 9902 9903 9904 9905 9906 9907 9908 9909 
# 2015-01-01 0 0 0 0 2 2 0 0 0 
# 2015-01-02 0 3 4 0 6 5 0 8 0 
# 2015-01-03 1 0 3 0 5 6 7 0 9 
+0

Teşekkürler; Sanırım bununla gideceğim. Performansta, her bir xts nesnesini yeniden oluşturmaya kıyasla daha büyük bir boş matris oluşturmak ve buna kopyalamak için önemli bir fark olacağını düşünüyor musunuz? (R'de matrisler sıralı olarak sıralanırken, rbind'in bu tür bir kopyaya ihtiyacı olduğunu mu varsayıyorum?) –

+1

@DarrenCook: Başımın üstünden değil. Daha hızlı olabilir, ancak her iki yolu da doğrulamak için profil yapmak zorundayım. 'rbind', bu tür bir kopya yapar, ancak R işlevlerini çağırmaktan genellikle daha hızlı olan' memcopy'ı kullanabilir. –

1
library(xts) 
library(plyr) 

z1df <- as.data.frame(z1) 
z2df <- as.data.frame(z2) 
z3df <- as.data.frame(z3) 

res <- rbind.fill(z1df, z2df, z3df) 
res[is.na(res)] <- 0 
res 

# 9902 9903 9904 9905 9906 9908 9901 9907 9909 
#1 0 0 0 2 2 0 0 0 0 
#2 3 4 0 6 5 8 0 0 0 
#3 0 3 0 5 6 0 1 7 9 

Bu

combining two data frames of different lengths

tarih sütununu

res$Date <- c("2015-01-01", "2015-01-02", "2015-01-03") # the appropriate values 
res$Date <- as.Date(res$Date) 

Dahil Ve XTS nesne dönüşümü aşağıdaki stackoverflow mesaja benzer

xts(res[,-10], order.by=res[,10]) 
+2

'rbind.fill' xts içinde değil. Sonuç aynı zamanda bir xts nesnesi değil. –

+0

@JoshuaUlrich Teşekkürler. – steveb

+0

Güncelleştirilmiş çözüm, her bir nesnedeki zamanların ardışık ve çakışmasız olduğunu varsayar ki bu muhtemelen geçerli değildir. Gerçek verilere uygulandığında, muhtemelen her bir satıra yanlış tarihler atayabilirsiniz. –