4

ベクトルv、および間隔のベクトル がありますwf(x)各区間での関数 の最大値を見つけたいです。結果を見つけるためのコードに従うよりも速い方法はありますか? 例えば:

v = c(3.5, 2.5, 4, 6.5, 10, 2.3, 1.8, 4.7, 12, 11.5)
w = c(0, 5, 15, 20)
f = function(x){x^2}
> max = unlist(list(sapply(split(v, cut(v, w),drop = TRUE),
               function(v) v[which.max(f(v))])), use.names = FALSE)
> max
[1]  4.7 12.0
4

1 に答える 1

4

findIntervalとはどうですかtapplyfindIntervalに似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
于 2013-06-18T01:41:36.160 に答える