हम भी कर सकता है:
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
भी देखें: [नियमित रूप से, लगातार दृश्यों के समूहों में एक सदिश विभाजन कैसे?] (Http: //stackoverflow.com/questions/5222061/how-to-partition-a-vec नियमित रूप से लगातार अनुक्रमों के टोर-इन-ग्रुप) – Henrik
... जो मुझे विश्वास है कि 'cumsum (... diff (...' idiom के लिए एक अच्छा, कैनोलिक पोस्ट है। – Henrik