簡體   English   中英

如何在R中的特定條件下對向量的元素進行求和?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM