私が質問を正しく理解している場合は、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
最初の要素は常にクラスにあるので、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行で記述する方法も少し整然としています:))