# 機能設計書 73-recode

## 概要

本ドキュメントは、dplyrパッケージの`recode()`関数に関する機能設計書です。`recode()`は、ベクトル内の値を別の値にマッピング（再コード化）するための関数です。

### 本機能の処理概要

`recode()`関数は、Rの`switch()`関数のベクトル化バージョンとして機能し、数値を位置または名前に基づいて、文字列や因子を名前に基づいて置換します。

**業務上の目的・背景**：データ分析において、カテゴリカル変数の値を別の値に変換する必要は頻繁に発生します。例えば、コード値をラベルに変換したり、値のグループ化（リコーディング）を行う場合です。`recode()`は、このような値の変換を簡潔に記述できるよう設計されました。ただし、dplyr 1.1.0以降では非推奨（superseded）となり、`recode_values()`や`replace_values()`への移行が推奨されています。

**機能の利用シーン**：
- カテゴリカル変数のラベル変換
- コード値から説明的な値への変換
- 値のグループ化・統合
- 欠損値の特別な処理

**主要な処理内容**：
1. 入力ベクトルの型に基づいてS3メソッドをディスパッチ
2. 置換ルールに基づいて各値をマッピング
3. 未置換値に対するデフォルト値または欠損値の処理
4. 結果ベクトルの返却

**関連システム・外部連携**：外部システムとの連携はありません。dplyr内部で完結する機能です。

**権限による制御**：特になし。Rの関数として公開されており、dplyrをロードした任意のユーザーが使用可能です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはRライブラリであり、ユーザーインターフェース画面は存在しません |

## 機能種別

値変換 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| .x | vector | Yes | 変換対象のベクトル（numeric/character/factor） | NULLでないこと |
| ... | dynamic-dots | Yes | 置換ルール。名前付き引数で指定 | 少なくとも1つは必要 |
| .default | any | No | 未マッチ値のデフォルト値 | 長さ1または.xと同じ長さ |
| .missing | any | No | NA値の置換値 | 長さ1または.xと同じ長さ |

### 入力データソース

関数の引数として直接渡されるベクトル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vector | .xと同じ長さで、置換後の値を含むベクトル。型は置換値の型に依存 |

### 出力先

呼び出し元のR環境に返却されます。

## 処理フロー

### 処理シーケンス

