2016-01-03 9 views
5

को देखते हुए विभिन्न एक-पंक्ति XTS वस्तुओं:एक्सटीएस ऑब्जेक्ट्स को थोड़ा अलग कॉलम के साथ कैसे विलय करें?

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")) 

मैं उन्हें एक ही XTS वस्तु में मर्ज करना चाहते हैं। लेकिन cbind(z1,z2,z3) देता है:

  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 

जबकि मैं क्या उम्मीद है:

  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 

(। मैं प्राप्त कर सकते हैं NAS fill=0 दे रही है, यानी cbind(z1,z2,z3,fill=0) साथ शून्य करने के लिए बदल)

rbind(z1,z2,z3) शिकायत है कि पंक्तियों कॉलम की अलग संख्या है। लेकिन, मेरा मानना ​​है कि यदि गायब कॉलम प्रत्येक एक्सटीएस ऑब्जेक्ट में पहले से जोड़े गए थे तो यह एक अच्छा दृष्टिकोण होगा?

वास्तविक डेटा में पंक्तियों के 1000s, और कुछ सौ कॉलम (एक बार मर्ज किए गए) हो सकते हैं, इसलिए मुझे दक्षता पर एक नजर आ गई है।

+0

'merge.xts' और' केवल, सूचकांक द्वारा विलय merge.zoo' तो आप अपने वांछित परिणाम 'merge' का उपयोग कर (cbind' या') नहीं मिल सकता है। तो ऐसा लगता है कि आपको 'rbind' की आवश्यकता है, लेकिन (जैसा कि आप कहते हैं) इसके लिए सभी ऑब्जेक्ट्स की एक ही क्रम में कॉलम की संख्या समान होगी। –

उत्तर

4

जैसा कि मैंने अपनी टिप्पणी में उल्लेख किया है, merge.xts (और merge.zoo) केवल इंडेक्स द्वारा विलय करें, इसलिए आप merge (या cbind) का उपयोग करके अपना वांछित परिणाम प्राप्त नहीं कर सकते हैं। तो ऐसा लगता है कि आपको rbind की आवश्यकता है, लेकिन (जैसा कि आप कहते हैं) इसके लिए सभी ऑब्जेक्ट्स को उसी क्रम में कॉलम की समान संख्या की आवश्यकता होगी।

मैंने वस्तुओं को संसाधित करने में सहायता के लिए नीचे दो कार्य बनाए हैं ताकि आप अपना वांछित परिणाम बनाने के लिए rbind कर सकें।

# 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

धन्यवाद; मुझे लगता है कि मैं इसके साथ जाऊंगा। क्या आपको लगता है कि प्रत्येक एक्सटीएस ऑब्जेक्ट को फिर से बनाने की तुलना में, एक विशाल रिक्त मैट्रिक्स को आगे बढ़ाने के लिए प्रदर्शन में महत्वपूर्ण अंतर आएगा, और फिर rbind को कॉल करने की तुलना में इसमें प्रतिलिपि होगी? (चूंकि आर में मैट्रिस कॉलम-प्रमुख ऑर्डर किए गए हैं, मुझे लगता है कि आरबीआईंड को उस तरह की प्रतिलिपि करने की ज़रूरत है, वैसे भी?) –

+1

@ डैरेनकूक: मेरे सिर के ऊपर से नहीं। यह तेज़ हो सकता है, लेकिन मुझे किसी भी तरह से सत्यापित करने के लिए प्रोफाइल करना होगा। 'rbind' उस तरह की प्रतिलिपि करता है, लेकिन यह 'memcopy' का उपयोग कर सकता है, जो आर कार्यों को कॉल करने से आमतौर पर तेज़ होता है। –

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 

यह निम्न stackoverflow पद

combining two data frames of different lengths

तारीख स्तंभ

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

शामिल हैं और बदलने के लिए XTS वस्तु के समान है

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

'rbind.fill' xts में नहीं है। आपका परिणाम xts ऑब्जेक्ट भी नहीं है। –

+0

@ जोशुआउलिच धन्यवाद। – steveb

+0

अद्यतन समाधान मानता है कि प्रत्येक ऑब्जेक्ट में समय अनुक्रमिक और गैर-ओवरलैपिंग होता है, जो संभवतः मामला नहीं है। वास्तविक डेटा पर लागू, यह संभवतः प्रत्येक पंक्ति को गलत तिथियां असाइन करेगा। –

संबंधित मुद्दे