Se entendi a pergunta corretamente, você deseja detectar quando o h_no
não aumenta e, em seguida, incrementa o class
. (Vou explicar como resolvi esse problema, há uma função independente no final.)
Trabalhando
No h_no
momento, só nos importamos com a coluna, então podemos extraí-la do quadro de dados:
> h_no <- data$h_no
Queremos detectar quando h_no
não sobe, o que podemos fazer calculando quando a diferença entre os elementos sucessivos é negativa ou zero. R fornece a diff
função que nos dá o vetor de diferenças:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Assim que tivermos isso, é uma questão simples encontrar os que não são positivos:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
Em R, TRUE
e FALSE
são basicamente iguais a 1
e 0
, portanto, se obtermos a soma cumulativa de nonpos
, aumentará em 1 nos (quase) pontos apropriados. A cumsum
função (que é basicamente o oposto de diff
) pode fazer isso.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Mas, há dois problemas: os números são muito pequenos; e, está faltando o primeiro elemento (deve haver quatro na primeira aula).
O primeiro problema é simplesmente resolvido: 1+cumsum(nonpos)
. E o segundo requer apenas a adição de um1
à frente do vetor, já que o primeiro elemento está sempre na 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
Agora, podemos anexá-lo de volta ao nosso quadro de dados com cbind
(usando a class=
sintaxe, podemos dar à coluna oclass
título ):
> data_w_classes <- cbind(data, class=classes)
E data_w_classes
agora contém o resultado.
Resultado final
Podemos compactar as linhas e agrupar tudo em uma função para torná-lo mais fácil de usar:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Ou, uma vez que faz sentido class
que seja um fator:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Você usa uma das funções como:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Este método de resolver este problema é bom porque evita a iteração explícita, que geralmente é recomendada para R, e evita a geração de muitos vetores intermediários e listas etc. E também é bem legal como pode ser escrito em uma linha :))