创建一个只对某个逻辑值进行计数的计数器,并给重复的次数相同的计数器

问题描述 投票:0回答:1

假设我有一个这样的逻辑值

rex <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, NA)

我如何创建一个计数器,它只对 TRUE 并将连续的重复作为同一个值在计数器中分组,例如:有这样的东西。

1, NA, 2,2,NA, 3, NA
r dplyr datatable counter data-cleaning
1个回答
0
投票

在以下情况下,被接受的解决方案不适用。

rex <- c(TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, NA, NA, TRUE)

它的打印结果是 1 NA 2 2 NA 3 NA NA NA.

以下函数返回正确答案。

solution <- function (rex) {
  result <- c()
  counter <- 1
  consecutive <- FALSE
  for (i in 1:length(rex)) {
    if (rex[i] == TRUE && !is.na(rex[i]) && consecutive) {
      result <- c(result, counter)
      consecutive <- TRUE
    } else if (rex[i] == TRUE && !is.na(rex[i]) && !consecutive) {
      result <- c(result, counter)
      consecutive <- TRUE
    } else{
      if(i < length(rex) && rex[i+1] == TRUE && !is.na(rex[i+1])){
        counter <- counter + 1
      }
      result <- c(result, NA)
      consecutive <- FALSE
    }
  }
  return(result)
}

调用 solution(rex) 印花 1 NA 2 2 NA 3 NA NA 4,这是正确的答案。


1
投票

你可以用 rle 及其倒数。

 inverse.rle(modifyList(b<-rle(rex),list(values = with(b,cumsum(values)*NA^(!values)))))
[1]  1 NA  2  2 NA  3 NA

这也可以写成:

inverse.rle(`[[<-`(b<-rle(rex),"values",with(b,cumsum(values)*NA^(!values))))

将其分解:

b <- rle(rex)
b$values <- cumsum(b$values) * NA^(!b$values)
inverse.rle(b)

0
投票

@Onyambu提供的答案的一个转折可以是:

with(rle(!is.na(rex) & rex), rep(cumsum(values), lengths)) * rex^NA

[1]  1 NA  2  2 NA  3 NA

当有NAs时也可以用,而不仅仅是在向量的末端。

© www.soinside.com 2019 - 2024. All rights reserved.