[英]How to cumsum the elements of a vector under certain condition in R?
我的目標是對向量的元素求和並將結果分配給每個元素。 但當達到一定條件時,則重新設置累計和。
例如:
vector_A <- c(1, 1, -1, -1, -1, 1, -1, -1, 1, -1)
現在,假設重置累積和的條件是下一個元素的符號不同。
然后所需的 output 是:
vector_B <- c(1, 2, -1, -2, -3, 1, -1, -2, 1, -1)
我怎樣才能做到這一點?
您可以使用自定義 function 而不是cumsum
並使用例如purrr::accumulate
累積結果:
library(purrr)
vector_A <- c(1, 1, -1, -1, -1, 1, -1, -1, 1, -1)
purrr::accumulate(vector_A, function(a,b) {
if (sign(a) == sign(b))
a+b
else
b
})
[1] 1 2 -1 -2 -3 1 -1 -2 1 -1
或者如果你想避免任何分支:
purrr::accumulate(vector_A, function(a,b) { b + a*(sign(a) == sign(b))})
[1] 1 2 -1 -2 -3 1 -1 -2 1 -1
帶有Reduce
的基本 R 選項
> Reduce(function(x, y) ifelse(x * y > 0, x + y, y), vector_A, accumulate = TRUE)
[1] 1 2 -1 -2 -3 1 -1 -2 1 -1
或者使用ave
+ cumsum
> ave(vector_A, cumsum(c(1, diff(sign(vector_A)) != 0)), FUN = cumsum)
[1] 1 2 -1 -2 -3 1 -1 -2 1 -1
使用ave
:
ave(vector_A, data.table::rleid(sign(A)), FUN = cumsum)
# [1] 1 2 -1 -2 -3 1 -1 -2 1 -1
accumulate
的公式版本:
purrr::accumulate(vector_A, ~ ifelse(sign(.x) == sign(.y), .x + .y, .y))
# [1] 1 2 -1 -2 -3 1 -1 -2 1 -1
我想到的方法是在數據中找到由條件 ( sign()
rle()
定義的運行 ( rle() ),分別在每次運行 ( tapply()
) 上應用cumsum()
) ,然后連接回一個向量( unlist()
)。 像這樣:
vector_A <- c(1, 1, -1, -1, -1, 1, -1, -1, 1, -1)
run_length <- rle(sign(vector_A))$lengths
run_id <- rep(seq_along(run_length), run_length)
unlist(tapply(vector_A, run_id, cumsum), use.names = FALSE)
#> [1] 1 2 -1 -2 -3 1 -1 -2 1 -1
稍微總結一下這個過程,我可能會在 function 中找到分組因子(運行索引)? 然后分組摘要需要使用現有工具完成,例如上面的tapply()
或創意ave()
,或者在數據框的上下文中,使用 dplyr 的group_by()
和summarise()
。
run_index <- function(x) {
with(rle(x), rep(seq_along(lengths), lengths))
}
ave(vector_A, run_index(sign(vector_A)), FUN = cumsum)
#> [1] 1 2 -1 -2 -3 1 -1 -2 1 -1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.