I've just spent today trying to fix a Heisenbug... this function returns a linear interpolator function:
interpOne <- function(xl,yl){ f = function(data){ t = (data-min(xl))/(max(xl)-min(xl)) return(min(yl)+t*(max(yl)-min(yl))) } return(f) } > k=interpOne(c(0,1),c(4,5)) > k(0.5) [1] 4.5 and this function uses the above to return a function that returns a piece-wise linear interpolator function: mr <- function(){ parts = list() ranges = rbind(c(0,1),c(1,2),c(2,3)) domains = rbind(c(3,4),c(5,6),c(2,8)) for(i in 1:length(ranges[,1])){ parts[[i]] = interpOne(ranges[i,],domains[i,]) } f = function(d){ pos = sum(d>ranges[,1]) cat("using pos = ",pos,"\n") return(parts[[pos]](d)) } return(f) } m = mr() The 'ranges' and 'domains' vectors describe the pieces. But this doesn't work: > m(0.5) using pos = 1 [1] -7 - but it should be 3.5 (since 0.5 is in the first piece, and that then interpolates between 3 and 4). What about the other pieces: > m(1.5) using pos = 2 [1] -1 > m(2.5) using pos = 3 [1] 5 - which looks like it's using the last set of range/domain pairs each time. Curious, I thought. So I thought I'd evaluate the functions as they are created in the list to see what's going on. Change the loop to print out: for(i in 1:length(ranges[,1])){ parts[[i]] = interpOne(ranges[i,],domains[i,]) cat("part ",i," at zero = ",parts[[i]](0),"\n") } and try: > m=mr() part 1 at zero = 3 part 2 at zero = 4 part 3 at zero = -10 looks good, those are the intercepts of my pieces... but now: > m(0.5) using pos = 1 [1] 3.5 > m(1.5) using pos = 2 [1] 5.5 > m(2.5) using pos = 3 [1] 5 Woah! It's now working! Trying to observe the thing changes it? A Heisenbug! I can only think it's my misunderstanding of some aspect of R's scoping and evaluation rules. Does evaluating the functions within that loop cause a copy of some environment to be made, or a 'lazy evaluation' to be evaluated? Or a 'promise' to be fulfilled? I don't really understand those terms, I'd just hoped functions ran in the environment they were created in. Seems sometimes they do, sometimes they dont... What's going on? R 2.9.0 on Ubuntu. Barry ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel