2012-01-12 12 views
6

जबकि आर के ifelse अविश्वसनीय रूप से आसान है, यह एक विशेष कमी है के लिए खोज रहे: कॉल ifelse(test, yes, no) में yes और no के सभी तत्वों मूल्यांकन किया जाता है, यहां तक ​​कि उन है कि दूर फेंक दिया जाएगा।एक अधिक कुशल ifelse()

यह नहीं बल्कि बेकार है आप एक जटिल संख्यात्मक व्यायाम के बीच में यह उपयोग कर रहे हैं, एक समारोह है कि integrate, uniroot, optim या जो कुछ भी करने के लिए खिलाया जा जाएगा में कहते हैं। उदाहरण के लिए, एक

ifelse(test, f(x, y, z), g(a, b, c)) 

हो सकता है जहां f और g मनमाने ढंग से जटिल या धीमी गति से कार्य हैं, संभवतः अधिक नेस्टेड ifelse के शामिल हैं।

क्या किसी ने ifelse के लिए एक प्रतिस्थापन लिखा है जो केवल yes/no के तत्वों का मूल्यांकन करता है जो रखा जाएगा? असल में,

out <- test 
for(i in seq_along(out)) 
{ 
    if(test[i]) out[i] <- f(x[i], y[i], z[i]) 
    else out[i] <- g(a[i], b[i], c[i]) 
} 

की रेखाओं के साथ कुछ लेकिन स्पष्ट लूप की अड़चन/अक्षमता के बिना कुछ। आर के अंदरूनी भाग के बिना यह भी संभव है?

+1

मुझे लगता है कि मैं * स्पष्ट लूप का उपयोग कर सकता हूं, लेकिन फिर मुझे लगता है कि मैं पुरानी कहानियों का पालन कर रहा हूं कि एक निर्धारित प्रोग्रामर किसी भी भाषा में फोरट्रान लिख सकता है .... –

+1

आवेदन का उपयोग करने के बारे में कैसे? तो प्रत्येक तत्व के लिए ifelse() का मूल्यांकन किया जाता है, और इसी तरह 'हां' और 'नो को केवल प्रासंगिक तत्वों के लिए मूल्यांकन किया जाता है, जब तक कि मेरी समझ की समझ गलत न हो, लेकिन मुझे यकीन है कि पिछले – nzcoops

+0

I में मेरे लिए काम किया गया है। अगर() - और, के साथ 'mapply' का उपयोग करने की कोशिश की, और वे vectorised 'ifelse' से 10 गुना धीमी थी! –

उत्तर

6

मुझे नहीं लगता कि समस्या ifelse है। f और g केवल आपकी अभिव्यक्ति में मूल्यांकन किया जा रहा है। मुझे लगता है कि आपकी समस्या यह है कि f और g वैक्टर के साथ धीमे हैं।

आप कॉल को f और g पर बदल सकते हैं ताकि वे केवल वेक्टर के उप-समूह पर मूल्यांकन कर सकें।

out <- numeric(length(test)) #or whatever the output type is 
out[test] <- f(x[test], y[test], z[test]) 
out[!test] <- g(x[!test], y[!test], z[!test]) 

आप इस समायोजित करने के लिए करता है, तो test के किसी भी तत्व NA हैं की आवश्यकता होगी।

+0

हां, मैंने यह भी किया है, लेकिन यह बल्कि बोझिल है। –

+4

यदि 'f' और' g' सभी वेक्टर किए गए हैं, तो यह आपका सबसे अच्छा विकल्प है। यदि नहीं तो किसी भी तरह का पाश करेगा। और यदि आपको लगता है कि यह बदसूरत कोड है (जो काफी उचित है) तो आप इसे हमेशा एक फ़ंक्शन में लपेट सकते हैं और इसे उस फ़ाइल में छुपा सकते हैं जिसे आप अक्सर नहीं देखते हैं। –

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