findInterval
とはどうですかtapply
。findInterval
に似cut
ていますが、因子に変換するオーバーヘッドはありません
tapply(v,findInterval(v,w),function(x)x[which.max(f(x))])
# 1 2
# 4.7 12.0
または、最大値が必要な場合
tapply(f(v),findInterval(v,w),max)
# 1 2
# 22.09 144.00
または、関数がすべての正の値に対して単調に増加しているという事実を利用することもできます。
f(tapply(v,findInterval(v,w),max))
境界で何が起こるかを指定する必要があることに注意してください (ヘルプ ファイルを読んでください)。
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