Si je comprends bien la question, vous voulez détecter quand le h_no
n'augmente pas, puis incrémenter 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 soucions que de la h_no
colonne pour le moment, nous pouvons donc l'extraire de la trame de données:
> h_no <- data$h_no
Nous voulons détecter quand h_no
ne monte pas, ce que nous pouvons faire en déterminant quand la différence entre les éléments successifs est soit négative, soit nulle. R fournit la diff
fonction 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 simple 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
Dans R, TRUE
et FALSE
sont fondamentalement les mêmes que 1
et 0
, donc si nous obtenons la somme cumulée de nonpos
, elle augmentera de 1 dans (presque) les endroits appropriés. La cumsum
fonction (qui est fondamentalement l'opposé de 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 nombres sont trop petits; et, il nous manque le premier élément (il devrait y en avoir quatre dans la première classe).
Le premier problème est résolu simplement: 1+cumsum(nonpos)
. Et le second nécessite simplement d'ajouter un 1
à l'avant du vecteur, puisque le premier élément est toujours en 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 bloc de données avec cbind
(en utilisant la class=
syntaxe, nous pouvons donner à la colonne l'en- class
tête):
> data_w_classes <- cbind(data, class=classes)
Et data_w_classes
contient maintenant le résultat.
Résultat final
Nous pouvons compresser les lignes ensemble et tout envelopper dans une fonction pour le rendre plus facile à utiliser:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Ou, puisqu'il est logique que le class
soit 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 les itérations explicites, ce qui est généralement recommandé pour R, et évite de générer beaucoup de vecteurs intermédiaires et de listes, etc. Et aussi c'est plutôt chouette comment cela peut être écrit sur une seule ligne :))