Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does lapply apply the function orderly?

Tags:

r

lapply

I have a list of functions

functions <- list(f1, f2, f3, ...)

And I need to pass an object x through all the functions. I could do it by:

for (fun in functions){
  fun(x)
}

The functions do not return anything, but their order is important, i.e. f1(x) must be applied before f2(x).

Thus, I'm thinking on using lapply:

lapply(functions, function(fun) fun(x))

But I don't know if lapply applies first the first function of the list functions or if it follows another order. With the loop I assure the ordering but it may go slower.

Any idea?

like image 804
ebeneditos Avatar asked Nov 07 '22 12:11

ebeneditos


1 Answers

The wording of the question "pass x through ..." suggests that you think this will accomplish a "composition", i.e. a serial application of functions to results from prior applications. Neither of your proposed solutions will do that although you could rework your for loop to do so. Take a look at the ?funprog help page which I am shamelessly quoting in part:

## Iterative function application:
Funcall <- function(f, ...) f(...)
## Compute log(exp(acos(cos(0))
Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE)

Compare the results of a for loop version with the Reduce version:

> flist <- list(log, exp, acos, cos)
> arg <- 0; for (f in flist) {arg <- f(arg)}
> arg
[1] 6.123234e-17
> Funcall <- function(f, ...) f(...)
> ## Compute log(exp(acos(cos(0))
> Reduce(Funcall, list(log, exp, acos, cos), 0, right = TRUE)
[1] 0

This shows that <something> is actually happening:

arg <- 0; for (f in flist) {arg <- f(arg);cat(arg,"\n")}
-Inf 
0 
1.570796 
6.123234e-17 

But they are not the same since the right=TRUE actually reverses the order of application and explains the trivial difference in the final result. Compare:

arg <- 0; for (f in rev(flist)) {arg <- f(arg);cat(arg,"\n")}
like image 163
IRTFM Avatar answered Nov 15 '22 07:11

IRTFM