I have a named list of some algorithm, which may look like this
> algorithm
$rBinarize
$rBinarize$x
[1] 40
and may contain an arbitrary number of additional algorithms. Each algorithm carries out an operation on a spatial object (spObj
, of class raster) and returns the modified raster. I would then like to use do.call
to (s)apply this (and all the other) algorithm(s) within a parent function to the original input. However, what I additionally want to achieve is a sequential application of the defined algorithms, i.e. on the output of the previous algorithm. I came up with the following code, but I am curious about additional suggestions to improve the performance, given it is possible.
if(sequential){
for(k in seq_along(algorithm)){
if(length(algorithm[[k]])==0){
args <- c(spObj = spObj)
} else{
args <- c(algorithm[[k]], spObj = spObj)
}
spObj <- do.call(what = names(algorithm)[k], args = args)
}
} else{
algorithm2 <- lapply(algorithm, function(x) x <- c(x, spObj = spObj))
modified <- sapply(seq_along(algorithm2), function(j) do.call(what = names(algorithm2)[[j]], args = algorithm2[[j]]))
}
Wouldn't it possible to use some sort of apply()
construction instead of the for
-loop? I am not sure if I simply don't understand the logic of apply
/do.call
sufficiently or if this is actually not possible in R.
I modified to for-loop to make it comparable with Davids suggestion and ran a microbenchmark on it:
microbenchmark(a = for(k in seq_along(alg)){
if(length(alg[[k]][-1])==0){
args <- c(spObj = spObj)
} else{
args <- c(alg[[k]][-1], spObj = spObj)
}
spObj <- do.call(what = alg[[k]]$algorithm, args = args)
},
b = Reduce(f = function(x, y) do.call(what = y$algorithm, args = c(list(x), y[-1])),
x = alg,
init = spObj))
Which resulted in
Unit: milliseconds
expr min lq mean median uq max neval
a 33.36777 35.22067 39.60699 36.79661 40.75072 152.0171 100
b 33.35236 35.39173 40.32860 37.51993 40.25102 154.0441 100
Is this one of these examples where a for-loop is in fact not slower than any other solution?