具有重置的累积条件产品
Cumulative conditional product with reset
我有一个很大的 xts 对象。但是,该示例位于数据的 data.frame 两列子集中。每当第二列 df$dd
小于 0 时,我想(在新列中)计算第一列 df$rt
的累积乘积。每当 df$dd
为 0 时,我想重置再次累积为0。因此,对于 df$dd
小于 0 的下一个实例,累积乘积再次开始 df$rt
。
以下示例数据框将所需结果添加为第三列 df$crt
,以供参考。请注意,已应用一些舍入。
df <- data.frame(
rt = c(0, 0.0171, 0.0796, 0.003, 0.0754, -0.0314, 0.0275, -0.0323, 0.0364, 0.0473, -0.0021),
dd = c(0, -0.0657, -0.0013, 0, -0.018, -0.0012, 0, 0, 0, -0.0016, -0.0856),
crt = c(0, 0.171, 0.0981, 0, 0.0754, 0.0415, 0, 0, 0, 0.473, 0.045)
)
我尝试了 with
、ifelse
和 cumprod
的各种组合,例如:
df$crt <- with(df, ifelse(df$dd<0, cumprod(1+df$rt)-1, 0))
然而,这不会在 df$dd
中的 0 之后重置累积乘积,它只会写入 0 并在 df$dd
再次低于零时继续先前的 df$rt
累积。
我想我缺少某种计数器来启动重置。请注意,我正在使用的数据框很大。
对逻辑向量(dd == 0
)取累加和创建分组列,在dd为0的位置加1,然后用replace
加上条件做'rt' 中的累积乘积仅在 'dd' 不等于 0
的地方
library(dplyr)
df %>%
group_by(grp = cumsum(dd == 0)) %>%
mutate(crt1 = replace(dd, dd != 0, (cumprod(1 + rt[dd!=0]) - 1))) %>%
ungroup %>%
select(-grp)
-输出
# A tibble: 11 x 4
rt dd crt crt1
<dbl> <dbl> <dbl> <dbl>
1 0 0 0 0
2 0.0171 -0.0657 0.171 0.0171
3 0.0796 -0.0013 0.0981 0.0981
4 0.003 0 0 0
5 0.0754 -0.018 0.0754 0.0754
6 -0.0314 -0.0012 0.0415 0.0416
7 0.0275 0 0 0
8 -0.0323 0 0 0
9 0.0364 0 0 0
10 0.0473 -0.0016 0.473 0.0473
11 -0.0021 -0.0856 0.045 0.0451
或使用base R
with(df, ave(rt * (dd != 0), cumsum(dd == 0), FUN = function(x)
replace(x, x != 0, (cumprod(1 + x[x != 0]) - 1))))
-输出
[1] 0.00000000 0.01710000 0.09806116 0.00000000 0.07540000 0.04163244 0.00000000 0.00000000 0.00000000 0.04730000 0.04510067
我有一个很大的 xts 对象。但是,该示例位于数据的 data.frame 两列子集中。每当第二列 df$dd
小于 0 时,我想(在新列中)计算第一列 df$rt
的累积乘积。每当 df$dd
为 0 时,我想重置再次累积为0。因此,对于 df$dd
小于 0 的下一个实例,累积乘积再次开始 df$rt
。
以下示例数据框将所需结果添加为第三列 df$crt
,以供参考。请注意,已应用一些舍入。
df <- data.frame(
rt = c(0, 0.0171, 0.0796, 0.003, 0.0754, -0.0314, 0.0275, -0.0323, 0.0364, 0.0473, -0.0021),
dd = c(0, -0.0657, -0.0013, 0, -0.018, -0.0012, 0, 0, 0, -0.0016, -0.0856),
crt = c(0, 0.171, 0.0981, 0, 0.0754, 0.0415, 0, 0, 0, 0.473, 0.045)
)
我尝试了 with
、ifelse
和 cumprod
的各种组合,例如:
df$crt <- with(df, ifelse(df$dd<0, cumprod(1+df$rt)-1, 0))
然而,这不会在 df$dd
中的 0 之后重置累积乘积,它只会写入 0 并在 df$dd
再次低于零时继续先前的 df$rt
累积。
我想我缺少某种计数器来启动重置。请注意,我正在使用的数据框很大。
对逻辑向量(dd == 0
)取累加和创建分组列,在dd为0的位置加1,然后用replace
加上条件做'rt' 中的累积乘积仅在 'dd' 不等于 0
library(dplyr)
df %>%
group_by(grp = cumsum(dd == 0)) %>%
mutate(crt1 = replace(dd, dd != 0, (cumprod(1 + rt[dd!=0]) - 1))) %>%
ungroup %>%
select(-grp)
-输出
# A tibble: 11 x 4
rt dd crt crt1
<dbl> <dbl> <dbl> <dbl>
1 0 0 0 0
2 0.0171 -0.0657 0.171 0.0171
3 0.0796 -0.0013 0.0981 0.0981
4 0.003 0 0 0
5 0.0754 -0.018 0.0754 0.0754
6 -0.0314 -0.0012 0.0415 0.0416
7 0.0275 0 0 0
8 -0.0323 0 0 0
9 0.0364 0 0 0
10 0.0473 -0.0016 0.473 0.0473
11 -0.0021 -0.0856 0.045 0.0451
或使用base R
with(df, ave(rt * (dd != 0), cumsum(dd == 0), FUN = function(x)
replace(x, x != 0, (cumprod(1 + x[x != 0]) - 1))))
-输出
[1] 0.00000000 0.01710000 0.09806116 0.00000000 0.07540000 0.04163244 0.00000000 0.00000000 0.00000000 0.04730000 0.04510067