# 機能設計書 28-cross_join

## 概要

本ドキュメントは、dplyrパッケージにおける`cross_join`関数の機能設計を定義する。`cross_join`は、2つのデータフレームのすべての行の組み合わせ（直積、デカルト積）を生成する結合関数である。

### 本機能の処理概要

`cross_join`関数は、SQLの CROSS JOIN に相当する操作を実行する。左側のデータフレーム（x）の各行を右側のデータフレーム（y）のすべての行と組み合わせ、結果として `nrow(x) * nrow(y)` 行のデータフレームを生成する。結合キーは使用せず、すべての組み合わせが生成される。

**業務上の目的・背景**：すべての可能な組み合わせを生成する必要がある場合に使用する。例えば、「すべての商品とすべての店舗の組み合わせを生成する」「すべての日付とすべての地域の組み合わせでマスタテーブルを作成する」「組み合わせ最適化のための候補リストを生成する」などのケースである。`cross_join`は、他の結合操作の基礎となる操作であり、フィルタリングと組み合わせることで任意の結合条件を実現できる。

**機能の利用シーン**：
- 完全なマトリクス（全組み合わせ）の生成
- シミュレーションや最適化のための候補セット作成
- 時系列とカテゴリの全組み合わせによる欠損検出用ベース作成
- 比較分析のための全ペア生成

**主要な処理内容**：
1. キーなしの結合設定（new_join_by()）
2. 列名の重複処理（join_cols）
3. xの各行をyの行数だけ繰り返し（vec_rep_each）
4. yの全行をxの行数だけ繰り返し（vec_rep）
5. 結果データフレームの構築

**関連システム・外部連携**：vctrパッケージのvec_rep、vec_rep_each関数を使用して効率的な行複製を実行。tibbleパッケージとの相互運用性を提供。

**権限による制御**：特になし。Rの通常のオブジェクト操作権限に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはRライブラリであり、UIは存在しない |

## 機能種別

データ変換 / 結合処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | data.frame / tibble | Yes | 左側テーブル | data.frameまたはその拡張型 |
| y | data.frame / tibble | Yes | 右側テーブル | data.frameまたはその拡張型 |
| copy | logical | No | 異なるソース間でのコピー許可 | TRUE/FALSE（デフォルト: FALSE） |
| suffix | character(2) | No | 重複列名への接尾辞 | 長さ2の文字ベクトル（デフォルト: c(".x", ".y")） |

### 入力データソース

R環境内のdata.frame、tibble、またはdbplyr/dtplyrによるリモートテーブル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | data.frame / tibble | xと同じ型で、nrow(x) * nrow(y)行を含む |

### 出力先

R環境内のオブジェクトとして返却

## 処理フロー

### 処理シーケンス

```
1. 引数の検証
   └─ check_dots_empty0: 不正な追加引数のチェック
2. データソースの同期
   └─ auto_copy: 異なるソースの場合のコピー処理
3. 結合設定
   └─ new_join_by(): 空のキー設定
4. 列名処理
   └─ join_cols: 出力列名と重複処理
5. データ複製
   ├─ vec_rep_each(x_out, times = y_size): xの各行をy行数分繰り返し
   └─ vec_rep(y_out, times = x_size): yの全行をx行数分繰り返し
6. 結果構築
   └─ x_out[names(y_out)] <- y_out
7. dplyr_reconstruct: 出力型の復元
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[check_dots_empty0]
    B --> C[auto_copy: yをxのソースにコピー]
    C --> D[new_join_by: 空のキー設定]
    D --> E[join_cols: 列名処理]
    E --> F[x_size = nrow x, y_size = nrow y]
    F --> G[vec_rep_each: xをy行数分繰り返し]
    G --> H[vec_rep: yをx行数分繰り返し]
    H --> I[x_out に y_out の列を追加]
    I --> J[dplyr_reconstruct]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-01 | 全組み合わせ | xの各行とyの各行のすべての組み合わせを生成 | 常に適用 |
| BR-28-02 | 結果行数 | 結果の行数は nrow(x) * nrow(y) | 常に適用 |
| BR-28-03 | キーなし | 結合キーは使用しない | 常に適用 |
| BR-28-04 | 行順序 | xの行順序を維持し、各x行に対してyの全行が続く | 常に適用 |
| BR-28-05 | 列名重複 | 重複する列名にはsuffixを付与 | 列名重複時 |

### 計算ロジック

- **行複製（x）**: `vec_rep_each(x_out, times = y_size)` - xの各行をy行数分繰り返し
- **行複製（y）**: `vec_rep(y_out, times = x_size)` - yの全行をx行数分繰り返し
- **結果行数**: `nrow(x) * nrow(y)`

## データベース操作仕様

### 操作別データベース影響一覧

本機能はインメモリ処理のため、データベース操作は発生しない。ただし、dbplyrバックエンドと連携した場合、SQLのCROSS JOINクエリが生成される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | メモリエラー | 結果行数が大きすぎる場合 | 入力データを削減するか、サンプリングを検討 |

### リトライ仕様

該当なし（同期処理）

## トランザクション仕様

該当なし（インメモリ処理）

## パフォーマンス要件

- 計算量: O(n * m)（nはxの行数、mはyの行数）
- メモリ使用量: n * m 行分のメモリを消費（急激に増加する可能性があるため注意）

## セキュリティ考慮事項

特になし。入力データの機密性は呼び出し側の責任で管理する。

## 備考

- 結果行数がnrow(x) * nrow(y)となるため、大きなデータセットでは注意が必要
- 以前は`left_join(x, y, by = character())`で実現していたが、明示的な関数として1.1.0で導入
- 他の結合タイプ（mutating join）の概念的な基礎となる操作

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | join-cross.R | `R/join-cross.R` | cross_joinのドキュメント（1-42行目） |

**読解のコツ**: cross_joinは「match each row in x to every row in y」という単純な概念。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | join-cross.R | `R/join-cross.R` | cross_join関数本体（43-91行目） |

**主要処理フロー**:
1. **43-45行目**: cross_joinジェネリック関数定義
2. **48-54行目**: cross_join.data.frameメソッドのパラメータ定義
3. **55行目**: check_dots_empty0
4. **57行目**: auto_copy
5. **63行目**: new_join_by() - 空のキー設定
6. **66行目**: keep = FALSE - キー列なしなので影響なし
7. **68-74行目**: join_cols - 列名処理
8. **79-80行目**: vec_size でサイズ取得
9. **85行目**: vec_rep_each - xの各行をy行数分繰り返し
10. **86行目**: vec_rep - yの全行をx行数分繰り返し
11. **88行目**: 列の結合
12. **90行目**: dplyr_reconstruct

### プログラム呼び出し階層図

```
cross_join(x, y, copy, suffix)
    │
    ├─ check_dots_empty0(...)
    │
    ├─ auto_copy(x, y, copy)
    │
    ├─ new_join_by()  # 空のキー設定
    │
    ├─ join_cols(x_names, y_names, by, suffix, keep=FALSE)
    │
    ├─ as_tibble(x/y, .name_repair = "minimal")
    │
    ├─ vec_size(x_in), vec_size(y_in)
    │
    ├─ vec_rep_each(x_out, times = y_size)
    │
    ├─ vec_rep(y_out, times = x_size)
    │
    └─ dplyr_reconstruct(x_out, x)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

x (n行) ──┐
          ├─▶ vec_rep_each(x, y_size) ─▶ x各行をy行数分繰り返し
          │           │
          │           └─▶ n * m 行のx列
          │
y (m行) ──┤
          └─▶ vec_rep(y, x_size) ─▶ y全行をx行数分繰り返し
                      │
                      └─▶ n * m 行のy列
                                │
                                └─▶ 列結合 ─▶ 結果 (n * m 行)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| join-cross.R | `R/join-cross.R` | ソース | cross_join関数の定義 |
| join-cols.R | `R/join-cols.R` | ソース | join_cols関数の定義 |
| join-by.R | `R/join-by.R` | ソース | new_join_by関数の定義 |
