# 機能設計書 7-mutate

## 概要

本ドキュメントは、dplyrパッケージの`mutate`関数に関する機能設計書です。`mutate`関数は、データフレームに新しい列を作成したり、既存の列を変更したりする機能を提供します。

### 本機能の処理概要

`mutate`関数は、データフレームに対して列の作成・変更・削除を行うデータ操作関数です。既存の列を使った計算式を指定することで、新しい列を作成したり、既存の列の値を更新したりできます。グループ化されたデータでは、各グループ内で独立して計算が行われます。

**業務上の目的・背景**：データ分析において、既存のデータから派生列を作成することは最も基本的な操作の一つです。単価と数量から売上を計算したり、日付から曜日を抽出したりといった加工処理に使用します。SQLのSELECT式における計算列や、ALTER TABLE ADD COLUMNに相当する機能を提供します。

**機能の利用シーン**：
- 既存列から計算列を作成（例：売上 = 単価 * 数量）
- 列の変換（例：文字列を大文字に変換）
- 条件分岐による値の設定（if_else、case_whenと組み合わせ）
- グループ内での集計値の付与（例：グループ平均）
- 不要な列の削除（NULLを設定）

**主要な処理内容**：
1. 引数の解析とquosure変換
2. グループ化情報の計算（`.by`引数または既存のグループ化）
3. `mutate_cols`で各式を順次評価
4. `across`や`pick`の展開
5. 結果列の`dplyr_col_modify`による適用
6. `.keep`、`.before`、`.after`による列の選択・配置

**関連システム・外部連携**：
- vctrs: ベクトル操作基盤
- rlang: quosureとデータマスキング機能

**権限による制御**：該当なし（Rライブラリのため）

## 関連画面

本プロジェクトはRライブラリ（dplyr）であり、ユーザーインターフェース画面は存在しません。

## 機能種別

データ操作（列の作成・変更）/ データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| .data | data.frame | Yes | 処理対象のデータフレーム | data.frameまたはその派生クラス |
| ... | expressions | No | 列を作成・変更する式（name = value形式） | - |
| .by | tidy-select | No | 一時的なグループ化に使用する列 | - |
| .keep | character | No | 保持する列（"all", "used", "unused", "none"） | - |
| .before | tidy-select | No | 新しい列の挿入位置（前） | - |
| .after | tidy-select | No | 新しい列の挿入位置（後） | - |

### 入力データソース

- メモリ上のdata.frame、tibble、grouped_df、rowwise_df

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | .dataと同じ型 | 列が変更されたデータフレーム |

### 出力先

- 関数の戻り値として返却（メモリ上）

## 処理フロー

### 処理シーケンス

```
1. 引数の解析
   └─ .keep引数のバリデーション
   └─ compute_by()でグループ化情報を計算
2. mutate_cols()の実行
   └─ DataMask$new()でデータマスクを作成
   └─ 各式を順次評価（逐次評価：前の結果を参照可能）
   └─ across/pickの展開
   └─ 結果のリサイクル・型チェック
3. dplyr_col_modify()で列を適用
4. mutate_relocate()で列位置を調整（.before/.after）
5. mutate_keep()で保持する列を選択（.keep）
```

### フローチャート

