2012-06-12 11 views
10

में मैच के सूचकांक प्राप्त करने की फास्ट तरह से, मैं a में सूचकांक युक्त b के बराबर लंबाई का एक वेक्टर प्राप्त करना चाहते हैं जहां b मैचों (यह एक बुरा स्पष्टीकरण मुझे पता है) में तत्व ...एक सूची असमान लंबाई की <code>a</code> युक्त वैक्टर और एक वेक्टर <code>b</code><code>a</code> में वैक्टर से कुछ तत्वों से युक्त यह देखते हुए सूची

निम्नलिखित कोड काम करता है:

a <- list(1:3, 4:5, 6:9) 
b <- c(2, 3, 5, 8) 

sapply(b, function(x, list) which(unlist(lapply(list, function(y, z) z %in% y, z=x))), list=a) 
[1] 1 1 2 3 

पाश के लिए एक साथ sapply की जगह Cours का एक ही प्राप्त होता है ई

समस्या यह है कि इस कोड का उपयोग 1000 से ऊपर की लंबाई वाले सूची और वैक्टर के साथ किया जाएगा। वास्तविक जीवन सेट पर फ़ंक्शन लगभग 15 सेकंड (लूप और sapply दोनों) के लिए होता है।

क्या किसी को यह पता है कि इसे कैसे गति देना है, समानांतर दृष्टिकोण के लिए सुरक्षित है? मैं एक सदिश दृष्टिकोण देखने में असफल रहा हूं (और मैं सी में प्रोग्राम नहीं कर सकता, हालांकि यह शायद सबसे तेज़ होगा)।

संपादित करें:

सिर्फ हारून के सुरुचिपूर्ण समाधान का उपयोग कर मैच() जो 1667 बार (15 से 0.009 के लिए)

के क्रम में एक गति वृद्धि मैं करने के लिए उस पर थोड़ा विस्तार दिया जोर देना होगा कई मैचों की अनुमति देते हैं (वापसी तो एक सूची है)

a <- list(1:3, 3:5, 3:7) 
b <- c(3, 5) 
g <- rep(seq_along(a), sapply(a, length)) 
sapply(b, function(x) g[which(unlist(a) %in% x)]) 
[[1]] 
[1] 1 2 3 

[[2]] 
[1] 2 3 

इस के लिए क्रम 0.169 था जो यकीनन काफी धीमी है, लेकिन दूसरी ओर अधिक लचीला

०१२३५१६४१० पर
+2

क्या आप कलन विधि क्या करना चाहते हैं 'b' का एक तत्व' A' के एक से अधिक तत्व में प्रकट होता है, तो क्या ज़रूरत है? क्या यह आपकी वास्तविक समस्या में संभव है? –

+0

मुझे यह निर्दिष्ट करना चाहिए था कि ... यह संभावना नहीं है – ThomasP85

उत्तर

12

यहाँ एक संभावना match का उपयोग कर रहा है:

> a <- list(1:3, 4:5, 6:9) 
> b <- c(2, 3, 5, 8) 
> g <- rep(seq_along(a), sapply(a, length)) 
> g[match(b, unlist(a))] 
[1] 1 1 2 3 

findInterval एक और विकल्प है:

> findInterval(match(b, unlist(a)), cumsum(c(0,sapply(a, length)))+1) 
[1] 1 1 2 3 

एक सूची लौटने के लिए, इस प्रयास करें:

a <- list(1:3, 4:5, 5:9) 
b <- c(2,3,5,8,5) 
g <- rep(seq_along(a), sapply(a, length)) 
aa <- unlist(a) 
au <- unique(aa) 
af <- factor(aa, levels=au) 
gg <- split(g, af) 
gg[match(b, au)] 
+0

15 सेकंड से 0.00 9 तक - यह एक प्रभावशाली सुधार है। मुझे पता चला कि मैं वास्तव में वेक्टर की बजाय एक सूची वापस करना चाहता हूं, ताकि यह कई मैचों को संभाल सके। मैंने इसे प्राप्त करने के लिए sapply (बी, फ़ंक्शन (एक्स) जी [जो (अनलिस्ट (ए)%% x में) के साथ अपने पहले सुझाव में अंतिम पंक्ति को प्रतिस्थापित किया है।] रन टाइम तब 0.169 था, जो आपके मुकाबले काफी धीमा है लेकिन अभी भी एक बड़ा सुधार है। – ThomasP85

0

के रूप में अपनी पोस्ट के लिए एक टिप्पणी से पता चलता है , यहमें एकाधिक वैक्टरों में समान तत्व दिखाई देने पर आप क्या करना चाहते हैं, इस पर निर्भर करता है। यह मानते हुए कि आप सबसे कम सूचकांक तुम कर सकते हो चाहता हूँ:

apply(sapply(a, function(vec) {b %in% vec}), 1, which.max)