आर के ifelse स्टेटमेंट वैक्टर वापस क्यों नहीं कर सकते?


118

मुझे समय-समय पर बहुत आसान होने के लिए आर के ifelse स्टेटमेंट मिले हैं। उदाहरण के लिए:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

लेकिन मैं निम्नलिखित व्यवहार से कुछ उलझन में हूं।

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

क्या यह एक डिज़ाइन विकल्प है जो मेरे भुगतान से ऊपर है?


1
ifelse के लिए थोड़ा अजीब डिजाइन ने इस तथ्य को देखते हुए कि सरल काम करता है।
2sb

4
ifelse एक वेक्टरकृत फ़ंक्शन है। उनका उपयोग विभिन्न कार्यों के लिए किया जाना चाहिए।
मर्बेल

जवाबों:


99

ifelseराज्यों के लिए प्रलेखन :

ifelseउसी आकार के साथ एक मान देता है, testजो yesया तो से चयनित तत्वों से भरा होता है या noइस पर निर्भर करता है कि तत्व testहै TRUEया FALSE

जब से आप लंबाई 1 का परीक्षण मान पास कर रहे हैं, तो आपको लंबाई के परिणाम मिल रहे हैं। 1. यदि आप लंबे समय तक टेस्ट वैक्टर पास करते हैं, तो आपको लंबे परिणाम मिलेंगे:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

तो ifelseबूलियन्स के वेक्टर का परीक्षण करने और उसी लंबाई के वेक्टर को वापस करने के विशिष्ट उद्देश्य के लिए अभिप्रेत है, (वेक्टर) yesऔर noतर्कों से लिए गए तत्वों से भरा हुआ ।

यह एक सामान्य भ्रम है, क्योंकि फ़ंक्शन का नाम, इस का उपयोग करने के लिए जब वास्तव में आप if () {} else {}इसके बजाय सिर्फ एक सामान्य निर्माण चाहते हैं ।


16
शायद आप वास्तव में बयानों के दूसरे सेट के लिए क्या चाहते थे if (TRUE) c(1,2) else c(3,4)
जोनाथन चांग

69

मुझे यकीन है कि आप ifइसके बजाय एक साधारण बयान चाहते हैं ifelse- आर में, ifबस एक नियंत्रण-प्रवाह संरचना नहीं है, यह एक मूल्य वापस कर सकता है:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4

@, यह मेरे लिए काम करता है, भले ही मुझे वह मिल जाए जो मुझे लगातार चेतावनी की आवश्यकता है " Warning in if (req(inputval) == "All") { : the condition has length > 1 and only the first element will be used"मुझे इस चेतावनी से छुटकारा पाने के लिए क्या करना चाहिए?
user5249203

1
@ user5249203, सवाल और केन का उत्तर उस मामले को संदर्भित करता है जहां हालत एक मूल्य है, अर्थात, लंबाई का एक वेक्टर 1. चेतावनी इंगित करती है कि req(inputval)इसमें अधिक तत्व हैं। एकल मान प्राप्त करने के लिए फ़ंक्शन any()या all()उपयोगी हो सकता है।
Uwe

12

ध्यान दें कि यदि आप परिणाम को अंदर रखते हैं, तो आप समस्या को दरकिनार कर सकते हैं ifelse:

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4

3
IMHO, यह असाइनमेंट के लिए ifelse()एक नियंत्रण प्रवाह के स्थान पर वेक्टरकृत फ़ंक्शन का दुरुपयोग करने के लिए प्रोत्साहित कर रहा है if ... else ...। अगर हालत एक TRUEया FALSEमूल्य है, तो मैं लिखना पसंद करूंगा a <- if (TRUE) c(1,2) else c(3,4)याif (TRUE) a <- c(1,2) else a <- c(3,4)
Uwe

1
@ हालांकि, मुझे लगता है कि प्रदर्शन में अंतर नहीं है ... का उपयोग ifelseकरते समय if... elseएक ही स्थिति के मामले में वास्तव में एक समस्या ifelseहो सकती है और कोड के अंदर कुछ मामलों में पसंद किया जा सकता है (सरल अनुमान यहाँ), मैं आपसे असहमत नहीं हो सकता ;-)। मैं सिर्फ एक रास्ता दिखाना चाहता था ifelse
कैथ

9

हाँ, मुझे लगता है कि ifelse () वास्तव में तब होता है जब आपके पास परीक्षणों का एक बड़ा लंबा वेक्टर होता है और प्रत्येक को दो विकल्पों में से एक के लिए मैप करना चाहते हैं। उदाहरण के लिए, मैं अक्सर इस तरह से प्लॉट () के लिए रंग करता हूं:

plot(x,y, col = ifelse(x>2,  'red', 'blue'))

आप परीक्षण का एक बड़ा लंबा वेक्टर था, लेकिन आउटपुट के लिए जोड़े चाहते हैं तो आपके इस्तेमाल कर सकते हैं sapply()या plyrके llply()या कुछ और शायद,।


4

कभी-कभी उपयोगकर्ता को switchइसके बजाय एक बयान की आवश्यकता होती है ifelse। उस स्तिथि में:

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

(जो केन विलियम्स के उत्तर का एक और वाक्यविन्यास विकल्प है)


4

यहां कैथ द्वारा सुझाए गए दृष्टिकोण के समान है, लेकिन यह मौजूदा प्री-असाइन किए गए वैक्टर के साथ काम कर सकता है

यह ऐसा उपयोग करने के आसपास आधारित get()है:

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2

4

`if` का उपयोग करें, उदा

> `if`(T,1:3,2:4)
[1] 1 2 3

यह यहाँ एकमात्र उत्तर है जो वास्तव में ifelse की अपेक्षित कार्यक्षमता प्रदान कर सकता है।
sus_mlm

2

आपके मामले में, का उपयोग कर if_elseसे dplyrउपयोगी हो गया होता: if_elseअधिक से अधिक सख्त है ifelse, और अपने मामले के लिए एक त्रुटि फेंकता है:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2

0

हर पृष्ठभूमि पर मिला :

ifelse(rep(TRUE, length(c(1,2))), c(1,2),c(3,4))
#>[1] 1 2

वांछित लंबाई वापस करने के लिए अपनी स्थिति का परिणाम दोहरा सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.