```
1. superseded警告の発行
   └─ lifecycle::signal_stage()でsupersededであることを通知
2. S3メソッドディスパッチ
   └─ UseMethod("recode")で.xの型に応じたメソッドを呼び出し
3. 型別の処理（numeric/character/factor）
   └─ 各型に応じた置換ロジックを実行
4. デフォルト値と欠損値の処理
   └─ .defaultと.missingによる補完処理
5. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[recode呼び出し] --> B[superseded警告を発行]
    B --> C{.xの型は?}
    C -->|numeric| D[recode.numeric]
    C -->|character| E[recode.character]
    C -->|factor| F[recode.factor]
    D --> G[位置または名前ベースの置換]
    E --> H[名前ベースの置換]
    F --> I[名前ベースの置換 + レベル更新]
    G --> J[.defaultの適用]
    H --> J
    I --> J
    J --> K[.missingの適用]
    K --> L[結果を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | 型別ディスパッチ | numeric/character/factorで異なる処理 | 常時 |
| BR-73-02 | 名前必須（文字列） | character型では置換値は名前付きでなければならない | character型の.x |
| BR-73-03 | 位置指定可能（数値） | numeric型では位置または名前で指定可能 | numeric型の.x |
| BR-73-04 | 未マッチ警告 | 未置換値がありdefaultなしの場合警告 | .defaultがnullで型が非互換 |
| BR-73-05 | factor特別処理 | factorではレベルが更新される | factor型の.x |

### 計算ロジック

**numeric型の場合**:
- 名前付き引数: 名前を数値に変換し、その値にマッチする要素を置換
- 名前なし引数: 位置（1, 2, 3, ...）にマッチする要素を置換

**character型の場合**:
- 名前付き引数の名前にマッチする要素を対応する値で置換

**factor型の場合**:
- レベルに対して置換を適用し、新しいレベルでfactorを再構成

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

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

本機能はデータベースを直接操作しません。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | メモリ内データの操作のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | 置換ルールが指定されていない | 少なくとも1つの置換ルールを指定 |
| - | エラー | character/factorで名前なし引数がある | すべての引数に名前を付ける |
| - | エラー | factorで.missingが指定された | .missingは使用不可 |
| - | 警告 | 未置換値がありデフォルトがない | .defaultを指定するか全値を網羅 |

### リトライ仕様

リトライ機構はありません。

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

トランザクション管理はありません（メモリ内操作のため）。

## パフォーマンス要件

- 線形時間計算量（O(n)）で動作
- 大規模ベクトルでもメモリ効率的に処理

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

特別なセキュリティ考慮事項はありません。

## 備考

- dplyr 1.1.0でsuperseded（非推奨）となりました
- `recode_values()`と`replace_values()`への移行が推奨されています
- `!!!`演算子を使用してルックアップテーブルを展開可能
- 因子の再コード化には`forcats::fct_recode()`も検討してください

---

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

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

### 推奨読解順序

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

まず、入出力の型とS3ディスパッチの仕組みを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | recode.R | `R/recode.R` | S3ジェネリック関数の構造、各型のメソッド定義 |

**読解のコツ**: `UseMethod()`によるS3ディスパッチの仕組みを理解しておくと、コードの流れが把握しやすくなります。

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

処理の起点となる関数を特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | recode.R | `R/recode.R` | recode関数のジェネリック定義（170-174行目） |

**主要処理フロー**:
1. **170-174行目**: recodeジェネリック関数の定義。superseded警告を発行しUseMethodでディスパッチ

#### Step 3: 型別メソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | recode.R | `R/recode.R` | recode.numeric（177-204行目） - 数値型の処理 |
| 3-2 | recode.R | `R/recode.R` | recode.character（207-230行目） - 文字列型の処理 |
| 3-3 | recode.R | `R/recode.R` | recode.factor（233-272行目） - 因子型の処理 |

**主要処理フロー（recode.numeric）**:
- **178行目**: list2(...)で動的引数を取得
- **180-188行目**: 名前の有無で位置指定か名前指定かを判断
- **195-198行目**: ループで各置換ルールを適用
- **200-203行目**: .defaultと.missingを適用

**主要処理フロー（recode.character）**:
- **208行目**: .xを文字列に変換
- **210-214行目**: 名前なし引数のバリデーション
- **221-224行目**: ループで名前ベースの置換を適用

**主要処理フロー（recode.factor）**:
- **235-237行目**: 置換ルールの存在確認
- **239-247行目**: 名前と.missingのバリデーション
- **254-262行目**: レベルに対して置換を適用
- **266-271行目**: 文字列の場合はレベル更新、それ以外は値抽出

#### Step 4: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | recode.R | `R/recode.R` | find_template（274-287行目） - 出力型の決定 |
| 4-2 | recode.R | `R/recode.R` | validate_recode_default（289-301行目） - デフォルト値の検証 |
| 4-3 | recode.R | `R/recode.R` | replace_with（359-384行目） - 値の置換処理 |

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

```
recode(.x, ...) [R/recode.R:170-174]
    │
    ├─ lifecycle::signal_stage() [外部パッケージ]
    │      └─ superseded警告を発行
    │
    └─ UseMethod("recode")
           │
           ├─ recode.numeric() [R/recode.R:177-204]
           │      ├─ list2(...) [rlang]
           │      ├─ have_name() [rlang]
           │      ├─ find_template() [R/recode.R:274-287]
           │      ├─ replace_with() [R/recode.R:359-384]
           │      └─ validate_recode_default() [R/recode.R:289-301]
           │
           ├─ recode.character() [R/recode.R:207-230]
           │      ├─ list2(...) [rlang]
           │      ├─ have_name() [rlang]
           │      ├─ find_template() [R/recode.R:274-287]
           │      ├─ replace_with() [R/recode.R:359-384]
           │      └─ validate_recode_default() [R/recode.R:289-301]
           │
           └─ recode.factor() [R/recode.R:233-272]
                  ├─ list2(...) [rlang]
                  ├─ have_name() [rlang]
                  ├─ find_template() [R/recode.R:274-287]
                  ├─ replace_with() [R/recode.R:359-384]
                  └─ validate_recode_default() [R/recode.R:289-301]
```

### データフロー図

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

.x (vector) ─────────────▶ UseMethod("recode")
                                │
                                ▼
                          型に応じたメソッド
                                │
                                ▼
... (置換ルール) ─────────▶ find_template()
                                │ 出力型を決定
                                ▼
                          replace_with() × n回
                                │ 各ルールを適用
                                ▼
.default ─────────────────▶ validate_recode_default()
                                │ デフォルト値を適用
                                ▼
.missing ─────────────────▶ replace_with()
                                │ NA値を置換
                                ▼
                           結果ベクトル ───────────▶ 呼び出し元
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| recode.R | `R/recode.R` | ソース | recode/recode_factor関数の実装 |
| recode-values.R | `R/recode-values.R` | ソース | 後継関数recode_values/replace_valuesの実装 |
| test-recode.R | `tests/testthat/test-recode.R` | テスト | recodeのテストケース |
| test-recode-values.R | `tests/testthat/test-recode-values.R` | テスト | 後継関数のテストケース |
