dplyr::filterにおける変数レベルの残存問題
先日,gtsummaryを使用してtbl_summary()でテーブルを作成していたところ,除外したはずの変数が下図のように残ってしまっていた.

元のデータセットには含まれる変数のレベルではあるが,dplyr::filterで除外されたはずのものである.
なぜこれは残ってしまったのか.例として具体的には下記のようなコードである.
# ライブラリの読み込み
library(tidyverse)
library(gtsummary)
# irisデータセットを萼片の長さでグループ分け
df <- iris %>%
mutate(
Sepal.Group = case_when(
Sepal.Length > 6 ~ "Large",
TRUE ~ "Small"
))
# 上記データセットからsetosaのみ除外して長さを比較したテーブル
df %>%
filter(Species != "setosa") %>%
tbl_summary(by = Sepal.Group)
ここにおいてfilterでSpeciesという変数から”setosa”というレベルは消えているはずなのに,テーブル上ではしっかりと0または0%として表示されてしまう.これはgtsummaryの問題ではなく,どうやら変数のレベルが残っていることに起因するらしい.念のためsummary等で確認しても残っている.
Species
setosa : 0
versicolor:50
virginica :50
デフォルトでfilterはlevelsを残すものらしい(非常に不便なように思えるが)
解決方法
1. droplevelsを使用する
最も簡単な方法はdroplevelsを使用することです.
df %>%
filter(Species != "setosa") %>%
droplevels() %>%
tbl_summary(by = Sepal.Group)
たったこれだけで不要なレベルを削除することができます.結果は下図.

2. 新しく関数を定義する
毎回droplevelsを行うのが面倒な場合にはfilterとdroplevelsをまとめて関数で定義してしまうのも手.
# 新しくフィルタリングする関数を定義
dfilter <- function(...) droplevels(filter(...))
# filterの代わりに使用する
df %>%
dfilter(Species != "setosa") %>%
tbl_summary(by = Sepal.Group)
参照

When filtering with dplyr in R, why do filtered out levels of a variable remain in filtered data?
I'm trying to filter out a bunch of data using the filter command from the dplyr package. Everything appears to be going...



コメント