質問を正しく理解している場合は、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
しかし、問題が 2 つあります。数字が小さすぎることです。そして、最初の要素がありません (最初のクラスには 4 つあるはずです)。
最初の問題は簡単に解決できます: 1+cumsum(nonpos)
. そして、1
最初の要素は常に class にあるため、2 番目の要素はベクトルの前に a を追加するだけ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 で一般的に推奨されている明示的な反復を回避し、大量の中間ベクトルやリストなどを生成することを回避するため、優れています。また、1 行で記述できる方法もすっきりしています :) )