I wanted to follow up. A more careful reading of the following: "A vector of the same length and attributes (including dimensions and "class") as test..."
So the above **refers only to a "class" attribute that appears among the attributes of test and result**. Using my previous example, note that: z <- c(TRUE,TRUE,FALSE) > attributes(z) NULL ## so no 'class' among attributes(z) ## However > class(z) ## S3 class [1] "logical" ## Similarly > w <- ifelse(z,5,'a') > attributes(w) NULL ## so no 'class' among attributes(w) > class(w) ##S3 class [1] "character" So my (anyway) confusion stems from conflating the S3 'class' of the object with a "class" attribute, of which there is none. Nevertheless, I believe that the phrase I suggested (or something along those lines) might clarify how the S3 class is determined and perhaps better distinguish it from a "class" attribute among the attributes, if there there is such. Or maybe that part of the doc should just be removed. My guess is that this documentation has been around for a long time and no one has gotten around to revising it once S3 classes came into wider use. ... or saw the need to revise it, anyway. -- Bert " On Mon, Oct 24, 2022 at 9:30 AM Bert Gunter <bgunter.4...@gmail.com> wrote: > > "...but 'same length and attributes (including dimensions and > ‘"class"’) as ‘test’' looks wrong. The output seems to be `logical` or > something related to the classes of `yes` & `no`." > > The documentation in fact says: > "A vector of the same length and attributes (including dimensions and > "class") as test and data values from the values of yes or no. **The > mode of the answer will be coerced from logical to accommodate first > any values taken from yes and then any values taken from no.** > > So the values are taken from 'yes' and 'no' (with coercion if they are > of different classes), and the class of the result will presumably be > inferred from the mode of those values. e.g. > > > z <- c(TRUE,TRUE,FALSE) > > class(z) > [1] "logical" > > w <- ifelse(z,5,'a') > > class(w) > [1] "character" ## note coercion > > So it would appear that the ifelse() documentation needs to be > clarified. For example, if the above asterisked phrase were "The S3 > *class* of the answer will be inferred from the mode, where the mode > of the answer will be coerced ..." that might resolve at least that > bit of confusion However, that might also be incorrect -- what about > S4 vs S3 vs Reference classes, for example (are such cases even > possible?)? I leave resolution of these matters -- or at least their > accurate and complete documentation -- to wiser heads. > > Cheers, > Bert > > > > > On Mon, Oct 24, 2022 at 8:45 AM Jorgen Harmse via R-help > <r-help@r-project.org> wrote: > > > > There were several interesting points about `ifelse`. The usual behaviour > > seems to be that all three inputs are evaluated, and the entries of `yes` > > corresponding to `TRUE` in `test` are combined with the entries of `no` > > corresponding to `FALSE` in `test`. Moreover, `yes` & `no` seem to be > > recycled as necessary in case `test` is longer. On top of that, there seems > > to be some sugar that suppresses evaluations in case `all(test)` and/or > > `all(!test)`, and the return type can be `logical` even if `yes` & `no` are > > not. I agreed with the other responses already, but my experiments further > > confirmed that `ifelse` is not interchangeable with `if(....) .... else > > ....`. > > > > > > > > The documentation confirms most of this, but 'same length and attributes > > (including dimensions and ‘"class"’) as ‘test’' looks wrong. The output > > seems to be `logical` or something related to the classes of `yes` & `no`. > > > > > > > > Regards, > > > > Jorgen Harmse. > > > > > > > > > ifelse(FALSE, {cat("Evaluating the vector for 'if'.\n"); 1:3}, > > > {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > Evaluating the vector for 'else'. > > > > [1] 0 > > > > > ifelse(rep(FALSE,5L), {cat("Evaluating the vector for 'if'.\n"); 1:3}, > > > {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > Evaluating the vector for 'else'. > > > > [1] 0 1 2 3 4 > > > > > ifelse(rep(TRUE,3L), {cat("Evaluating the vector for 'if'.\n"); 1:3}, > > > {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > Evaluating the vector for 'if'. > > > > [1] 1 2 3 > > > > > ifelse(c(TRUE,TRUE,FALSE), {cat("Evaluating the vector for 'if'.\n"); > > > 1:3}, {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > Evaluating the vector for 'if'. > > > > Evaluating the vector for 'else'. > > > > [1] 1 2 2 > > > > > ifelse(c(TRUE,TRUE,FALSE,TRUE), {cat("Evaluating the vector for > > > 'if'.\n"); 1:3}, {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > Evaluating the vector for 'if'. > > > > Evaluating the vector for 'else'. > > > > [1] 1 2 2 1 > > > > > args(ifelse) > > > > function (test, yes, no) > > > > NULL > > > > > ifelse(c(TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,TRUE), {cat("Evaluating the > > > vector for 'if'.\n"); 1:3}, {cat("Evaluating the vector for 'else'.\n"); > > > 0:4}) > > > > Evaluating the vector for 'if'. > > > > Evaluating the vector for 'else'. > > > > [1] 1 2 2 1 2 0 1 > > > > > ifelse(logical(0L), {cat("Evaluating the vector for 'if'.\n"); 1:3}, > > > {cat("Evaluating the vector for 'else'.\n"); 0:4}) > > > > logical(0) > > > > > ifelse(TRUE, integer(0L), numeric(0L)) > > > > [1] NA > > > > > class(ifelse(TRUE, integer(0L), numeric(0L))) > > > > [1] "integer" > > > > > ifelse(integer(0L)) # test is an empty vector of integers and yes & no > > > are missing. > > > > logical(0) > > > > > > > > > > > > > > > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > > and provide commented, minimal, self-contained, reproducible code. ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.