Nếu tôi hiểu câu hỏi một cách chính xác, bạn muốn phát hiện khi h_no
nào giá trị không tăng và sau đó tăng class
. (Tôi sẽ đi qua cách tôi đã giải quyết vấn đề này, có một chức năng tự ở cuối.)
Đang làm việc
Chúng tôi chỉ quan tâm đến h_no
cột vào lúc này, vì vậy chúng tôi có thể trích xuất cột đó từ khung dữ liệu:
> h_no <- data$h_no
Chúng tôi muốn phát hiện khi h_no
nào không tăng, điều này chúng tôi có thể làm bằng cách tìm ra khi sự khác biệt giữa các phần tử liên tiếp là âm hoặc bằng không. R cung cấp diff
hàm cho chúng ta vectơ khác biệt:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Một khi chúng ta có điều đó, việc tìm ra những cái không tích cực là một vấn đề đơn giản:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
Trong R, TRUE
và FALSE
về cơ bản giống với 1
và 0
, vì vậy nếu chúng ta nhận được tổng tích lũy của nonpos
, nó sẽ tăng 1 trong (gần như) các điểm thích hợp. Các cumsum
chức năng (mà về cơ bản là trái ngược với diff
) có thể làm điều này.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Tuy nhiên, có hai vấn đề: một số quá nhỏ; và, chúng tôi đang thiếu phần tử đầu tiên (phải có bốn phần tử trong lớp đầu tiên).
Vấn đề đầu tiên chỉ đơn giản được giải quyết: 1+cumsum(nonpos)
. Và phần thứ hai chỉ yêu cầu thêm a 1
vào phía trước của vectơ, vì phần tử đầu tiên luôn nằm trong lớp 1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Bây giờ, chúng tôi có thể đính kèm nó trở lại khung dữ liệu của chúng tôi với cbind
(bằng cách sử dụng class=
cú pháp, chúng tôi có thể đặt class
tiêu đề cho cột ):
> data_w_classes <- cbind(data, class=classes)
Và data_w_classes
bây giờ chứa kết quả.
Kết quả cuối cùng
Chúng ta có thể nén các dòng lại với nhau và gói tất cả lại thành một hàm để dễ sử dụng hơn:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Hoặc, vì nó có ý nghĩa đối class
với một yếu tố:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Bạn sử dụng một trong hai chức năng như:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Phương pháp giải quyết vấn đề này rất tốt vì nó tránh lặp lại rõ ràng, thường được khuyến nghị cho R và tránh tạo ra nhiều vectơ trung gian và danh sách, v.v. Và cũng khá gọn gàng khi nó có thể được viết trên một dòng :))