2017-05-09 5 views
3

Problème: Avec un vecteur atomique, trouvez les indices de début et de fin des passages dans le vecteur.Comment trouver les positions de début et de fin/indices de courses/valeurs consécutives dans R?

vecteur exemple avec des pistes:

x = rev(rep(6:10, 1:5)) 
# [1] 10 10 10 10 10 9 9 9 9 8 8 8 7 7 6 

Sortie de rle():

rle(x) 
# Run Length Encoding 
# lengths: int [1:5] 5 4 3 2 1 
# values : int [1:5] 10 9 8 7 6 

sortie souhaitée:

# start end 
# 1  1 5 
# 2  6 9 
# 3 10 12 
# 4 13 14 
# 5 15 15 

La classe de base rle ne semble pas fournir cette fonctionnalité, mais la classe Rle et la fonction rle2 faire. Cependant, étant donné que la fonctionnalité est mineure, coller à la base R semble plus judicieux que d'installer et de charger des paquets supplémentaires.

Il existe des exemples d'extraits de code (here, here et on SO) qui résolvent le problème légèrement différent de trouver des index de début et de fin pour des exécutions qui satisfont certaines conditions. Je voulais quelque chose qui soit plus général, qui puisse être effectué sur une seule ligne et n'implique pas l'attribution de variables ou de valeurs temporaires.

Répondre à ma propre question parce que j'étais frustré par le manque de résultats de recherche. J'espère que cela aide quelqu'un!

Répondre

5

logique de noyau:

# Example vector and rle object 
x = rev(rep(6:10, 1:5)) 
rle_x = rle(x) 

# Compute endpoints of run 
end = cumsum(rle_x$lengths) 
start = c(1, lag(end)[-1] + 1) 

# Display results 
data.frame(start, end) 
# start end 
# 1  1 5 
# 2  6 9 
# 3 10 12 
# 4 13 14 
# 5 15 15 

Tidyverse/dplyr moyen (structure centrée sur les données):

library(dplyr) 

rle(x) %>% 
    unclass() %>% 
    as.data.frame() %>% 
    mutate(end = cumsum(lengths), 
     start = c(1, lag(end)[-1] + 1)) %>% 
    extract(c(1,2,4,3)) # To re-order start before end for display 

Parce que les start et end vecteurs sont la même longueur que le composant values de l'objet rle , résoudre le problème lié à l'identification des points de terminaison pour les exécutions répondant à certaines conditions est simple: filter ou sous-ensemble les start et end vecteurs utilisant la condition sur les valeurs d'exécution.