HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Replace for loop while with apply family function in R

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
whilewithapplyloopreplacefunctionforfamily

Problem

I have trouble with for loop, my code runs very slowly. The thing I want to do is to use function from apply family to make my codes run faster (instead of using for loopand while). Here is an example and my loop:

require(data.table)
require(zoo)

K= 10^(-10)) {
        df<-as.data.table(df)
        df[,K:= K1,by=c("a", "b")] 
        df[,assetreturn:=c(NA,diff(log(K))),by=c("a", "b")] 
        df[,rollsdasset:=rollapply(assetreturn, 249, sd, fill=NA, align='right')*sqrt(250), by=c("a", "b")]
        df[,iterK1:=(cap+L*exp(-rf)*pnorm(blackscholes(K,L,rf, 1,rollsdasset[250]))-rollsdasset[250])/pnorm(blackscholes(K,L,rf, 1,rollsdasset[250])) ,by=c("a", "b")]
        df<-as.data.frame(df)
        errors$V1[i]<-sum((df[df$V1 %in% errors$V1[i],"K"]-df[df$V1 %in% errors$V1[i],"K1"])^2)
        }
    }


Any help would be appreciated.

Solution

You could replace the for loop with a function + sapply like this:

reduce.errors = 10^(-10)) {
    df<-as.data.table(df)
    df[,K:= K1,by=c("a", "b")] 
    df[,assetreturn:=c(NA,diff(log(K))),by=c("a", "b")] 
    df[,rollsdasset:=rollapply(assetreturn, 249, sd, fill=NA, align='right')*sqrt(250), by=c("a", "b")]
    df[,iterK1:=(cap+L*exp(-rf)*pnorm(blackscholes(K,L,rf, 1,rollsdasset[250]))-rollsdasset[250])/pnorm(blackscholes(K,L,rf, 1,rollsdasset[250])) ,by=c("a", "b")]
    df<-as.data.frame(df)
    err <- sum((df[df$V1 %in% err,"K"]-df[df$V1 %in% err,"K1"])^2)
  }  
}
sapply(errors$V1, reduce.errors)


But I don't think this will make it faster at all. If I understand correctly you need the while loop there to reduce the error below a threshold, and so you need the iteration and this cannot be replaced with the "apply" functions easily.

If you want to improve the speed, I think you'll need to rethink come up with a different approach, if it's even possible.

Code Snippets

reduce.errors <- function(err) {
  while (err >= 10^(-10)) {
    df<-as.data.table(df)
    df[,K:= K1,by=c("a", "b")] 
    df[,assetreturn:=c(NA,diff(log(K))),by=c("a", "b")] 
    df[,rollsdasset:=rollapply(assetreturn, 249, sd, fill=NA, align='right')*sqrt(250), by=c("a", "b")]
    df[,iterK1:=(cap+L*exp(-rf)*pnorm(blackscholes(K,L,rf, 1,rollsdasset[250]))-rollsdasset[250])/pnorm(blackscholes(K,L,rf, 1,rollsdasset[250])) ,by=c("a", "b")]
    df<-as.data.frame(df)
    err <- sum((df[df$V1 %in% err,"K"]-df[df$V1 %in% err,"K1"])^2)
  }  
}
sapply(errors$V1, reduce.errors)

Context

StackExchange Code Review Q#49276, answer score: 2

Revisions (0)

No revisions yet.