简体   繁体   中英

Looking for a more efficient ifelse()

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM