我有一个向量v
和一个区间向量w
。我想在每个区间中找到函数的最大值f(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
答案 0 :(得分:4)
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