使用 tidyverse 函数,我希望创建一个新的数据列,其总和等于第一列中的累积和,但使用的增量不大于incr
.
可以以 df 开头
incr <- 1.5
df <- data.frame(a = c(6,0,0,2.5,0,0))
df
a
1 6.0
2 0.0
3 0.0
4 2.5
5 0.0
6 0.0
然后b
使用以下命令创建一个新列incr
:
a b
1 6.0 1.5
2 0.0 1.5
3 0.0 1.5
4 2.5 1.5
5 0.0 1.5
6 0.0 1.0
我发现tidyr::uncount()
它似乎是一个可以工作的函数,但我需要使用非整数增量。一般来说,尝试改变和使用矢量化函数,并对运行它进行了一些思考rowwise()
,但我的大多数想法都需要迭代。
来自下面的评论:如果类比有帮助,请将其想象为排队下载。列a
显示您在时间 1 时按下载 6 MB,在时间 2 和 3 时按 0 MB,然后在时间 4 时按下载 2.5 MB。但是,您的连接只能以 的速度下载incr
。因此,如果incr
是 1.5,该列b
将显示实际下载的内容。您在每个周期都充分使用该连接速度,直到您在时间 6 内下载最终残差 ( 1.0
)。
为了更好地突出维度,这里还有另一个 df:
incr <- 1.5
df <- data.frame(a = rep(0,100),b=rep(0,100))
df$a[c(30,33,38)] = c(6,2.5,1)
df[30:39,]
a b
30 6.0 0
31 0.0 0
32 0.0 0
33 2.5 0
34 0.0 0
35 0.0 0
36 0.0 0
37 0.0 0
38 1.0 0
39 0.0 0
具有所需的输出
a b
30 6.0 1.5
31 0.0 1.5
32 0.0 1.5
33 2.5 1.5
34 0.0 1.5
35 0.0 1.0
36 0.0 0.0
37 0.0 0.0
38 1.0 1.0
39 0.0 0.0
因为我不知道什么时候放弃,我认为唯一的解决办法就是迭代。但我认为你总是可以在 C++ 中进行迭代,使其像向量化函数一样超快:
一种可能性是使用函数工厂。这允许您保存一些状态信息,在本例中是余数,这对您的计算很有帮助。迭代来自内部
map_dbl
,但这不是矢量化答案:我将使用
for
带有一堆if
语句的循环来完成此操作:设置数据框
For
循环和if
语句:输出
在实现方面,我使用了@Andy Baxter的Rcpp函数,并且效果非常好!
对于希望仅使用 tidyverse 而无需 C++ 来解决此问题的未来用户:同意 @Andy Baxter 的结论,即这需要迭代,我从上面
case_when()
的 100 行开始构建了一个可行但笨重的方法df
: