Se ho capito correttamente la domanda, vuoi rilevare quando il h_no
non aumenta e quindi incrementare il class
. (Spiegherò come ho risolto questo problema, c'è una funzione autonoma alla fine.)
Lavorando
Per h_no
il momento ci interessa solo la colonna, quindi possiamo estrarla dal data frame:
> h_no <- data$h_no
Vogliamo rilevare quando h_no
non sale, cosa che possiamo fare calcolando quando la differenza tra elementi successivi è negativa o zero. R fornisce la diff
funzione che ci fornisce il vettore delle differenze:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Una volta che lo abbiamo, è semplice trovare quelli che non sono positivi:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
In R, TRUE
e FALSE
sono fondamentalmente uguali a 1
e 0
, quindi se otteniamo la somma cumulativa di nonpos
, aumenterà di 1 in (quasi) i punti appropriati. La cumsum
funzione (che è fondamentalmente l'opposto di diff
) può farlo.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Ma ci sono due problemi: i numeri sono uno troppo piccolo; e ci manca il primo elemento (dovrebbero essercene quattro nella prima classe).
Il primo problema è risolto semplicemente: 1+cumsum(nonpos)
. E il secondo richiede solo l'aggiunta di un 1
all'inizio del vettore, poiché il primo elemento è sempre in 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
Ora possiamo ricollegarlo al nostro data frame con cbind
(usando la class=
sintassi, possiamo dare alla colonna l' class
intestazione):
> data_w_classes <- cbind(data, class=classes)
E data_w_classes
ora contiene il risultato.
Risultato finale
Possiamo comprimere le linee insieme e avvolgere il tutto in una funzione per renderlo più facile da usare:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Oppure, poiché ha senso class
che sia un fattore:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Puoi utilizzare entrambe le funzioni come:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Questo metodo per risolvere questo problema è buono perché evita l'iterazione esplicita, che è generalmente raccomandata per R, ed evita di generare molti vettori intermedi ed elenchi, ecc. Ed è anche abbastanza carino come può essere scritto su una riga :))