admin管理员组文章数量:1302384
Below is a reproducible example with a test dataframe:
dat<- structure(list(A = c(1.3, 1.5, 1.6, 1.2, 1.1, 1.2),
B = c(0.25, 0.21, 0.21, 0.15, 0.26, 0.17)),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -6L))
I want to do add a column with an initial value, say 1000, and then use accumulate
but depending on a condition on column A.
Basically, if value in column A is superior or equal to 1.2; Column C = 1000-(Column B * 1000). But this is for the first row only. For the rest, instead of 1000 (initial value), it should be previous value.
My desired output would be something like this :
A | B | C |
---|---|---|
1.3 | 0.25 | 750 |
1.5 | 0.21 | 592.5 |
1.6 | 0.21 | 468.075 |
1.2 | 0.15 | 397.864 |
1.1 | 0.26 | 397.864 |
1.2 | 0.17 | 330.227 |
Below is a reproducible example with a test dataframe:
dat<- structure(list(A = c(1.3, 1.5, 1.6, 1.2, 1.1, 1.2),
B = c(0.25, 0.21, 0.21, 0.15, 0.26, 0.17)),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -6L))
I want to do add a column with an initial value, say 1000, and then use accumulate
but depending on a condition on column A.
Basically, if value in column A is superior or equal to 1.2; Column C = 1000-(Column B * 1000). But this is for the first row only. For the rest, instead of 1000 (initial value), it should be previous value.
My desired output would be something like this :
A | B | C |
---|---|---|
1.3 | 0.25 | 750 |
1.5 | 0.21 | 592.5 |
1.6 | 0.21 | 468.075 |
1.2 | 0.15 | 397.864 |
1.1 | 0.26 | 397.864 |
1.2 | 0.17 | 330.227 |
(and so the first row should be 1000 if column A is inferior to 1.2).
I've tried to use accumulate
but I can't make the conditional part work:
dat<-dat %>%
mutate(C = accumulate(tail(B,-1), .f = ~ .x - (.x * .y), .init = 1000))
Share
Improve this question
edited Feb 11 at 19:05
M--
29.2k10 gold badges69 silver badges106 bronze badges
Recognized by R Language Collective
asked Feb 10 at 19:53
M.OM.O
4712 silver badges9 bronze badges
0
2 Answers
Reset to default 13If you would like to use accumulate
> dat %>%
+ mutate(C = accumulate(B * (A >= 1.2), ~ .x * (1 - .y), .init = 1000)[-1])
# A tibble: 6 × 3
A B C
<dbl> <dbl> <dbl>
1 1.3 0.25 750
2 1.5 0.21 592.
3 1.6 0.21 468.
4 1.2 0.15 398.
5 1.1 0.26 398.
6 1.2 0.17 330.
With base R, you can do the same if you use Reduce
or cumprod
transform(
dat,
C = Reduce(\(x, y) x * (1 - y),
B * (A >= 1.2),
init = 1000,
accumulate = TRUE
)[-1]
)
or
transform(
dat,
C = cumprod(1 - B * (A >= 1.2)) * 1000
)
which gives
A B C
1 1.3 0.25 750.0000
2 1.5 0.21 592.5000
3 1.6 0.21 468.0750
4 1.2 0.15 397.8638
5 1.1 0.26 397.8638
6 1.2 0.17 330.2269
data
> dput(dat)
structure(list(A = c(1.3, 1.5, 1.6, 1.2, 1.1, 1.2), B = c(0.25,
0.21, 0.21, 0.15, 0.26, 0.17)), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
library(dplyr)
dat %>%
mutate(C = purrr::accumulate2(B[-1], A[-1], ~ .x - (.x * .y) * (..3 >= 1.2) ,
.init = 1000 - first(B) * 1000 * (first(A) >= 1.2)))
#> # A tibble: 6 × 3
#> A B C
#> <dbl> <dbl> <dbl>
#> 1 1.3 0.25 750
#> 2 1.5 0.21 592.
#> 3 1.6 0.21 468.
#> 4 1.2 0.15 398.
#> 5 1.1 0.26 398.
#> 6 1.2 0.17 330.
Created on 2025-02-10 with reprex v2.1.1
本文标签: rUse purrraccumulate with conditionStack Overflow
版权声明:本文标题:r - Use purrr::accumulate with condition - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741693715a2392882.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论