Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the *first* longest sequence of TRUE in a boolean vector

Tags:

r

I need to find the first longest sequence of TRUE in a boolean vector. Some examples:

bool <- c(FALSE, TRUE, FALSE, TRUE)
# should become
c(FALSE, TRUE, FALSE, FALSE)

bool <- c(FALSE, TRUE, FALSE, TRUE, TRUE)
# should become
c(FALSE, FALSE, FALSE, TRUE, TRUE)

bool <- c(FALSE, TRUE, TRUE, FALSE, TRUE, TRUE)
# should become
c(FALSE, TRUE, TRUE, FALSE, FALSE, FALSE)

The answer from here handles all my cases correct, except the first one of the above examples.


How can I change

with(rle(bool), rep(lengths == max(lengths[values]) & values, lengths))

so that it also handles the first above example correct?

like image 707
symbolrush Avatar asked Apr 22 '20 09:04

symbolrush


2 Answers

One option could be:

with(rle(bool), rep(seq_along(values) == which.max(lengths * values), lengths))

Results for the first vector:

[1] FALSE  TRUE FALSE FALSE

For the second:

[1] FALSE FALSE FALSE  TRUE  TRUE

For the third:

[1] FALSE  TRUE  TRUE FALSE FALSE FALSE
like image 170
tmfmnk Avatar answered Oct 10 '22 07:10

tmfmnk


Not elegant but might work:

bool <- c(FALSE, TRUE, FALSE, TRUE)

tt <- rle(bool)
t1 <- which.max(tt$lengths[tt$values])
tt$values[tt$values][-t1] <- FALSE
inverse.rle(tt)
#[1] FALSE  TRUE FALSE FALSE

and as a function:

fun <- function(bool) {
  tt <- rle(bool)
  t1 <- which.max(tt$lengths[tt$values])
  tt$values[tt$values][-t1] <- FALSE
  inverse.rle(tt)
}
fun(c(FALSE, TRUE, FALSE, TRUE))
#[1] FALSE  TRUE FALSE FALSE

fun(c(FALSE, TRUE, FALSE, TRUE, TRUE))
#[1] FALSE FALSE FALSE  TRUE  TRUE

fun(c(FALSE, TRUE, TRUE, FALSE, TRUE, TRUE))
#[1] FALSE  TRUE  TRUE FALSE FALSE FALSE

fun(FALSE)
#[1] FALSE

fun(logical(0))
#logical(0)
like image 26
GKi Avatar answered Oct 10 '22 07:10

GKi