您可以使用tidyverse 尝试以下类似操作
首先,将x 制作成数据框
x <- as.data.frame(sample(-20:20))
colnames(x) <- c("dat")
然后像管道一样:
x %>%
mutate(sm = starting.limit) %>%
mutate(sm = if_else(sm+lead(dat,1) > upper.limit, upper.limit
, if_else(sm+lead(dat,1) < lower.limit, lower.limit, sm) )) %>%
select(sm) %>%
filter(sm != is.na(sm)) %>%
tail(n=1)
有效地,根据需要修改最后的select、filter和tail函数。
基准测试
我很好奇这对其他解决方案的表现如何,并尝试将我的代码添加到已经提供的微基准测试中。来了
perf <- microbenchmark(
m1 = {upper.limit <- 15
starting.limit <- 5
lower.limit <- 0
set.seed(123)
x <- sample(-200000:200000)
for(i in 1:length(x)){
k <- starting.limit + x[i]
k <- ifelse(k > upper.limit, upper.limit, ifelse(k < lower.limit, lower.limit,k))
starting.limit <- k
}},
m2 = {
set.seed(123)
x <- sample(-200000:200000)
vec <- purrr::accumulate(c(5, x), k_fun)
k <- tail(vec, 1)
},
m3 = {
x <- sample(-200000:200000)
xd <- as.data.frame(x)
colnames(xd) <- c("dat")
xd %>%
mutate(sm = starting.limit) %>%
mutate(sm = if_else(sm+lead(dat,1) > upper.limit, upper.limit
, if_else(sm+lead(dat,1) < lower.limit, lower.limit, sm) )) %>%
select(sm) %>%
filter(sm != is.na(sm)) %>%
tail(n=1)
}
)
输出:
Unit: milliseconds
expr min lq mean median uq max neval
m1 1223.49718 1255.69514 1272.2679 1260.9643 1272.3401 1392.0402 100
m2 964.76948 982.96555 1007.5521 989.5366 1007.9106 1173.2754 100
m3 68.80358 76.77386 133.0509 170.5572 177.0051 274.9299 100