The reason is that d$dis300[i] <- h
calls $<-.data.frame
.
This is a pretty complicated function, as you can see:
`$<-.data.frame`
You do not say what foo
, but if it is an atomic vector, the function $<-
implemented in C for speed.
However, I hope you declare foo as follows:
foo <- numeric(netot)
This ensures that you do not need to redistribute the vector for each assignment in the loop:
foo <- 0 # BAD! system.time( for(i in 1:5e4) foo[i] <- 0 ) # 4.40 secs foo <- numeric(5e4) # Pre-allocate system.time( for(i in 1:5e4) foo[i] <- 0 ) # 0.09 secs
Using the *apply
family, you are not worried about this:
d$foo <- vapply(1:netot, function(i, aaa, ent, dis) { h <- aaa[ent[i], dis[i]] if (h == 0) writeLines(sprintf("ERROR. ent:%i dis:%i", ent[i], dis[i])) h }, numeric(1), aaa=aaa, ent=d$ent, dis=d$dis)
... here I also extracted d$ent
and d$dis
outside the loop, which should also improve the situation. It is not possible to start it yourself, because you did not give reproducible data. But here is a similar example:
d <- data.frame(x=1) system.time( vapply(1:1e6, function(i) d$x, numeric(1)) ) # 3.20 secs system.time( vapply(1:1e6, function(i, x) x, numeric(1), x=d$x) ) # 0.56 secs
... but finally it seems that all of this can be reduced to (with the exception of your error detection code):
d$foo <- aaa[cbind(d$ent, d$dis)]