[R] Do NOT use ifelse() if you can use if(.) else . [was "Checking .."]
Martin Maechler
maechler at stat.math.ethz.ch
Tue Dec 23 10:05:47 CET 2014
>>>>> Steven Yen <syen04 at gmail.com>
>>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes:
>>>>> Steven Yen <syen04 at gmail.com>
>>>>> on Sun, 14 Dec 2014 09:30:56 -0500 writes:
> Thanks. This worked!! :)
> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher)
"worked", yes.
But please --- for the mailing list archives ---
do use better code.
Unfortunately, ifelse() is used and has been advertized much too
often in cases where it is very sub-optimal efficiency wise.
ifelse(Cond, A, B) should only be used when the condition
'Cond', a logical vector can be (and typically is) of length > 1
{and even then, it maybe a nice short cut, but often still suboptimal
efficiency wise ... but let's not get there}
In cases like this one when the condition 'Cond' is a
simple TRUE or FALSE (i.e. of length 1), using
if(Cond) A else B
instead of
ifelse(Cond, A, B)
is
1. much more R - like [[ "everything you do is a function call" ]]
hence much more elegant
2. considerably more efficient.
3. :-) less typing: uses two "," less ;-)
> require(microbenchmark)
Loading required package: microbenchmark
> x <- setNames(,LETTERS)
> y <- setNames(letters, runif(letters))
> z <- pi
> microbenchmark(r1 <- ifelse(z > 3, x, y), r2 <- if(z > 3) x else y, times=1000)
Unit: nanoseconds
expr min lq mean median uq max neval cld
r1 <- ifelse(z > 3, x, y) 4466 4971.5 5498.928 5244 5673.5 31705 1000 b
r2 <- if (z > 3) x else y 171 212.0 265.241 264 291.0 3130 1000 a
>
i.e., roughly a factor of 20 times more efficient
Martin Maechler,
ETH Zurich and R Core Team.
> At 08:43 AM 12/14/2014, Ben Tupper wrote:
>> Hi,
>>
>> Does this work for you? It simply tests if the name Fisher is found
>> among the names of the elements of spec.
>>
>> obj = list(spec = list)
>> Fisher <- ifelse(!("Fisher" %in% names(obj$spec)), FALSE, obj$spec$Fisher)
>>
>> Cheers,
>> Ben
>>
>> On Dec 14, 2014, at 8:07 AM, Steven Yen <syen04 at gmail.com> wrote:
>>
>> > My obj does not always come with a logical variable defined. So I do
>> >
>> > my.foo <- function(obj,df,digits=5){
>> > if (!is.na("obj$spec$Fisher")) Fisher<-obj$spec$Fisher
>> > ...
>> > }
>> >
>> > This works when "Fisher" is defined in/passed from obj. When it
>> is not, I get error:
>> >
>> > Error in (!is.na("obj$spec$Fisher")) & Fisher :
>> > operations are possible only for numeric, logical or complex types
>> >
>> > I tried exist(Fisher), missing(Fisher)... to no vail. Any idea? Thanks.
More information about the R-help
mailing list