Если я правильно понимаю вопрос, вы хотите определить, когда h_no
не увеличивается, а затем увеличивать class
. (Я расскажу, как я решил эту проблему, в конце есть автономная функция.)
Работает
На данный момент нас интересует только h_no
столбец, поэтому мы можем извлечь его из фрейма данных:
> h_no <- data$h_no
Мы хотим определить, когда h_no
не повышается, что мы можем сделать, определив, когда разница между последовательными элементами либо отрицательна, либо равна нулю. R предоставляет diff
функцию, которая дает нам вектор различий:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Как только мы его получим, легко будет найти те, которые не являются положительными:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
В R TRUE
и FALSE
в основном такие же, как 1
и 0
, поэтому, если мы получим кумулятивную сумму nonpos
, она увеличится на 1 (почти) в соответствующих местах. cumsum
Функция (которая в основном противоположность diff
) может это сделать.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Но есть две проблемы: числа слишком малы; и нам не хватает первого элемента (в первом классе должно быть четыре).
Первая проблема решается просто: 1+cumsum(nonpos)
. А для второго просто требуется добавить 1
перед вектором, поскольку первый элемент всегда находится в классе 1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Теперь мы можем прикрепить его обратно к нашему фрейму данных с помощью cbind
(используя class=
синтаксис, мы можем присвоить столбцу class
заголовок):
> data_w_classes <- cbind(data, class=classes)
А data_w_classes
теперь содержит результат.
Конечный результат
Мы можем сжать строки вместе и обернуть все это в функцию, чтобы упростить использование:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Или, поскольку имеет смысл class
быть фактором:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Вы используете любую функцию, например:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Этот метод решения этой проблемы хорош, потому что он избегает явной итерации, которая обычно рекомендуется для R, и избегает генерации множества промежуточных векторов и списка и т. Д. И также вроде изящно, как это может быть написано в одной строке :))