दिलचस्प पोस्ट
अभिगम नियंत्रण-अनुमति-उत्पत्ति द्वारा मूल नल की अनुमति नहीं है "Exec sp_reset_connection" का मतलब क्या एसक्यूएल सर्वर प्रोफाइलर में है? `इनआईटीसीआर 'नर्सस के लिए अपरिभाषित संदर्भ क्यों चरित्र '^' को नजरअंदाज कर दिया है पायथन पापेन – कैसे Popen विंडोज में '^' चरित्र से बचने के लिए? Tensorflow: कैसे बदलें या ढाल को संशोधित करें? आईओएस टेस्ट / ऐपिस टीडीडी / बीडीडी और इंटीग्रेशन और स्वीकार्य टेस्टिंग क्रॉस डोमेन अनुरोध कैसे करें आर और जीजीप्लोट 2 का उपयोग करके पिरामिड प्लॉट का चित्रण करना हाइव में अपडेट, SET विकल्प ब्लैकबेरी SQLite डेटाबेस निर्माण: "फाइल सिस्टम तैयार नहीं है" क्या ब्राउज़रों 'एफ 5' और 'Ctrl + F5' रिफ्रेश उत्पन्न करते हैं? मैं एसक्यूएल सर्वर में INNER JOIN का उपयोग कर एक से अधिक तालिकाओं से कैसे हटाऊं? AngularJS डेटा परिवर्तन के लिए वस्तुओं की घड़ी सरणी मैं एक अतिप्रवाह विभाग के भीतर किसी तत्व को कैसे स्क्रॉल कर सकता हूं? Javascript console.log कैप्चर कर रहा है?

नियमित, लगातार अनुक्रमों के समूहों में एक वेक्टर को कैसे विभाजित किया जाए?

मेरे पास एक सदिश है, जैसे कि c(1, 3, 4, 5, 9, 10, 17, 29, 30) और मैं एक साथ 'पड़ोसी' तत्वों को एक साथ समूह करना चाहता हूं जो एक नियमित, सख़्त सदिश में लगातार अनुक्रम बनाते हैं जिसके परिणामस्वरूप:

एल 1: 1
L2: 3,4,5
एल 3: 9, 10
एल 4: 17
एल 5: 29,30

निष्पक्ष कोड (एक पूर्व सी प्रोग्रामर का):

 partition.neighbors <- function(v) { result <<- list() #jagged array currentList <<- v[1] #current series for(i in 2:length(v)) { if(v[i] - v [i-1] == 1) { currentList <<- c(currentList, v[i]) } else { result <<- c(result, list(currentList)) currentList <<- v[i] #next series } } return(result) } 

अब मैं समझता हूं कि

ए) आर सी नहीं है (घुंघराले ब्रैकेट के बावजूद)
बी) वैश्विक चर शुद्ध बुराई हैं
ग) यह परिणाम प्राप्त करने का एक बहुत ही अकुशल तरीका है

, इसलिए किसी भी बेहतर समाधान का स्वागत है

Solutions Collecting From Web of "नियमित, लगातार अनुक्रमों के समूहों में एक वेक्टर को कैसे विभाजित किया जाए?"

कुछ आर मुहावरों का भारी उपयोग करना:

 > split(v, cumsum(c(1, diff(v) != 1))) $`1` [1] 1 $`2` [1] 3 4 5 $`3` [1] 9 10 $`4` [1] 17 $`5` [1] 29 30 

डार्कोज़िग लिखते हैं, "आप अलग-अलग आधार पर एक बहुत नीपर कोड लिख सकते हैं …"

यहां एक तरीका है:

 split(v, cumsum(diff(c(-Inf, v)) != 1)) 

संपादित करें (जोड़ा गया समय):

टॉमी ने यह पता लगाया कि यह प्रकार के साथ सावधान रहकर तेजी से हो सकता है; इसका कारण यह तेजी से बढ़ता है कि split पूर्णांक पर तेजी से होता है, और वास्तव में अभी भी कारकों पर तेजी से बढ़ रहा है।

यहां यहोशू के समाधान हैं; cumsum से परिणाम एक संख्यात्मक है क्योंकि यह 1 साथ c घ है, इसलिए यह सबसे धीमा है।

 system.time({ a <- cumsum(c(1, diff(v) != 1)) split(v, a) }) # user system elapsed # 1.839 0.004 1.848 

बस 1L साथ 1L इसलिए परिणाम एक पूर्णांक गति काफी ऊपर है

 system.time({ a <- cumsum(c(1L, diff(v) != 1)) split(v, a) }) # user system elapsed # 0.744 0.000 0.746 

संदर्भ के लिए यह टॉमी का समाधान है; यह भी एक पूर्णांक पर विभाजित है

 > system.time({ a <- cumsum(c(TRUE, diff(v) != 1L)) split(v, a) }) # user system elapsed # 0.742 0.000 0.746 

यहाँ मेरा मूल समाधान है; यह भी एक पूर्णांक पर विभाजित है

 system.time({ a <- cumsum(diff(c(-Inf, v)) != 1) split(v, a) }) # user system elapsed # 0.750 0.000 0.754 

यहां पर यहोशू का परिणाम है, जिसके फलस्वरूप परिणाम split होने से पहले पूर्णांक में परिवर्तित split

 system.time({ a <- cumsum(c(1, diff(v) != 1)) a <- as.integer(a) split(v, a) }) # user system elapsed # 0.736 0.002 0.740 

पूर्णांक वेक्टर पर split सभी संस्करण उसी के समान हैं; यह भी तेज हो सकता है कि पूर्णांक वेक्टर पहले से ही एक कारक था, क्योंकि पूर्णांक से फर्क करने के लिए वास्तव में लगभग आधा समय लगता है। यहां मैं इसे सीधे एक कारक में बना देता हूं; यह सामान्य रूप में अनुशंसित नहीं है क्योंकि यह कारक वर्ग की संरचना पर निर्भर करता है। यह सिर्फ तुलनात्मक प्रयोजनों के लिए किया गया है

 system.time({ a <- cumsum(c(1L, diff(v) != 1)) a <- structure(a, class = "factor", levels = 1L:a[length(a)]) split(v,a) }) # user system elapsed # 0.356 0.000 0.357 

यहोशू और हारून पर मौजूद थे हालांकि, उनके कोड को सही प्रकार, पूर्णांक और तार्किकों के सावधान उपयोग से दो बार तेज़ी से अधिक बनाया जा सकता है:

 split(v, cumsum(c(TRUE, diff(v) != 1L))) v <- rep(c(1:5, 19), len = 1e6) # Huge vector... system.time( split(v, cumsum(c(1, diff(v) != 1))) ) # Joshua's code # user system elapsed # 2.64 0.00 2.64 system.time( split(v, cumsum(c(TRUE, diff(v) != 1L))) ) # Modified code # user system elapsed # 1.09 0.00 1.12 

आप एक data.frame बना सकते हैं और तत्वों को diff , ifelse और cumsum का उपयोग करके समूहों को असाइन कर सकते हैं, तो कुल मिलाकर उपयोग कर tapply :

 v.df <- data.frame(v = v) v.df$group <- cumsum(ifelse(c(1, diff(v) - 1), 1, 0)) tapply(v.df$v, v.df$group, function(x) x) $`1` [1] 1 $`2` [1] 3 4 5 $`3` [1] 9 10 $`4` [1] 17 $`5` [1] 29 30 

आप कट-अंक आसानी से परिभाषित कर सकते हैं:

 which(diff(v) != 1) 

उस प्रयास के आधार पर:

 v <- c(1,3,4,5,9,10,17,29,30) cutpoints <- c(0, which(diff(v) != 1), length(v)) ragged.vector <- vector("list", length(cutpoints)-1) for (i in 2:length(cutpoints)) ragged.vector[[i-1]] <- v[(cutpoints[i-1]+1):cutpoints[i]] 

जिसके परिणामस्वरूप:

 > ragged.vector [[1]] [1] 1 [[2]] [1] 3 4 5 [[3]] [1] 9 10 [[4]] [1] 17 [[5]] [1] 29 30 

यह एल्गोरिदम एक अच्छा नहीं है, लेकिन आप diff के आधार पर एक बहुत नीपर कोड लिख सकते हैं 🙂 गुड लक!