Si je comprends bien la question, vous voulez détecter quand la h_no
n'augmente pas, puis incrémente le class
. (Je vais vous expliquer comment j'ai résolu ce problème, il y a une fonction autonome à la fin).
Travail
Nous ne nous préoccupons que de la h_no
pour le moment, nous pouvons donc l'extraire du cadre de données :
> h_no <- data$h_no
Nous voulons détecter quand h_no
n'augmente pas, ce que nous pouvons faire en déterminant quand la différence entre des éléments successifs est négative ou nulle. R fournit le diff
qui nous donne le vecteur des différences :
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Une fois que nous avons cela, il est facile de trouver ceux qui ne sont pas positifs :
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
En R, TRUE
et FALSE
sont fondamentalement les mêmes que 1
et 0
donc si nous obtenons la somme cumulée de nonpos
il augmentera de 1 dans (presque) les endroits appropriés. Le site cumsum
(qui est fondamentalement l'opposé de la fonction diff
) peut le faire.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Mais il y a deux problèmes : les chiffres sont un peu trop faibles et il manque le premier élément (il devrait y en avoir quatre dans la première classe).
Le premier problème est simplement résolu : 1+cumsum(nonpos)
. Et la seconde nécessite simplement d'ajouter un 1
au début du vecteur, puisque le premier élément est toujours dans la classe 1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Maintenant, nous pouvons le rattacher à notre cadre de données avec cbind
(en utilisant le class=
nous pouvons donner à la colonne la syntaxe class
tête) :
> data_w_classes <- cbind(data, class=classes)
Et data_w_classes
contient maintenant le résultat.
Résultat final
Nous pouvons comprimer les lignes ensemble et les regrouper dans une fonction pour en faciliter l'utilisation :
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Ou, puisque c'est logique pour le class
pour être un facteur :
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Vous utilisez l'une ou l'autre fonction comme :
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Cette méthode de résolution de ce problème est bonne car elle évite l'itération explicite, qui est généralement recommandée pour R, et évite de générer beaucoup de vecteurs intermédiaires et de listes, etc. Et aussi, c'est assez chouette de pouvoir l'écrire en une seule ligne :) )
0 votes
Voir aussi Créer une variable de regroupement pour des séquences consécutives et un vecteur de fractionnement