R stanで得られた潜在クラスモデルの推定結果から、各個人がどのクラスに属するかを最頻値から求める
今回は、ほぼメモです
stanで潜在クラスモデルを回した後に、個人がどのクラスに振り分けられることが多いかを知るときに困ったので
以下のようなデータがあったときに、個人がどのクラスに属してそうかを知りたいわけです。
いろいろ方法はあると思いますが、各行において最も大きなclの値を抽出して、個人ごとにその値の最頻値を獲れば、いけるかなと思います
データの構造としては
- 参加者(id)が50人いる
- 各参加者(id)につき10個のclデータがある(今回clは乱数)
- clは4つある
> set.seed(42) > id <- 1:50 > umr <- data.frame(id = rep(id,each=10), + cl1 = rnorm(id,0,1), + cl2 = rnorm(id,0,1), + cl3 = rnorm(id,0,1), + cl4 = rnorm(id,0,1)) > head(umr) id cl1 cl2 cl3 cl4 1 1 1.3709584 0.32192527 1.2009654 -0.04069848 2 1 -0.5646982 -0.78383894 1.0447511 -1.55154482 3 1 0.3631284 1.57572752 -1.0032086 1.16716955 4 1 0.6328626 0.64289931 1.8484819 -0.27364570 5 1 0.4042683 0.08976065 -0.6667734 -0.46784532 6 1 -0.1061245 0.27655075 0.1055138 -1.23825233
プロセス
- 各行においてclで一番大きな数を抽出
- 個人ごとに一番大きなclの最頻値を抽出
# 個人の識別子 id <- 1:50 umr <- data.frame(id = rep(id, each = 10), cl1 = rnorm(id, 0, 1), cl2 = rnorm(id, 0, 1), cl3 = rnorm(id, 0, 1), cl4 = rnorm(id, 0, 1)) %>% tibble::rowid_to_column(var = "subid") umr %>% # clをロング型に pivot_longer(cols = starts_with("cl"), names_to = "var_name", values_to = "value") %>% # idとsubidでグループ処理 group_by(id, subid) %>% # subid内での最大値フィルタ filter(value == max(value)) %>% # countを準備 group_by(id, var_name) %>% count(name = "cnt") %>% # group切り直し group_by(id) %>% # countがidごとに最頻値なレコードを残す filter(cnt == max(cnt)) # A tibble: 50 x 3 # Groups: id [50] id var_name cnt <int> <chr> <int> 1 1 cl3 4 2 2 cl1 4 3 3 cl3 4 4 4 cl4 6 5 5 cl1 4 6 6 cl3 4 7 7 cl1 4 8 8 cl3 4 9 9 cl4 6 10 10 cl1 4 # ... with 40 more rows
idが1の人は、cl3に振り分けられることが最も多いということがわかりました(以下省略)
※{dplyr} 1.0.0
を使えば、また違う書き方ができると思います。