Si entiendo la pregunta correctamente, desea detectar cuándo h_no
no aumenta y luego aumentar class
. (Voy a explicar cómo resolví este problema, hay una función autónoma al final).
Trabajando
Solo nos importa la h_no
columna por el momento, por lo que podemos extraer eso del marco de datos:
> h_no <- data$h_no
Queremos detectar cuándo h_no
no sube, lo que podemos hacer calculando cuándo la diferencia entre los elementos sucesivos es negativa o cero. R proporciona la diff
función que nos da el vector de diferencias:
> 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 vez que tenemos eso, es muy sencillo encontrar los que no son positivos:
> 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
y FALSE
son básicamente lo mismo que 1
y 0
, por lo que si obtenemos la suma acumulada de nonpos
, aumentará en 1 en (casi) los puntos apropiados. La cumsum
función (que es básicamente lo contrario de diff
) puede hacer esto.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Pero hay dos problemas: los números son demasiado pequeños; y nos falta el primer elemento (debería haber cuatro en la primera clase).
El primer problema se resuelve simplemente: 1+cumsum(nonpos)
. Y el segundo solo requiere agregar un 1
al frente del vector, ya que el primer elemento siempre está en la clase 1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Ahora, podemos adjuntarlo nuevamente a nuestro marco de datos con cbind
(usando la class=
sintaxis, podemos darle a la columna el class
encabezado):
> data_w_classes <- cbind(data, class=classes)
Y data_w_classes
ahora contiene el resultado.
Resultado final
Podemos comprimir las líneas juntas y envolverlo todo en una función para que sea más fácil de usar:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
O, dado que tiene sentido class
que sea un factor:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Utiliza cualquiera de las funciones como:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Este método para resolver este problema es bueno porque evita la iteración explícita, que generalmente se recomienda para R, y evita generar muchos vectores intermedios y listas, etc. Y también es bastante bueno cómo se puede escribir en una línea :))