2017-01-09 8 views
7

नीचे दिए गए उदाहरण में, मुझे 010 अनुक्रमों की संख्या, या 1010 अनुक्रमों की संख्या पता है। नीचे एक व्यावहारिक उदाहरण है;बाइनरी संयोजनों के दो अवलोकनों की संख्या को कैसे गिनें?

x <- c(1,0,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0) 

इस उदाहरण में, 010 दृश्यों की संख्या 6 हो सकता है और 1010 दृश्यों की संख्या होगी 4.

क्या सबसे कुशल/सरल लगातार दृश्यों की संख्या की गणना करने के लिए तरीका क्या होगा?

+0

यह पहले मामले 'sum (diff (diff (x)) == -2) के लिए काम करता है, लेकिन कोई यह जांच सकता है कि यह कहीं भी विफल रहता है या नहीं। –

उत्तर

7

एक अन्य समाधान इस होगा:

library(stringr) 
x <- c(1,0,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0) 
xx = paste0(x, collapse = "") 
str_count(xx, '(?<=010)') 
[1] 6 

str_count(xx, '(?<=1010)') 
[1] 4 

रूप @Pierre Lafortune टिप्पणियाँ इस किया जा सकता है में बताया किसी भी संकुल का उपयोग किए बिना:

length(gregexpr("(?<=010)", xx, perl=TRUE)[[1]]) 
[1] 6 
+0

अरे यह अच्छा है !! मुझे लगता है कि मुझे जल्द ही यह पैकेज सीखना होगा !! :) मैं आधार आर –

+0

@ joel.wilson का उपयोग करने में व्यस्त था, इस तरह की चीजों की गिनती के लिए यह वास्तव में सुविधाजनक है। – Kristofersen

+3

दोनों मामलों के लिए आउटपुट गलत है –

5

तर्क: उस पैटर्न की लंबाई का एक सबस्ट्रेट लें जिसे आप खोज रहे हैं और पैटर्न के साथ इसकी तुलना करें।

xx = paste0(x, collapse = "") 
# [1] "1001000111001010101010" 
# case 1 : 
xxx = "010" 
sum(sapply(1:(length(x)-nchar(xxx)+1), function(i) substr(xx,i,i+nchar(xxx)-1)==xxx)) 
# [1] 6 

# case 2 : 
xxx = "1010" 
# [1] 4 
10

एक stringless रास्ता:

f = function(x, patt){ 
    if (length(x) == length(patt)) return(as.integer(x == patt)) 
    w = head(seq_along(x), 1L-length(patt)) 
    for (k in seq_along(patt)) w <- w[ x[w + k - 1L] == patt[k] ] 
    w 
} 

length(f(x, patt = c(0,1,0))) # 6 
length(f(x, patt = c(1,0,1,0))) # 4 

विकल्प।

function(x,patt) sum(apply(embed(x,length(patt)),1,function(x) all(!xor(x,patt)))) 

या एक और भिन्नता:

function(x,patt) sum(!colSums(xor(patt, t(embed(x,length(patt)))))) 

या data.table साथ:

library(data.table) 
setkey(setDT(shift(x, seq_along(patt), type = "lead")))[as.list(patt), .N] 

(shift समारोह बहुत embed के समान है से @ cryo11, यहाँ एक और तरीका है।)

+0

+1। यहां एक और एक: 'एफ = फ़ंक्शन (एक्स, पैट) योग (लागू करें (एम्बेड करें, एक्स, लंबाई (पैट)), 1, फ़ंक्शन (x) सभी (! Xor (x, patt)))'। इसे बाहरी 'लंबाई' की आवश्यकता नहीं है। – cryo111

+0

@ cryo111 कूल, इसके लिए xor का उपयोग करने का कभी सोचा नहीं! मुझे लगता है कि 'एम्बेड करें 'का उपयोग' ==', ट्रांसपोज़/स्वीप, और कॉल या पंक्ति रकम के साथ करने के तरीके भी हैं। – Frank

3

आर नेपेश किया 3.3.0 मेंसमारोह। इस और substring का उपयोग करना, हम @ joel.wilson की विधि लागू कर सकते हैं के रूप में

sum(startsWith(substring(paste(x, collapse=""), 
         head(seq_along(x), -2), tail(seq_along(x), -2)), "010")) 

यहाँ, substring निर्माणों तीनों चरित्र आसन्न सेट और startsWith परीक्षण करता है, तो इनमें से प्रत्येक के रूप में "010" में ही है। फिर सही मूल्यों को एक साथ सम्मिलित किया जाता है।

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