Reputation: 2155
I've created the following loop but would like to write it as a lapply function. Is this possible? I'm trying to get my head around apply functions but haven't quite got the hang of it yet.
Decay <- function(x, decay=y) stats::filter(x, decay, method = "recursive")
d<-iris[,c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width")]
DecayX <- c(0.1,0.3,0.6,0.8,0.95)
DecVars = c("Sepal.Length","Petal.Width")
for (j in DecVars){
for (i in DecayX){
VarName <- paste(colnames(d[j]),i*100,"DEC",sep="_")
d[[VarName]]<-Decay(d[j],i)
}
}
Upvotes: 4
Views: 84
Reputation: 6813
Another way would be to replace each for loop with an sapply()
which is faster than for
loops and doesn't require the use of expand.grid()
.
invisible(
sapply(DecVars, function(j) {
sapply(DecayX, function(i) {
VarName <- paste(colnames(d[j]),i*100,"DEC",sep="_")
d[[VarName]] <<- Decay(d[j],i)
})
})
)
You can see that this is a lot faster than using for
loops and also marginally faster than the use of mapply()
with grid.expand()
:
library(microbenchmark)
microbenchmark(
'mapply' = {
vars <- c(expand.grid(DecayX,DecVars,stringsAsFactors = F))
invisible(
mapply(function(x,DecV){VarName <- paste(colnames(d[DecV]),x*100,"DEC",sep="_");
d[[VarName]]<<-Decay(d[DecV],x)},x=vars[[1]],DecV=vars[[2]])
)},
'sapply' = {
invisible(
sapply(DecVars, function(j) {
sapply(DecayX, function(i) {
VarName <- paste(colnames(d1[j]),i*100,"DEC",sep="_")
d1[[VarName]] <<- Decay(d1[j],i)
})
})
)
},
'for-loop' = {
for (j in DecVars){
for (i in DecayX){
VarName <- paste(colnames(d[j]),i*100,"DEC",sep="_")
d[[VarName]]<-Decay(d[j],i)
}
}
},
times = 1000)
Note: if you ignore the expand.grid()
step, mapply()
would be marginally faster.
Upvotes: 1
Reputation: 11480
I don't see any reason to use the apply family here.
You could use mapply
vars <- c(expand.grid(DecayX,DecVars,stringsAsFactors = F))
invisible(
mapply(function(x,DecV){VarName <- paste(colnames(d[DecV]),x*100,"DEC",sep="_");
d[[VarName]]<<-Decay(d[DecV],x)},x=vars[[1]],DecV=vars[[2]])
)
I think in cases of a double loop I would not use the apply
family.
Upvotes: 4