How about findInterval and tapply . findInterval is similar to cut , but without the overhead of converting to factors
tapply(v,findInterval(v,w),function(x)x[which.max(f(x))]) # 1 2 # 4.7 12.0
Or if you want the maximum value
tapply(f(v),findInterval(v,w),max) # 1 2 # 22.09 144.00
Or you could use the fact that your function monotonically increases for all positive values ββand does.
f(tapply(v,findInterval(v,w),max))
Note that you will need to specify what happens at the borders (read the help file)
library(microbenchmark) microbenchmark( mnel = tapply(v,findInterval(v,w),max), flodel = unname(vapply(split(f(v), cut(v, w), drop = TRUE), max, numeric(1L))), flodel2 = unname(vapply(split(seq_along(v), findInterval(v, w)), function(i, v, fv)v[i][which.max(fv[i])], numeric(1L), v, f(v)))) # Unit: microseconds # expr min lq median uq max neval # mnel 260.945 262.9155 264.2265 276.0645 458.670 100 # flodel 331.218 334.3585 336.0580 351.1985 694.715 100 #flodel2 124.998 127.3230 128.5170 137.0505 354.545 100