2017-03-27 11 views
5

तो, अगर इनपुट के रूप मेंअगर वे अनुक्रमिक हैं तो मैं केवल वेक्टर में संख्याओं को कैसे उलट सकता हूं?

v <- (1, 2, 3, 7, 2, 8, 9) 

एक वेक्टर ऐसी है उत्पादन होगा

(3, 2, 1, 7, 2, 9, 8) 

मैं के लिए और एक is.sorted समारोह के रूप में शर्त के साथ छोरों अगर नेस्टेड उपयोग करने की कोशिश की है, लेकिन ऐसा नहीं किया है कोई सफलता मिली

+1

भी देखें: [नियमित रूप से, लगातार दृश्यों के समूहों में एक सदिश विभाजन कैसे?] (Http: //stackoverflow.com/questions/5222061/how-to-partition-a-vec नियमित रूप से लगातार अनुक्रमों के टोर-इन-ग्रुप) – Henrik

+0

... जो मुझे विश्वास है कि 'cumsum (... diff (...' idiom के लिए एक अच्छा, कैनोलिक पोस्ट है। – Henrik

उत्तर

8
नमूना डेटा

x <- c(1, 2, 3, 7, 2, 8, 9) 

आप

grp <- cumsum(!c(TRUE, diff(x)==1)) 
grp 
# [1] 0 0 0 1 2 3 3 

असल में हम पिछले तत्व से diff को देखो और परिवर्तन ट्रैक के साथ "अनुक्रमिक समूह" में विभाजन कर सकते हैं किसी भी समय है कि मूल्य नहीं है के साथ

1 के बराबर 1.

आप ave (यह एक समूह परिवर्तन) के साथ उन मानों को फिर से ऑर्डर करने के लिए इस समूह की जानकारी का उपयोग कर सकते हैं।

revsort<-function(...) sort(...,decreasing=TRUE) 
ave(x, grp, FUN=revsort) 
# [1] 3 2 1 7 2 9 8 
5

हम भी कर सकता है:

x <- c(0, which(diff(vec) != 1), length(vec)) 
unlist(sapply(seq(length(x) - 1), function(i) rev(vec[(x[i]+1):x[i+1]]))) 

#[1] 3 2 1 7 2 9 8 

विचार पहली बार लगातार नंबर की स्थितियों के आधार पर वेक्टर कटौती करने के लिए है। फिर हम इन कटों को पार करते हैं और rev लागू करते हैं।


डाटा

vec <- c(1, 2, 3, 7, 2, 8, 9) 

बेंचमार्किंग

library(microbenchmark) 
vec1 <- c(1, 2, 3, 7, 2, 8, 9) 
vec2 <- c(1:1000, sample.int(100, 10), 5:500, sample.int(100, 10), 100:125) 

f_MrFlick <- function(x){ 
    revsort<-function(...) sort(...,decreasing=TRUE) 
    grp <- cumsum(!c(TRUE, diff(x)==1)) 
    ave(x, grp, FUN=revsort) 
} 

f_989 <- function(vec){ 
    x <- c(0, which(diff(vec) != 1), length(vec)) 
    unlist(sapply(seq(length(x) - 1), function(i) rev(vec[(x[i]+1):x[i+1]]))) 
} 

all(f_MrFlick(vec1)==f_989(vec1)) 
# [1] TRUE 
all(f_MrFlick(vec2)==f_989(vec2)) 
# [1] TRUE 

length(vec1) 
# [1] 7 
microbenchmark(f_MrFlick(vec1), f_989(vec1)) 
# Unit: microseconds 
      # expr  min  lq  mean median  uq  max neval 
# f_MrFlick(vec1) 287.006 297.0585 305.6340 302.833 312.6695 479.912 100 
    # f_989(vec1) 113.348 119.7645 124.7901 121.903 127.0360 268.186 100 
# -------------------------------------------------------------------------- 
length(vec2) 
# [1] 1542 
microbenchmark(f_MrFlick(vec2), f_989(vec2)) 
# Unit: microseconds 
      # expr  min  lq  mean median  uq  max neval 
# f_MrFlick(vec2) 1532.553 1565.2745 1725.7540 1627.937 1698.084 3914.149 100 
    # f_989(vec2) 426.874 454.6765 546.9115 466.439 489.322 2634.383 100 
संबंधित मुद्दे

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