我需要输出(对于另一个动物园:roll_apply)要求达到某个值的元素数。下面是一个例子:
# value to reach
vTR = c(10,15,12,13,10,15,10)
# element to sum
element = c(9,6,5,2,1,9,1)
magicFoo(vTR, element)
# should return c(NA, 2, 3, 3, 4, 4, 2)
# 10 ~ NA, 15 <= 9+6, 12 <= 5+6+9, 13 <= 2+5+6, 10 <= 1+2+5+6...
例如,我正在寻找某种动态计算k的ave。
我可以用for循环来做,但我在这里寻找更优雅的方式:
vTR = c(10,15,12,13,10,15,10)
# element to sum
element = c(9,6,5,2,1,9,1)
res = c()
j = 1
k = 0
sumE = 0
for (i in 1:length(vTR)){
k = k+1
sumE = sum(element[j:k])
if (sumE < vTR[i]) {
res[length(res)+1] = NA
next
}
repeat {
j = j + 1
sumE = sum(element[j:k])
if (sumE < vTR[i]) {
j = j-1
res[length(res)+1] = k-j +1
break
}
}
}
# > res
# [1] NA 2 3 3 4 4 2
答案 0 :(得分:5)
使用sapply
,我们可以遍历vTR
中的每个元素并获取第一个x
值,反转它们并对它们取累积和,并在值超过时查找索引vTR[x]
值。
sapply(seq_along(vTR),function(x) which.max(cumsum(rev(head(element, x)))>=vTR[x]))
#[1] 1 2 3 3 4 4 2
要获得确切的预期输出,我们可以通过
进行修改sapply(seq_along(vTR), function(x) {
val = cumsum(rev(head(element, x)))
if (sum(val) >= vTR[x])
which.max(val >= vTR[x])
else
NA
})
#[1] NA 2 3 3 4 4 2
答案 1 :(得分:1)
为了计算速度,我略微修改了Ronak Shah的非常好的answer,在n更接近n的地方运行:
nbIndexForCumSum = function(vTR, element) {
rs = rev(c(0,cumsum(rev(element))))
j = 1
unlist(sapply(seq_along(vTR), function(x) {
while(j > 1 & rs[j] < vTR[x] + rs[x+1]) j <<- j-1
res = length(rs[j:x]) - which.max(rs[j:x] < vTR[x] + rs[x+1]) + 2
j <<- ifelse(x > res, x - res, 1)
ifelse( rs[j] < vTR[x] + rs[x+1], NA, res)
}) )
}