Featured image of post [R & SQL] データサイエンス100本ノック+α - R-040 (解説)

[R & SQL] データサイエンス100本ノック+α - R-040 (解説)

店舗と商品の組み合わせデータの作成

参考記事:
[R & SQL] データサイエンス100本ノック+α - 概要・導入

演習問題

難易度
全ての店舗と全ての商品を組み合わせたデータを作成したい。店舗データ(store)と商品データ(product)を直積し、件数を計算せよ。

出力イメージ:

       n
1 531590

実行環境の構築について

R コード実行環境の構築に必要な手順は こちら から確認できます。

セットアップが完了すると、必要なパッケージとデータを使用できるようになります。


解答例を以下に示します。

R (データフレーム操作)

利用するデータ

データフレーム df_storedf_product を利用します。

解答例 (1)

cross_join() を用いた解答例です。

解答コードと実行結果

R
df_store %>% 
  cross_join(df_product) %>% 
  count()
# A tibble: 1 × 1
       n
   <int>
1 531590

解説

  • df_store %>% cross_join(df_product)
    df_storedf_product のデータフレームを cross_join() によって結合します。
    cross_join() は、2 つのデータフレームの各行の全組み合わせ (デカルト積) を作成し、その結果を新しいデータフレームとして返します。
    例えば、df_store に 100 行、df_product に 500 行があるとすると、結合された結果には 100 * 500 = 50,000 行が含まれることになります。

  • count()
    count() は、データフレームの行数をカウントする関数です。
    ここでは、cross_join() で結合された結果の行数、つまり生成された全組み合わせの数をカウントしています。
    実行結果で得られる n は組み合わせの総数を表し、ここでは 531,590 件の組み合わせが得られたことが分かります。

解答例 (2)

tidyr::crossing() を用いた解答例です。

解答コードと実行結果

R
df_store %>% 
  tidyr::crossing(df_product) %>% 
  count()
# A tibble: 1 × 1
       n
   <int>
1 531590

解説

crossing() は、tidyr パッケージに含まれる関数で、cross_join() と同様に 2 つのデータフレーム (df_storedf_product) の各行の全組み合わせ (デカルト積) を生成し、結果を新しいデータフレームとして返します。
tidyr パッケージを使用しているプロジェクトでは、コードの一貫性を保つことができます。

R (データベース操作)

データベースでの操作も 解答例 (1) と同様の流れです。
データフレーム df_storedf_product をテーブル参照 db_storedb_product に置き換えることで、同様の操作を実行できます。

R
db_result = db_store %>% 
  cross_join(db_product) %>% 
  count()

db_result %>% collect()
# A tibble: 1 × 1
       n
   <dbl>
1 531590
  • db_result %>% collect()
    データベース操作の結果を R のデータフレーム (tibble) として取得します。

SQL

利用するデータ

store テーブルと product テーブルを利用します。

自動生成された SQL クエリ

データベース操作による結果 (db_result) に基づき、自動生成された SQLクエリを show_query() で確認できます。

R
db_result %>% show_query()
SQL
SELECT COUNT(*) AS n
FROM (
  SELECT store.*, product.*
  FROM store
  CROSS JOIN product
) q01

解答クエリ

このクエリをより簡潔な形に書き直すと、次のようになります。

SQL
SELECT 
  COUNT(*) AS n
FROM 
  store 
CROSS JOIN 
  product

解説

COUNT(*) を用いて、生成された組み合わせの総数をカウントします。結果として、店舗と商品の全組み合わせ数が返されます。

  • SELECT COUNT(*) AS n
    COUNT(*) は、結果セット内の行数をカウントします。ここでは、全組み合わせの数を取得します。
    AS n でカウントされた値に名前を付けています。
  • FROM store
    store テーブルからデータを取得します。
  • CROSS JOIN product
    store テーブルと product テーブルを CROSS JOIN によって結合します。この演算子は、両テーブルの全ての行の組み合わせを生成します。

実行結果の確認

この SQLクエリの実行結果は、次のようにして確認できます。

R
q = sql("
SELECT 
  COUNT(*) AS n
FROM 
  store 
CROSS JOIN 
  product
"
)

q %>% db_get_query(con)
# A tibble: 1 × 1
       n
   <dbl>
1 531590