2011-10-05 11 views
7

एक previous post मुझे इस प्रश्न पोस्ट करने के लिए प्रेरित किया। यह == से isTRUE(all.equal()) (और != से !isTRUE(all.equal()) पर पुन: असाइन करने के लिए एक सर्वोत्तम अभ्यास की तरह प्रतीत होता है। मुझे आश्चर्य है कि अन्य लोग अभ्यास में ऐसा करते हैं? मुझे अभी एहसास हुआ कि मैं == और != का उपयोग अपने कोडबेस में संख्यात्मक समानता करने के लिए करता हूं। मेरी पहली प्रतिक्रिया था कि मैं एक पूर्ण साफ़ करते हैं और all.equal में बदलने की जरूरत है। लेकिन वास्तव में, हर मैं उपयोग == और != मैं समानता (डेटाप्रकार की परवाह किए बिना) परीक्षण करना चाहते हैं। वास्तव में, मुझे यकीन है कि क्या इन आपरेशनों का परीक्षण होगा नहीं कर रहा हूँ समानता के अलावा अन्य के लिए। मुझे यकीन है कि मैं कुछ अवधारणा यहाँ याद कर रहा हूँ कर रहा हूँ। किसी ने मुझे प्रबुद्ध कर सकते हैं? केवल तर्क मैं इस दृष्टिकोण के खिलाफ देखना कि कुछ मामलों में दो गैर समान संख्या की सहनशीलता की वजह से समान होना दिखाई देगा all.equal। लेकिन हमें बताया गया है कि दो संख्याएं जो वास्तव में समान हैंपास नहीं हो सकती हैंकी वजह से वे स्मृति में कैसे संग्रहीत हैं। तो वास्तव में all.equal पर डिफ़ॉल्ट नहीं होने का क्या मतलब है?क्या आप == और! = IstrUE (all.equal()) को पुनः निर्दिष्ट करते हैं?

+0

कि ऐसा करने के लिए इस तरह के एक अजीब बात यह तरह लग रहा था, तो मैं तुलना मदद पृष्ठ में नोट पढ़ें: "का प्रयोग न करें == और = इस तरह के भाव अगर में के रूप में परीक्षण, के लिए, जहाँ आप एक मिल जाना चाहिए! एकल सत्य या गलत। जब तक आप पूरी तरह से सुनिश्चित नहीं हैं कि असामान्य कुछ भी नहीं हो सकता है, तो आपको इसके बजाय समान कार्य का उपयोग करना चाहिए। " तो शायद यह बेवकूफ एक विचार नहीं है। –

+3

मैं नहीं कहने जा रहा हूं, आपको नहीं करना चाहिए। इसके बजाय 'समान' का उपयोग करें, और सब्सक्रिप्शन करते समय वेक्टरीकृत तुलनाओं के लिए '==' रखें। – joran

+3

यदि आप सामान्य ऑपरेटरों को ओवरलोड करना शुरू करते हैं, तो आपका कोड गंभीर रूप से गैर-पोर्टेबल होगा। सीखने के लिए बेहतर है कि प्रत्येक ऑपरेटर या फ़ंक्शन क्या करता है और सही नौकरी के लिए सही टूल का उपयोग करता है। –

उत्तर

7

जैसा कि @ जोरन ने बताया है, आप == और != के साथ फ्लोटिंग पॉइंट समस्याओं में बहुत अधिक किसी भी भाषा में भाग लेंगे। आर में उनमें से एक महत्वपूर्ण पहलू वेक्टरेशन हिस्सा है।

यह एक नया फ़ंक्शन almostEqual, fuzzyEqual या इसी तरह के परिभाषित करने के लिए बेहतर होगा। यह दुर्भाग्यपूर्ण है कि ऐसा कोई आधार कार्य नहीं है। all.equal बहुत ही कुशल है, क्योंकि यह वस्तुओं के सभी प्रकार संभालती है और एक स्ट्रिंग रिटर्न अंतर का वर्णन जब ज्यादातर तुम सिर्फ TRUE या FALSE चाहते नहीं है।

यहां इस तरह के एक समारोह का एक उदाहरण है। यह == की तरह सदिश है।

almostEqual <- function(x, y, tolerance=1e-8) { 
    diff <- abs(x - y) 
    mag <- pmax(abs(x), abs(y)) 
    ifelse(mag > tolerance, diff/mag <= tolerance, diff <= tolerance) 
} 

almostEqual(1, c(1+1e-8, 1+2e-8)) # [1] TRUE FALSE 

... यह all.equal की तुलना में तेजी 2x आसपास अदिश मूल्यों के लिए, और वैक्टर के साथ बहुत तेजी से है।

x <- 1 
y <- 1+1e-8 
system.time(for(i in 1:1e4) almostEqual(x, y)) # 0.44 seconds 
system.time(for(i in 1:1e4) all.equal(x, y)) # 0.93 seconds 
+0

टॉमी - कुछ परीक्षणों के बाद मुझे लगता है कि इस फ़ंक्शन में एक बग है। विचार करें: matrixa = round (मैट्रिक्स (rnorm (9), nrow = 3, ncol = 3), 6) matrixb = matrixa - .001 लगभग एक्वाल (मैट्रिक्स, मैट्रिक्सब, सहिष्णुता = .001) – SFun28

+0

यहां तक ​​कि यह कभी-कभी गलत होता है: लगभग एक्वाल (मैट्रिक्स, मैट्रिक्सब, सहिष्णुता = .01) – SFun28

+0

@ एसएफयू 28 - मुझे लगता है कि कोड सही है। इसके बजाए 'all.equal' आज़माएं और आपको गैर-सत्य भी मिलें। ऐसा इसलिए है क्योंकि यह एक रिश्तेदार सहिष्णुता है।'rnorm' बड़ी (3.5) या छोटी (0.0003) संख्या दे सकता है, लेकिन मैट्रिक्सब में जो भी त्रुटि आप जोड़ते हैं वह हमेशा' 0.001' है। इसके बजाए 'matrixb <- matrixa * 1.001' आज़माएं। – Tommy

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