2016-05-25 27 views
12

Dato un vettore booleano, come posso trovare il pezzo più lungo continuo di TRUE e modificare il resto TRUE valori su FALSE?Trova il pezzo continuo più lungo di TRUE in un vettore booleano

Ad esempio, dato un vettore booleano:

bool = c(TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) 

Come posso ottenere un vettore come: RLE

c(FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE) 
+0

Vuoi dire la catena continua più lunga di VERO? –

+0

@MhairiMcNeill Sì – sl1129

+6

Questo suona come la codifica della lunghezza di esecuzione "??" (wink wink hint hint) –

risposta

11

Ecco un approccio che metterà in evidenza tutti i pezzi più lunghi della consecutivi TRUE s in un vettore booleano. Ciò significa che se ci sono, ad esempio, due blocchi TRUE della stessa lunghezza (massima), entrambi verranno riportati come TRUE nell'output.

Possiamo usare:

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

che significa:

  • with(rle(bool), ...): calcolare il tirature
  • lengths == max(lengths[values]) & values: verificare se ogni run length è uguale alla lunghezza massima corsa in cui i valori sono TRUEe controllare anche se i valori stessi sono TRUE
  • rep(...., lengths): ripetere ciascuno dei Logicals risultanti più spesso il proprio tiratura

caso di test di OP:

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 

Secondo caso di test: stessi massimi per T e 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 

Terzo test case: F chunk più lungo di 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 
14

Usando:

myRle <- rle(bool)$length 
rep(myRle == max(myRle), myRle) 

OP didn' t fornire risposte a possibili problemi con questo approccio, b ut la risposta completa è proposta da docendodiscimus dovrebbe coprire tutti i possibili problemi.

+4

Attendi un minuto. Se avessimo una corsa più lunga di FALSE rispetto a TRUE, ciò non funzionerebbe, giusto? –

+2

@MhairiMcNeill, 'con (rle (bool), rep (lunghezze == max (lunghezze [valori]) e valori, lunghezze))' potrebbe essere più robusto anche se segnerà _all_ più grandi blocchi di TRUE (se ci sono più massimi). –

+0

Se non vuoi le upvotes, perché non eliminare? – jpmc26

1

Con ispirazione da @ zx8754

Questo dovrebbe funzionare anche quando la sequenza complessiva più lunga è realizzata in 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) 
+0

Ah si. E ho individuato un secondo problema quando si hanno più sequenze massime. Penso che dovrebbe essere proprio ora per trovare la prima sequenza massima ... –