Rでdplyrを使用してfilterする際に変数のレベルが残る問題

R

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...

コメント

タイトルとURLをコピーしました