Myriad
Myriad

Reputation: 351

Create a counter that only counts a certain logical value and gives the same number to repetitions

Say I have a logical value like this

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

How do I create a counter which will only count for the TRUE and will group consecutive repetitions as the same value in the counter. ex. to have something like this:

1, NA, 2,2,NA, 3, NA

Upvotes: 2

Views: 84

Answers (3)

cesarsotovalero
cesarsotovalero

Reputation: 1327

The accepted solution doesn't work for the following case:

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

It prints 1 NA 2 2 NA 3 NA NA NA.

The following function returns the correct answer:

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)
}

Calling solution(rex) prints 1 NA 2 2 NA 3 NA NA 4, which is the correct answer.

Upvotes: 1

tmfmnk
tmfmnk

Reputation: 39858

A twist on the answer provided by @Onyambu could be:

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

[1]  1 NA  2  2 NA  3 NA

It should also work when there are NAs not just at the end of the vector.

Upvotes: 0

Onyambu
Onyambu

Reputation: 79288

You could use rle and its inverse:

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

This can also be written as:

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

To break it down:

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

Upvotes: 1

Related Questions