to be continued...

Rや心理統計学の備忘録的な

There are three kinds of lies: lies, damned lies, and statistics.

- 嘘には三種類ある。嘘、大嘘、そして統計だ -
Benjamn Disraeli(19世紀のイギリス首相)

R stanで得られた潜在クラスモデルの推定結果から、各個人がどのクラスに属するかを最頻値から求める

最近は、fgoを始めました(初めての星5は葛飾北斎)

今回は、ほぼメモです

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

プロセス

  1. 各行においてclで一番大きな数を抽出
  2. 個人ごとに一番大きな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を使えば、また違う書き方ができると思います。