```mermaid
flowchart TD
    A[mutate開始] --> B[.keep検証]
    B --> C[compute_by]
    C --> D[mutate_cols]
    D --> E[DataMask作成]
    E --> F[各式を順次評価]
    F --> G{across/pick?}
    G -->|Yes| H[展開処理]
    G -->|No| I[結果計算]
    H --> I
    I --> J[dplyr_col_modify]
    J --> K{.before/.after?}
    K -->|Yes| L[mutate_relocate]
    K -->|No| M[mutate_keep]
    L --> M
    M --> N[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 行数の不変 | 行数は変更されない | 常時 |
| BR-02 | 逐次評価 | 後の式は前の式の結果を参照可能 | 常時 |
| BR-03 | NULL設定で削除 | 列にNULLを設定すると削除される | 常時 |
| BR-04 | グループ内評価 | グループ化データでは各グループ内で計算 | grouped_df使用時 |
| BR-05 | リサイクル | 長さ1のベクトルは全行にリサイクル | 常時 |
| BR-06 | グループ変数の保持 | .keepの設定に関わらずグループ変数は保持 | grouped_df使用時 |

### 計算ロジック

- 式は左から右に順次評価
- 結果のサイズはグループサイズ（または全体行数）に一致する必要がある
- データフレームを返す式は複数列として展開される

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | dplyr:::mutate_incompatible_size | 結果サイズが行数と一致しない | サイズを調整 |
| - | dplyr:::mutate_mixed_null | グループ間でNULLと非NULLが混在 | 一貫した型を返す |
| - | dplyr:::mutate_not_vector | 結果がベクトルでない | ベクトルを返す式に修正 |

### リトライ仕様

該当なし（同期処理のため）

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

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

## パフォーマンス要件

- 大規模データセットに対しても効率的に動作
- グループ化データでは各グループで並列ではなく逐次処理

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

- 入力データの検証はdplyrフレームワーク内で実施

## 備考

- `transmute()`は`mutate(.keep = "none")`と同等で非推奨
- rowwise_dfでは行ごとに式が評価される

---

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

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

### 推奨読解順序

#### Step 1: mutate関数の基本構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mutate.R | `R/mutate.R` | mutate関数の定義と基本フロー |

**読解のコツ**: mutate関数はdplyrの中核機能の一つで、多くの内部関数を使用している。

**主要処理フロー**:
- **145-147行目**: mutate関数定義（ジェネリック関数）
- **171-209行目**: mutate.data.frame実装

#### Step 2: 列計算の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mutate.R | `R/mutate.R` | mutate_cols関数 |

**主要処理フロー**:
- **253-301行目**: mutate_cols関数
- **259行目**: DataMask作成
- **271-289行目**: 各式を順次評価（withCallingHandlers）

#### Step 3: 個別列計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mutate.R | `R/mutate.R` | mutate_col関数 |

**主要処理フロー**:
- **303-468行目**: mutate_col関数
- **308-309行目**: expand_pick, expand_across
- **329-388行目**: シンボル/定数の最適化処理
- **390-423行目**: 第1パス - 式の評価
- **427-465行目**: 第2パス - 結果の統合

#### Step 4: 列の配置・保持を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mutate.R | `R/mutate.R` | mutate_relocate, mutate_keep関数 |

**主要処理フロー**:
- **213-232行目**: mutate_relocate関数
- **234-251行目**: mutate_keep関数

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

```
mutate(.data, ..., .by, .keep, .before, .after)
    │
    └─ UseMethod("mutate")
           │
           └─ mutate.data.frame(.data, ..., .by, .keep, .before, .after)
                  │
                  ├─ compute_by(.by, .data)
                  │
                  ├─ mutate_cols(.data, dplyr_quosures(...), by)
                  │      │
                  │      ├─ DataMask$new(data, by, "mutate")
                  │      │
                  │      └─ for each dot:
                  │             └─ mutate_col(dot, data, mask, new_columns)
                  │                    │
                  │                    ├─ expand_pick(dot, mask)
                  │                    ├─ expand_across(dot)
                  │                    │
                  │                    ├─ (symbol) ? 既存値を参照
                  │                    ├─ (constant) ? リサイクル
                  │                    └─ (expression) ? mask$eval_all_mutate(quo)
                  │
                  ├─ dplyr_col_modify(.data, cols)
                  │
                  ├─ mutate_relocate(out, .before, .after)
                  │      └─ relocate(out, all_of(names), ...)
                  │
                  └─ mutate_keep(out, .keep, used, names_new, names_groups)
                         └─ dplyr_col_select(out, names_out)
```

### データフロー図

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

.data (data.frame)  ───▶ DataMask作成 ───▶ 各式を評価 ───▶ 新列リスト
      │                       │                  │              │
      │                       ▼                  ▼              ▼
      │              グループ情報          逐次評価結果      cols
      │                       │                  │              │
      └───────────────────────┴──────────────────┴──────────────┘
                                                                │
                                                                ▼
                                                      dplyr_col_modify
                                                                │
                                                                ▼
                                               mutate_relocate / mutate_keep
                                                                │
                                                                ▼
                                                        結果data.frame
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mutate.R | `R/mutate.R` | ソース | mutate関数の実装 |
| data-mask.R | `R/data-mask.R` | ソース | DataMaskクラスの定義 |
| generics.R | `R/generics.R` | ソース | dplyr_col_modify |
| colwise.R | `R/colwise.R` | ソース | across関連の実装 |
| relocate.R | `R/relocate.R` | ソース | relocate関数 |
| transmute.R | `R/transmute.R` | ソース | transmute関数（非推奨） |
