@ फैबियन-वर्नर द्वारा प्रदान किया गया उत्तर बहुत अच्छा है, लेकिन वस्तुओं में कई कक्षाएं हो सकती हैं, और "कारक" जरूरी नहीं कि पहले एक द्वारा लौटा जा सकता है class(yes)
, इसलिए मैं सभी वर्ग विशेषताओं की जांच करने के लिए इस छोटे संशोधन का सुझाव देता हूं:
safe.ifelse <- function(cond, yes, no) {
class.y <- class(yes)
if ("factor" %in% class.y) { # Note the small condition change here
levels.y = levels(yes)
}
X <- ifelse(cond,yes,no)
if ("factor" %in% class.y) { # Note the small condition change here
X = as.factor(X)
levels(X) = levels.y
} else {
class(X) <- class.y
}
return(X)
}
मैंने आर डेवलपमेंट टीम के साथ आधार :: ifelse () संरक्षित करने के लिए उपयोगकर्ता के चयन के आधार पर एक डॉक्यूमेंटेड विकल्प जोड़ने के लिए एक अनुरोध प्रस्तुत किया है, जिसमें विशेषताओं को संरक्षित करना है। निवेदन यहाँ है: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=1669 - यह पहले से ही इस आधार पर "WONTFIX" के रूप में फ़्लैग किया गया है कि यह हमेशा से अब है, लेकिन मैंने एक अनुवर्ती तर्क प्रदान किया है कि क्यों एक साधारण जोड़ बहुत सारे आर उपयोगकर्ताओं को सिरदर्द से बचा सकता है। शायद उस बग थ्रेड में आपका "+1" आर कोर टीम को दूसरा रूप लेने के लिए प्रोत्साहित करेगा।
EDIT: यहां एक बेहतर संस्करण है जो उपयोगकर्ता को यह निर्दिष्ट करने की अनुमति देता है कि कौन से विशेषताओं को संरक्षित करना है, या तो "cond" (डिफ़ॉल्ट ifelse () व्यवहार), "हां", उपरोक्त कोड के अनुसार व्यवहार, या "no", उन मामलों के लिए जहां "नहीं" मान के गुण बेहतर हैं:
safe_ifelse <- function(cond, yes, no, preserved_attributes = "yes") {
# Capture the user's choice for which attributes to preserve in return value
preserved <- switch(EXPR = preserved_attributes, "cond" = cond,
"yes" = yes,
"no" = no);
# Preserve the desired values and check if object is a factor
preserved_class <- class(preserved);
preserved_levels <- levels(preserved);
preserved_is_factor <- "factor" %in% preserved_class;
# We have to use base::ifelse() for its vectorized properties
# If we do our own if() {} else {}, then it will only work on first variable in a list
return_obj <- ifelse(cond, yes, no);
# If the object whose attributes we want to retain is a factor
# Typecast the return object as.factor()
# Set its levels()
# Then check to see if it's also one or more classes in addition to "factor"
# If so, set the classes, which will preserve "factor" too
if (preserved_is_factor) {
return_obj <- as.factor(return_obj);
levels(return_obj) <- preserved_levels;
if (length(preserved_class) > 1) {
class(return_obj) <- preserved_class;
}
}
# In all cases we want to preserve the class of the chosen object, so set it here
else {
class(return_obj) <- preserved_class;
}
return(return_obj);
} # End safe_ifelse function
if_else()
dplyr पैकेज में एक फंक्शन है जोifelse
डेट ऑब्जेक्ट्स की सही कक्षाओं को बनाए रखते हुए स्थानापन्न कर सकता है - यह एक हालिया उत्तर के रूप में नीचे पोस्ट किया गया है । मैं यहाँ इस पर ध्यान आकर्षित कर रहा हूँ क्योंकि यह इस समस्या को हल करता है जो कि एक यूनिट परीक्षण है और एक CRAN पैकेज में प्रलेखित है, कई अन्य उत्तरों के विपरीत जो (इस टिप्पणी के अनुसार) इसके आगे रैंक किए गए थे।