2015-05-19 6 views
6

क्या लूप का उपयोग करने से काउंटर इंडेक्स बनाने का कोई तेज़ तरीका है? समान मूल्यों के संगत रनों के भीतर, सूचकांक एक जैसा होना चाहिए। मुझे लूपिंग बहुत धीमी लगती है खासकर जब डेटा इतना बड़ा होता है।बराबर मानों के संगत रनों में इंडेक्स जोड़ें

उदाहरण के लिए, यहाँ इनपुट और वांछित आउटपुट है

x <- c(2, 3, 9, 2, 4, 4, 3, 4, 4, 5, 5, 5, 1) 

वांछित जिसके परिणामस्वरूप काउंटर:

c(1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9) 

ध्यान दें कि गैर -contiguous रन अलग अनुक्रमित है। जैसे मूल्यों 2 और 4

मेरे अक्षम कोड के वांछित अनुक्रमित देखना यह है:

group[1]<-1 
counter<-1 
for (i in 2:n){ 
if (x[i]==x[i-1]){ 
    group[i]<-counter 
}else{ 
    counter<-counter+1 
    group[1]<-counter} 
} 
+0

धन्यवाद TimoSta =) – Rens

उत्तर

7

आप इस तरह संख्यात्मक मान है, तो आप diff और cumsum उपयोग कर सकते हैं मूल्यों में परिवर्तन को जोड़ने के लिए

x <- c(2,3,9,2,4,4,3,4,4,5,5,5,1) 
cumsum(c(1,diff(x)!=0)) 
# [1] 1 2 3 4 5 5 6 7 7 8 8 8 9 
+0

धन्यवाद! यह कोड अच्छी तरह से काम करता है। =) – Rens

+0

मेरे उत्तर से निश्चित रूप से तेज़। इस समय अरुण के 'डेटाटेबल' उत्तर के खिलाफ आकलन नहीं कर सकता। – Jota

+0

उस टिप्पणी के लिए धन्यवाद फ्रैंक। अब मैं श्रीफ्लिक के सुझाव का उपयोग करूंगा। ऐसा लगता है कि अरुण के डेटाटेबल सुझाव के लिए कुछ स्थापना की आवश्यकता है। – Rens

8

data.table का उपयोग करना, समारोह rleid() है जो:

require(data.table) # v1.9.5+ 
rleid(x) 
# [1] 1 2 3 4 5 5 6 7 7 8 8 8 9 
+1

मदद के लिए धन्यवाद! =) – Rens

6

यह चरित्र मूल्यों का सांख्यिक के साथ काम करेंगे:

rep(1:length(rle(x)$values), times = rle(x)$lengths) 
#[1] 1 2 3 4 5 5 6 7 7 8 8 8 9 

तुम भी थोड़ा अधिक कुशल हो सकता rle सिर्फ एक बार (2x के बारे में तेजी से) पर कॉल करके और एक बहुत मामूली गति सुधार का उपयोग कर बनाया जा सकता है rep.int बजाय rep:

संपादन के लिए
y <- rle(x) 
rep.int(1:length(y$values), times = y$lengths) 
+0

धन्यवाद। यह कोड भी काम करता है! =) – Rens

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