Jika saya memahami pertanyaan dengan benar, Anda ingin mendeteksi saat h_no
tidak bertambah dan kemudian menaikkan class
. (Saya akan menjelaskan bagaimana saya memecahkan masalah ini, ada fungsi mandiri di bagian akhir.)
Kerja
Kami hanya peduli tentang h_no
kolom untuk saat ini, jadi kami dapat mengekstraknya dari bingkai data:
> h_no <- data$h_no
Kami ingin mendeteksi kapan h_no
tidak naik, yang dapat kami lakukan dengan menghitung ketika perbedaan antara elemen yang berurutan negatif atau nol. R menyediakan diff
fungsi yang memberi kita vektor perbedaan:
> d.h_no <- diff(h_no)
> d.h_no
[1] 1 1 1 -3 1 1 1 1 1 1 -6 1 1 1
Setelah kita mendapatkannya, itu adalah masalah sederhana untuk menemukan yang tidak positif:
> nonpos <- d.h_no <= 0
> nonpos
[1] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE
Di R, TRUE
dan FALSE
pada dasarnya sama dengan 1
dan 0
, jadi jika kita mendapatkan jumlah kumulatif dari nonpos
, itu akan meningkat 1 di (hampir) tempat yang sesuai. The cumsum
function (yang pada dasarnya adalah kebalikan dari diff
) dapat melakukan hal ini.
> cumsum(nonpos)
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2 2
Tapi, ada dua masalah: angkanya terlalu kecil; dan, kami kehilangan elemen pertama (harus ada empat di kelas pertama).
Masalah pertama adalah hanya diselesaikan: 1+cumsum(nonpos)
. Dan yang kedua hanya perlu menambahkan a 1
ke depan vektor, karena elemen pertama selalu ada di kelas 1
:
> classes <- c(1, 1 + cumsum(nonpos))
> classes
[1] 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3
Sekarang, kita dapat melampirkannya kembali ke bingkai data kita dengan cbind
(dengan menggunakan class=
sintaks, kita dapat memberi class
judul pada kolom ):
> data_w_classes <- cbind(data, class=classes)
Dan data_w_classes
sekarang berisi hasilnya.
Hasil akhir
Kita dapat memampatkan garis menjadi satu dan membungkus semuanya menjadi sebuah fungsi agar lebih mudah digunakan:
classify <- function(data) {
cbind(data, class=c(1, 1 + cumsum(diff(data$h_no) <= 0)))
}
Atau, karena masuk akal jika class
menjadi faktor:
classify <- function(data) {
cbind(data, class=factor(c(1, 1 + cumsum(diff(data$h_no) <= 0))))
}
Anda menggunakan salah satu fungsi seperti:
> classified <- classify(data) # doesn't overwrite data
> data <- classify(data) # data now has the "class" column
(Metode pemecahan masalah ini bagus karena menghindari iterasi eksplisit, yang umumnya direkomendasikan untuk R, dan menghindari menghasilkan banyak vektor dan daftar perantara dll. Dan juga agak rapi bagaimana itu dapat ditulis dalam satu baris :))