1
0

More than 1 year has passed since last update.

【R】Tidyverse を使わないでクロス集計表を作る

Posted at

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

であるが,tidyverse をパズルのように組み合わせて,tidyverse 食わず嫌いにとっては,何をやっているのかよくわからない。

そういうときは,そもそも,どのような結果がほしいのか,それを得るのには tidyverse を使わないでやる方法はあるのかを考える。

暫し黙考。
データが "T"/"F" で書かれているのでピンとひらめく。行列掛け算すれば一行でできる。
対角成分を NA にするかどうかは簡単な話。むしろこのままのほうが扱いやすいか?

> system.time({
+   df = as.matrix(read.csv("sampledatacross2.csv")[, -1])
+   print(t(df) %*% df)
+ })
          果物.野菜   日用雑貨 缶詰野菜 缶詰肉 冷凍肉 ビール ワイン 清涼飲料   菓子
果物.野菜       299  59       62       86     61     86     89     84       56 145   82
               59 183       33       55     41     52     47     49       42  48   54
日用雑貨         62  33      177       44     31     51     45     46       35  56   56
缶詰野菜         86  55       44      303     73    173    167     97       63  89   71
缶詰肉           61  41       31       73    204     75     60     54       42  63   54
冷凍肉           86  52       51      173     75    302    170     71       54  90   66
ビール           89  47       45      167     60    170    293     77       45  85   64
ワイン           84  49       46       97     54     71     77    287       60  78  144
清涼飲料         56  42       35       63     42     54     45     60      184  52   52
              145  48       56       89     63     90     85     78       52 292   86
菓子             82  54       56       71     54     66     64    144       52  86  276
   user  system elapsed 
  0.003   0.001   0.006 

tidyverse を使うより,150 倍ほど速い。

> library(tidyverse)
> system.time({
+ df_read <- read_csv("sampledatacross2.csv")
+ df_cross <- df_read |>
+   pivot_longer(cols = !ID) |>
+   filter(value == TRUE) |>
+   mutate(name_2 = name) |>
+   group_by(ID) |>
+   expand(name, name_2) |>
+   ungroup()
+ col_names <- df_read |>
+   names() |>
+   (\(x) x[-1])()
+ 
+ print(df_cross |>
+   filter(name != name_2) |>
+   pivot_wider(
+     id_cols = name,
+     names_from = name_2,
+     values_from = name_2,
+     values_fn = length
+   ) |>
+   relocate(name, {{ col_names }}) |>
+   mutate(name = name |> factor(levels = col_names)) |>
+   arrange(name) |>
+   knitr::kable())
+ })
Rows: 1000 Columns: 12                                                                                                                        
── Column specification ───────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl  (1): ID
lgl (11): 果物野菜, , 日用雑貨, 缶詰野菜, 缶詰肉, 冷凍肉, ビール, ワイン, 清涼飲料, , 菓子

 Use `spec()` to retrieve the full column specification for this data.
 Specify the column types or set `show_col_types = FALSE` to quiet this message.


|name      | 果物野菜| | 日用雑貨| 缶詰野菜| 缶詰肉| 冷凍肉| ビール| ワイン| 清涼飲料|  | 菓子|
|:---------|---------:|--:|--------:|--------:|------:|------:|------:|------:|--------:|---:|----:|
|果物野菜 |        NA| 59|       62|       86|     61|     86|     89|     84|       56| 145|   82|
|        |        59| NA|       33|       55|     41|     52|     47|     49|       42|  48|   54|
|日用雑貨  |        62| 33|       NA|       44|     31|     51|     45|     46|       35|  56|   56|
|缶詰野菜  |        86| 55|       44|       NA|     73|    173|    167|     97|       63|  89|   71|
|缶詰肉    |        61| 41|       31|       73|     NA|     75|     60|     54|       42|  63|   54|
|冷凍肉    |        86| 52|       51|      173|     75|     NA|    170|     71|       54|  90|   66|
|ビール    |        89| 47|       45|      167|     60|    170|     NA|     77|       45|  85|   64|
|ワイン    |        84| 49|       46|       97|     54|     71|     77|     NA|       60|  78|  144|
|清涼飲料  |        56| 42|       35|       63|     42|     54|     45|     60|       NA|  52|   52|
|        |       145| 48|       56|       89|     63|     90|     85|     78|       52|  NA|   86|
|菓子      |        82| 54|       56|       71|     54|     66|     64|    144|       52|  86|   NA|
   user  system elapsed 
  0.487   0.009   0.497 

元記事ではこれに引き続き,組み合わせの上位5件を抽出というのがあるのだが,仕様が今ひとつわからない。
いずれにしても,別の集計プログラムを書くよりは,上のクロス表を出発点にするのが吉かな?

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0