While R's ifelse
is incredibly handy, it does have a particular shortcoming: in the call ifelse(test, yes, no)
all elements of yes
and no
are evaluated, even those that will be thrown away.
This is rather wasteful if you're using it in the middle of a complicated numerical exercise, say in a function that will be fed to integrate
, uniroot
, optim
or whatever. For example, one might have
ifelse(test, f(x, y, z), g(a, b, c))
where f
and g
are arbitrarily complex or slow functions, possibly involving more nested ifelse
's.
Has anyone written a replacement for ifelse
that only evaluates the elements of yes
/no
that will be kept? Basically, something along the lines of
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])
}
but without the clumsiness/inefficiency of an explicit loop. Is this even possible without getting into the innards of R?
I don't think that the problem is ifelse
. f
and g
are only being evaluated once in your expression. I think your problem is that f
and g
are slow with vectors.
You could change the calls to f
and g
so that they only get evaluated on a subset of the vector.
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])
You'll need to adjust this if any elements of test
are NA
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With