2011-08-05 14 views
5

मैं निम्नलिखित वेक्टर में पत्र तुलना करने के लिए एक for loop लिखने में सफल:(परहेज छोरों) एक ही वेक्टर के आसन्न तत्वों की तुलना

bases <- c("G","C","A","T") 
test <- sample(bases, replace=T, 20) 

test

[1] "T" "G" "T" "G" "C" "A" "A" "G" "A" "C" "A" "T" "T" "T" "T" "C" "A" "G" "G" "C" 

वापस आ जाएगी समारोह Comp() मैं के साथ यह जांच कर सकते हैं कि कोई पत्र अगले अक्षर

Comp <- function(data) 
{ 
    output <- vector() 
    for(i in 1:(length(data)-1)) 
    { 
    if(data[i]==data[i+1]) 
     { 
     output[i] <-1 
     } 
     else 
     { 
     output[i] <-0 
     } 
    } 
    return(output) 
} 
से मेल खाता है या नहीं

परिणामस्वरूप;

> Comp(test) 
[1] 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0 

यह काम कर रहा है, फिर भी इसकी verry बड़ी संख्या के साथ धीमी गति से। वजह मैं sapply()

Comp <- function(x,i) if(x[i]==x[i+1]) 1 else 0 
unlist(lapply(test, Comp, test)) 

की कोशिश की दुर्भाग्य से अपने काम नहीं कर रहा ... (Error in i + 1 : non-numeric argument to binary operator) मैं मुसीबत पता लगाना है कि यह कैसे तुलना करने के लिए वेक्टर में पूर्ववर्ती पत्र का उपयोग करने के लिए है। इसके अलावा length(data)-1, अंतिम अक्षर की तुलना नहीं करने के लिए एक समस्या बन सकती है।

मदद के लिए सभी को धन्यवाद!

चीयर्स लकी

+0

मैंने समस्या को बेहतर तरीके से संदर्भित करने और संदर्भ उद्देश्यों के लिए शीर्षक को दोहराया। आपको यह भी पता होना चाहिए कि स्वाद/लापरवाही आदि * * लूप हैं, यद्यपि एक अलग रूप में। Http: // stackoverflow भी देखें।कॉम/प्रश्न/2275896/आईएस-आरएस-लागू-परिवार-से-सिंटेक्टिक-चीनी –

+0

धन्यवाद, मैं आर और प्रोग्रामिंग के लिए नया हूं, – LuckyLion

उत्तर

13

बस "अंतराल" test और == का उपयोग करें, जो vectorized है।

bases <- c("G","C","A","T") 
set.seed(21) 
test <- sample(bases, replace=TRUE, 20) 
lag.test <- c(tail(test,-1),NA) 
#lag.test <- c(NA,head(test,-1)) 
test == lag.test 

अद्यतन:

इसके अलावा, आपके Comp समारोह जब आप इसे प्रारंभ क्योंकि आप output की लंबाई निर्दिष्ट नहीं करते धीमी है। मुझे संदेह है कि आप पूर्व-आवंटित करने की कोशिश कर रहे थे, लेकिन vector() एक शून्य-लंबाई वेक्टर बनाता है जिसे आपके लूप के प्रत्येक पुनरावृत्ति के दौरान विस्तारित किया जाना चाहिए। यदि आप vector() से vector(length=NROW(data)-1) पर कॉल बदलते हैं तो आपका Comp फ़ंक्शन काफी तेज़ है।

set.seed(21) 
test <- sample(bases, replace=T, 1e5) 
system.time(orig <- Comp(test)) 
# user system elapsed 
# 34.760 0.010 34.884 
system.time(prealloc <- Comp.prealloc(test)) 
# user system elapsed 
# 1.18 0.00 1.19 
identical(orig, prealloc) 
# [1] TRUE 
+0

शर्तों से परिचित नहीं है बहुत धन्यवाद =) – LuckyLion

3

@Joshua के रूप में लिखा है, आप चाहिए पाठ्यक्रम उपयोग vectorization की - यह तरीका अधिक सक्षम है। ... लेकिन सिर्फ संदर्भ के लिए, आपके Comp फ़ंक्शन को अभी भी थोड़ा अनुकूलित किया जा सकता है।

तुलना का परिणाम TRUE/FALSE है जो 1/0 के गौरवशाली संस्करण है। साथ ही, नतीजे सुनिश्चित करने के परिणामस्वरूप आधा स्मृति उपभोग करने के बजाय परिणाम पूर्णांक है।

Comp.opt <- function(data) 
{ 
    output <- integer(length(data)-1L) 
    for(i in seq_along(output)) 
    { 
     output[[i]] <- (data[[i]]==data[[i+1L]]) 
    } 
    return(output) 
} 

... और गति अंतर:

> system.time(orig <- Comp(test)) 
    user system elapsed 
    21.10 0.00 21.11 
> system.time(prealloc <- Comp.prealloc(test)) 
    user system elapsed 
    0.49 0.00 0.49 
> system.time(opt <- Comp.opt(test)) 
    user system elapsed 
    0.41 0.00 0.40 
> all.equal(opt, orig) # opt is integer, orig is double 
[1] TRUE 
+0

धन्यवाद सुझाव! – LuckyLion

0

इस पर एक नज़र डालें:

> x = c("T", "G", "T", "G", "G","T","T","T") 
> 
> res = sequence(rle(x)$lengths)-1 
> 
> dt = data.frame(x,res) 
> 
> dt 
    x res 
1 T 0 
2 G 0 
3 T 0 
4 G 0 
5 G 1 
6 T 0 
7 T 1 
8 T 2 

तेज़ काम कर सकते।

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