R言語のdroplevels関数がわかりづらいと思ったので実際に動かしてみました。
droplevelsの仕様
以下はdroplevelsの引数の説明です。処理対象データ(x)がベクトル(factor)の場合とデータフレーム(data.frame)の場合で処理が異なるため、2種類あります。(要はオーバーロードの状態になっている)
オプションにexceptとexcludeがありますが、どちらも「除外する」のような意味で違いがわからないので、これらを使用した場合の動作を確認しました。
# droplevels.factor
droplevels(x, exclude = if(anyNA(levels(x))) NULL else NA, …)
# droplevels.data.frame
droplevels(x, except = NULL, exclude, …)
動作環境
R version 3.4.3
テストデータ
まずはデータの元の状態を確認します。
テストデータにはirisを使います。
以下の通り、irisはdata.frame形式で、列が5種類あります。(Sepal.Length、Sepal.Width、Petal.Length、Petal.Width、Species)
> str(iris)
'data.frame': 150 obs. of 5 variables:
$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
irisのSpecies列にはレベル(取りうる値)が3種類あり、以下のように各レベルが50件ずつあります。(setosa, versicolor, virginica)
> table(iris$Species)
setosa versicolor virginica
50 50 50
irisはSpecies列でソートされているため、最初の100件にはvirginicaが使われていません(0件)。
しかしこの最初の100件を抽出して、virginicaが未使用(0件)の状態になっても、virginicaの存在は出力に残ります。
> ir = iris[1:100,]
> table(ir$Species)
setosa versicolor virginica
50 50 0
droplevels関数:未使用レベルを削除する
未使用レベルが残っていると、後続の処理や表記で都合が悪い場合があるため、droplevelsで未使用レベルを削除する等の対処を施します。(たとえば未使用レベルを残してSMOTEを使うとエラーになります)
droplevels(x)でxにある未使用レベルを削除できます。以下の例ではvirginicaが消えています。
> table(droplevels(ir$Species))
setosa versicolor
50 50
> table(droplevels(ir)$Species) #データフレームごと食わせても削除してくれる
setosa versicolor
50 50
excludeオプション:指定したレベルを使用/未使用に関わらず削除する
excludeオプションでレベルを指定すると、未使用でない場合も削除します。
以下の例では、未使用レベルのvirginicaが消えるだけでなく、未使用ではないsetosaも消えます。
excludeはfactorとdata.frameの両方で使用できます。
> table(droplevels(ir$Species, exclude = "setosa"))
versicolor
50
> table(droplevels(ir, exclude = "setosa")$Species) #データフレームごと食わせても削除してくれる
versicolor
50
exceptオプション:指定した列ではレベルを削除しない
exceptオプションで列を指定すると、未使用レベルがある場合でも削除しなくなります。
以下の例ではSpecies列を指定することで、Speciesに未使用レベルがあっても消えなくなります。
exceptは処理対象データ(x)がdata.frameの場合に使用可能であり、factorの場合は一列しかないためか、当記事の冒頭の説明にもあるように、オプション自体が用意されていません。
> table(droplevels(ir, except = 5)$Species) #何列目にあるかで指定する
setosa versicolor virginica
50 50 0
> table(droplevels(ir, except = "Species")$Species) #列名でも良い
setosa versicolor virginica
50 50 0
> table(droplevels(ir$Species, except = 1)) #factorでは用意されていない(使っても消える)
setosa versicolor
50 50
> table(droplevels(ir$Species, except = "Species")) #factorでは用意されていな(以下略
setosa versicolor
50 50
まとめ
- | exclude | except |
---|---|---|
動作の概要 | 指定したレベルを削除する | 指定した列ではレベルを削除しない |
factorで使えるか | 使える | 使えない |
data.frameで使えるか | 使える | 使える |
用例 | exclude = "setosa" | except = 5(あるいは except = "Species") |
参考にしたページ
droplevels function | R Documentation
https://www.rdocumentation.org/packages/base/versions/3.4.3/topics/droplevels