【R】Tidyverse を使わないでクロス集計表を作る(パート2)


【R】Tidyverseの関数群でクロス集計表を作る
https://qiita.com/eitsupi/items/942d913e7b98e853a36b

の後半の仕様がはっきりしなかったので,引用先を見てプログラムを書いた。
呪文のような tidyverse よりは,なにをやっているかわかりやすいか(プログラムがわかるという前提ではあるが)。

3 行目の m の値を変えれば何位までであっても汎用できる。

> system.time({
+ df = as.matrix(read.csv("sampledatacross2.csv")[, -1])
+ tbl = t(df) %*% df
+ m = 5
+ pair = matrix(character(m*2), m)
+ sorted_list = sort(tbl[upper.tri(tbl)], decreasing=TRUE)
+ for (i in 1:m) {
+   for (row in 1:(nrow(tbl)-1)) {
+       for (col in (row+1):ncol(tbl)) {
+           if (tbl[row, col] == sorted_list[i]) {
+               pair[i, ] = c(rownames(tbl)[row], colnames(tbl)[col])
+           }
+       }
+   }
+ }
+ df2 = NULL
+ for (i in 1:nrow(df)) {
+   for (j in 1:m) {
+       if (df[i, pair[j, 1]] && df[i, pair[j, 2]]) {
+           df2 = rbind(df2, df[i, ])
+           break
+       }
+   }
+ }
+ colnames(df2) = colnames(df)
+ })
   user  system elapsed 
  0.014   0.001   0.015 
> print(head(df2))
     果物.野菜     日用雑貨 缶詰野菜 缶詰肉 冷凍肉 ビール ワイン 清涼飲料      菓子
[1,]     FALSE FALSE    FALSE     TRUE  FALSE   TRUE   TRUE  FALSE    FALSE  TRUE FALSE
[2,]      TRUE FALSE    FALSE    FALSE  FALSE  FALSE  FALSE  FALSE    FALSE  TRUE FALSE
[3,]      TRUE  TRUE     TRUE     TRUE  FALSE  FALSE  FALSE   TRUE    FALSE  TRUE FALSE
[4,]      TRUE FALSE    FALSE    FALSE  FALSE  FALSE  FALSE  FALSE    FALSE  TRUE FALSE
[5,]      TRUE FALSE     TRUE    FALSE  FALSE  FALSE  FALSE  FALSE     TRUE  TRUE FALSE
[6,]     FALSE FALSE    FALSE    FALSE  FALSE   TRUE   TRUE  FALSE     TRUE FALSE FALSE
> print(tail(df2))
       果物.野菜     日用雑貨 缶詰野菜 缶詰肉 冷凍肉 ビール ワイン 清涼飲料      菓子
[442,]     FALSE FALSE    FALSE     TRUE  FALSE  FALSE  FALSE   TRUE    FALSE  TRUE  TRUE
[443,]      TRUE FALSE     TRUE    FALSE  FALSE   TRUE   TRUE   TRUE    FALSE  TRUE  TRUE
[444,]      TRUE FALSE    FALSE     TRUE  FALSE   TRUE   TRUE  FALSE    FALSE FALSE FALSE
[445,]     FALSE FALSE    FALSE     TRUE  FALSE   TRUE   TRUE  FALSE    FALSE  TRUE FALSE
[446,]     FALSE FALSE    FALSE     TRUE  FALSE   TRUE   TRUE  FALSE    FALSE  TRUE  TRUE
[447,]      TRUE FALSE    FALSE    FALSE  FALSE  FALSE  FALSE   TRUE    FALSE FALSE  TRUE