2013-08-08 6 views
7

संतुष्ट यह मैं मैट्रिक्स है आर कहो में returning the rows of a matrix that meet a condition पर सवाल का एक विस्तार है की पंक्तियों का चयन करने का सबसे तेज़ तरीका:आर - एक मैट्रिक्स कि कई स्थितियों

 one two three four 
[1,] 1 6 11 16 
[2,] 2 7 12 17 
[3,] 3 8 11 18 
[4,] 4 9 11 19 
[5,] 5 10 15 20 
[6,] 1 6 15 20 
[7,] 5 7 12 20 

मैं सभी पंक्तियों को वापस करना चाहते हैं, जहां matrix$two == 7 और matrix$three == 12 जितनी जल्दी हो सके। इस तरह से मैं यह करने के लिए पता है:

out <- mat[mat$two == 7,] 
final_out <- out[out$three == 12, ] 

वहाँ स्पष्ट रूप से एक एक लाइनर में final_out की सामग्री को प्राप्त करने के लिए एक विधि होना चाहिए, जैसे कुछ: final_out <- which(mat$two == 7 && mat$three == 12) तेजी से और अधिक के दो लाइन की तुलना में संक्षिप्त है कि उपरोक्त कोड

इस एकाधिक शर्त मैट्रिक्स क्वेरी को वापस करने के लिए सबसे तेज़ आर कोड क्या है?

उत्तर

11

बस तार्किक तुलना के साथ [ subsetting का उपयोग करें ...

# Reproducible data 
set.seed(1) 
m <- matrix(sample(12,28,repl=T) , 7 , 4) 
    [,1] [,2] [,3] [,4] 
[1,] 4 8 10 3 
[2,] 5 8 6 8 
[3,] 7 1 9 2 
[4,] 11 3 12 4 
[5,] 3 3 5 5 
[6,] 11 9 10 1 
[7,] 12 5 12 5 


# Subset according to condition 
m[ m[,2] == 3 & m[,3] == 12 , ] 
[1] 11 3 12 4 
1

के रूप में arr.ind=TRUE साथ उपयोग which:

> mat[which(mat[,"two"]==7 & mat[,"three"] == 12, arr.ind = TRUE),] 
    one two three four 
2 2 7 12 17 
7 5 7 12 20 
+0

या 'मैट [मैट [," दो "] == 7 और मैट [," तीन "] == 12,]' – Roland

+0

मैंने पूरी तरह से सवाल नहीं पढ़ा था और मुझे एहसास नहीं हुआ कि ओपी पहले से ही है उपयोग किया गया 'कौन सा –

+0

$ sub-सेटिंग matrices के लिए उपयुक्त है? मुझे एक त्रुटि मिलती है। – dayne

-2

आर में पूर्ण सबसे तेज़ तरीका ifelse जो if विपरीत vectorized के लिए अनुमति देता हो जाएगा सशर्त। आप सशर्त के वैक्टर भी कैश कर सकते हैं (उदा। isSeven <- mat[, 'two'] == 7) और बाद में उन का उपयोग/पुन: उपयोग करें।

मैं एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण यहाँ नहीं है, लेकिन मैं क्या करना होगा

की तरह कुछ
ifelse(mat[, 'two'] == 7 & mat[, 'three'] == 12, "both", "not both") 

तुम वहाँ में अन्य सशर्त, खटखटाने या यह कुछ भी है कि एक पक्षधर वेक्टर में परिणाम होगा वापसी हो सकती है।

+0

मुझे नहीं लगता कि 'ifelse' तार्किक सबसेटिंग से तेज़ होगा। आखिरकार, यह वही है जो 'ifelse' आंतरिक रूप से करता है। – Roland

+1

उम्म्म, दावा है कि यह सबसे तेज़ है सादा गलत है! –

3

अद्यतन MICROBENCHMARK का उपयोग:

बेंचमार्क का उपयोग करते हुए विपरीत जवाब देता है। ऐसा लगता है कि @ SimonO101 द्वारा दिया गया उत्तर थोड़ा तेज कार्यान्वयन प्रदान करता है।

require(microbenchmark) 
set.seed(1) 
m <- matrix(sample(12,100,repl=T) , 25 , 4) 
colnames(m) <- c("one","two","three","four") 

bench1 <- microbenchmark(m[which(m[,'two']==7 & m[,'three'] == 12, arr.ind = TRUE),]) 
summary(bench1$time) 
    Min. 1st Qu. Median Mean 3rd Qu. Max. 
    7700 8750 9449 9688 9800 22400 

bench2 <- microbenchmark(m[ m[,2] == 3 & m[,3] == 12 , ]) 
summary(bench2$time) 
    Min. 1st Qu. Median Mean 3rd Qu. Max. 
    6300 7350 7351 7599 8050 15400 

पुराने उत्तर:

@Jiber द्वारा और @ SimonO101 दिए गए उत्तर के संयोजन, एक थोड़ा तेजी से जवाब देता है, कम से कम अपने कंप्यूटर पर।

मैंने गणना समय को अलग करने के लिए मैट्रिक्स को बहुत बड़ा बना दिया।

set.seed(1) 
m <- matrix(sample(12,1000000000,repl=T) , 1e8 , 10) 
colnames(m) <- c("one","two","three","four","five","six","seven","eight","nine","ten") 

system.time(m[which(m[,'two']==7 & m[,'three'] == 12, arr.ind = TRUE),]) 
    user system elapsed 
    6.49 1.58 8.06 
system.time(m[ m[,2] == 3 & m[,3] == 12 , ]) 
    user system elapsed 
    8.23 1.29 9.52 

यह स्पष्ट रूप से मानता है कि मैट्रिक्स कॉलम का नाम है।

+1

आपको समय की गणना के लिए 'लाइब्रेरी (माइक्रोबेंमार्क) 'का उपयोग करना चाहिए ... यह अधिक विश्वसनीय है। टिप के लिए – Thomas

+0

@ थॉमस धन्यवाद। यह बेंचमार्किंग पर मेरा पहला प्रयास था। पैकेज स्थापित करने के बाद मैं जवाब अपडेट कर दूंगा। – dayne

+0

इसमें थोड़ी देर लग सकती है ... एसओ के आसपास देखो, आप अन्य उदाहरण देखेंगे कि लोग इसका उपयोग कैसे करते हैं। – Thomas

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