问题
Given a boolean vector, how can I find the longest continuous chunk of TRUE
and change the rest TRUE
values to FALSE
?
For example, given a boolean vector:
bool = c(TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
How can I get a vector like:
c(FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
回答1:
Here's an approach that will highlight all longest chunks of consecutive TRUE
s in a boolean vector. That means, if there are, say, two TRUE
chunks of the same (max) length, both will be reported as TRUE
in the output.
We can use:
with(rle(bool), rep(lengths == max(lengths[values]) & values, lengths))
which means:
with(rle(bool), ...)
: compute the run lengthslengths == max(lengths[values]) & values
: check if each run length is equal to the maximum run length where values isTRUE
and also check if values itself isTRUE
rep(...., lengths)
: repeat each of the resulting logicals as often as it's own run length
OP's test case:
bool <- c(TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
with(rle(bool), rep(lengths == max(lengths[values]) & values, lengths))
# [1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE FALSE
Second test case: same maxima for T and F:
x <- c(TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE)
with(rle(x), rep(lengths == max(lengths[values]) & values, lengths))
# [1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
Third test case: F longer chunk than T:
y <- c(TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE)
with(rle(y), rep(lengths == max(lengths[values]) & values, lengths))
# [1] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
回答2:
Using rle:
myRle <- rle(bool)$length
rep(myRle == max(myRle), myRle)
OP didn't provide answers to possible issues with this approach, but the complete answer is proposed by docendodiscimus should cover all possible issues.
回答3:
With inspiration from @zx8754
This should work even when the longest overall sequence is made of FALSE
.
runs <- rle(bool)
lengths <- runs$lengths
is_max <- which(lengths == max(lengths[runs$values]) & runs$values)
rep(1:length(lengths) == is_max[1], lengths)
来源:https://stackoverflow.com/questions/37447114/find-the-longest-continuous-chunk-of-true-in-a-boolean-vector