# 機能設計書 37-setequal

## 概要

本ドキュメントは、dplyrパッケージの `setequal()` 関数の機能設計を記述する。この関数は2つのデータフレームが同じ行を含むかを判定する集合演算関数である。

### 本機能の処理概要

`setequal()` は、2つのデータフレーム x と y が（行の順序を無視して）同じ行を含んでいるかを判定し、TRUE または FALSE を返す関数である。これは集合の等価性判定に相当する操作を提供する。

**業務上の目的・背景**：データ分析において、2つのデータセットが実質的に同じ内容を持っているかを確認する必要がある場面がある。例えば、データ移行後の検証、処理結果の確認、異なるソースから取得したデータの一致確認などに使用される。`setequal()` は、base Rの同名関数をジェネリック関数として拡張し、データフレームに対しても適用可能にしている。

**機能の利用シーン**：
- データ移行後の整合性検証
- 異なる処理パスの結果比較
- テストでの期待結果との照合
- バックアップデータの検証

**主要な処理内容**：
1. `check_dots_empty()` で追加引数がないことを確認
2. `check_compatible()` で2つのデータフレームの互換性を検証
3. `vctrs::vec_cast_common()` で共通型にキャスト
4. `vctrs::vec_in()` を使用して双方向の包含関係を検証
5. 両方向ともすべての行が含まれていればTRUEを返す

**関連システム・外部連携**：genericsパッケージからインポートされたジェネリック関数として実装。vctrパッケージの `vec_cast_common()` と `vec_in()` に依存。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

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

## 機能種別

データ操作 / 集合演算 / 比較判定

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | data.frame | Yes | 最初のデータフレーム | データフレームである必要がある |
| y | data.frame | Yes | 2番目のデータフレーム | xと互換性のあるデータフレームである必要がある |
| ... | (空) | No | 使用されない。空であることが必須 | check_dots_empty()でチェック |

### 入力データソース

プログラムからの直接入力（データフレームオブジェクト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (返り値) | logical | xとyが同じ行を含む場合TRUE、そうでない場合FALSE |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. ドット引数の検証
   └─ check_dots_empty()で追加引数がないことを確認

2. 互換性チェック
   └─ check_compatible()でxとyの列名・型の互換性を検証

3. 共通型へのキャスト
   └─ vec_cast_common()でxとyを共通型に変換

4. 包含関係の検証
   └─ vec_in(cast$x, cast$y)でxのすべての行がyに含まれるか確認
   └─ vec_in(cast$y, cast$x)でyのすべての行がxに含まれるか確認

5. 結果の判定
   └─ 両方ともすべてTRUEならば全体としてTRUEを返す

6. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[check_dots_empty]
    B --> C[check_compatible x, y]
    C --> D{互換性あり?}
    D -->|No| E[エラー: 互換性なし]
    D -->|Yes| F[vec_cast_common]
    F --> G[vec_in x in y]
    G --> H[vec_in y in x]
    H --> I{両方向とも全行一致?}
    I -->|Yes| J[TRUE を返却]
    I -->|No| K[FALSE を返却]
    J --> L[終了]
    K --> L
    E --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | 互換性要件 | xとyは同じ列名（順序は異なっても可）と互換性のある型を持つ必要がある | 常時 |
| BR-37-02 | 順序無視 | 行の順序は判定に影響しない | 常時 |
| BR-37-03 | 重複考慮 | 重複行も考慮して判定される（重複の有無が異なればFALSE） | 常時 |
| BR-37-04 | 対称性 | setequal(x, y)とsetequal(y, x)は同じ結果を返す | 常時 |

### 計算ロジック

集合の等価性: `x = y ⟺ (x ⊆ y) ∧ (y ⊆ x)`

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

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

該当なし（インメモリ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 互換性エラー | yがデータフレームでない場合 | データフレームを渡す |
| - | 列数不一致エラー | xとyの列数が異なる場合 | 同じ列数のデータフレームを使用 |
| - | 列名不一致エラー | xとyの列名が一致しない場合 | 同じ列名を持つデータフレームを使用 |
| - | 型不一致エラー | 同名の列で型が互換性を持たない場合 | 型を揃えてから実行 |
| - | ドット引数エラー | ...に引数が渡された場合 | 追加引数を削除 |

### リトライ仕様

該当なし（同期処理）

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

該当なし（インメモリ操作）

## パフォーマンス要件

特に定義なし。vctrパッケージの最適化された実装に依存。

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

特になし

## 備考

- base Rの `setequal()` をジェネリック関数として拡張している
- 既存のベクター向け動作はデフォルトメソッドで保持される
- TRUE/FALSEのみを返し、データフレームを返さない（他の集合演算と異なる）
- 行の順序は無視されるが、重複行の有無は考慮される

---

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

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

### 推奨読解順序

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

互換性チェックと型キャストのロジックを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sets.R | `R/sets.R` | is_compatible関数（162-241行目）の互換性チェックロジック |

**読解のコツ**: `setequal()` は他の集合演算と同様の互換性チェックを行うが、返り値がlogicalである点が異なる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sets.R | `R/sets.R` | setequal.data.frame メソッド（142-148行目） |

**主要処理フロー**:
1. **143行目**: `check_dots_empty()` で追加引数がないことを確認
2. **144行目**: `check_compatible(x, y)` で互換性を検証
3. **146行目**: `vec_cast_common(x = x, y = y)` で共通型にキャスト
4. **147行目**: `all(vec_in(cast$x, cast$y)) && all(vec_in(cast$y, cast$x))` で双方向チェック

#### Step 3: 実装の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sets.R | `R/sets.R` | 147行目の双方向チェックロジック |

**実装の詳細**:
- `vec_cast_common()`: x と y を互換性のある共通型にキャスト
- `vec_in(cast$x, cast$y)`: x の各行が y に存在するかのlogicalベクトル
- `vec_in(cast$y, cast$x)`: y の各行が x に存在するかのlogicalベクトル
- `all()`: すべての要素がTRUEかを判定
- `&&`: 両方の条件が満たされた場合のみTRUE

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

```
setequal(x, y, ...)
    │
    ├─ setequal.data.frame()      [dplyr]
    │      │
    │      ├─ check_dots_empty()  [rlang]
    │      │
    │      ├─ check_compatible()  [dplyr]
    │      │      │
    │      │      └─ is_compatible()
    │      │
    │      ├─ vec_cast_common()   [vctrs]
    │      │
    │      ├─ vec_in()            [vctrs] x2
    │      │
    │      └─ all()               [base] x2
    │
    └─ setequal.default()         [base] (ベクター用)
```

### データフロー図

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

データフレーム x ─┐
                  │
                  ├───▶ setequal() ───▶ TRUE または FALSE
                  │     (双方向 vec_in)
データフレーム y ─┘

例:
x = {A, B, C}
y = {C, A, B}  （順序が異なる）
setequal(x, y) = TRUE

x = {A, B, C}
y = {A, B}
setequal(x, y) = FALSE
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sets.R | `R/sets.R` | ソース | setequal.data.frame実装、互換性チェック |
| generics.R | `R/generics.R` | ソース | ジェネリック関数のインポート |
