# 機能設計書 10-rename_with

## 概要

本ドキュメントは、dplyrパッケージの`rename_with`関数に関する機能設計書です。`rename_with`関数は、関数を使用してデータフレームの列名を変更する機能を提供します。

### 本機能の処理概要

`rename_with`関数は、指定した関数を列名に適用して新しい列名を生成するデータ操作関数です。`toupper`や`tolower`のような変換関数、またはカスタムのラムダ関数を使用して、選択した列の名前を一括変更できます。

**業務上の目的・背景**：データ分析において、列名の一括変換は頻繁に必要とされる操作です。全ての列名を大文字/小文字に変換したり、特定のパターンで接頭辞/接尾辞を追加したりする際に使用します。`rename`関数が個別の列名変更に適しているのに対し、`rename_with`はパターンベースの一括変更に適しています。

**機能の利用シーン**：
- 全列名を大文字/小文字に統一
- 列名にプレフィックス/サフィックスを追加
- 列名から特定の文字を置換（例：ピリオドをアンダースコアに）
- 特定のパターンに一致する列のみを変換

**主要な処理内容**：
1. 関数の変換（`as_function`でラムダ関数対応）
2. 対象列の選択（tidy-select構文）
3. 選択した列名に関数を適用
4. 結果のバリデーション（文字ベクトル、同じ長さ）
5. 名前の一意性チェック
6. `set_names`による名前の適用

**関連システム・外部連携**：
- tidyselect: 列選択機能
- rlang: ラムダ関数サポート（`as_function`）

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

## 関連画面

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

## 機能種別

データ操作（列名の一括変更）/ データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| .data | data.frame | Yes | 処理対象のデータフレーム | data.frameまたはその派生クラス |
| .fn | function | Yes | 列名を変換する関数 | 文字ベクトルを返す関数 |
| .cols | tidy-select | No | 対象列の選択（デフォルト: everything()） | - |
| ... | - | No | .fnに渡す追加引数 | - |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 関数の準備
   └─ as_function(.fn)でラムダ関数をサポート
2. 対象列の選択
   └─ tidyselect::eval_select()で列位置を取得
3. 関数の適用
   └─ .fn(列名, ...)で新しい名前を生成
4. 結果のバリデーション
   └─ 文字ベクトルであること
   └─ 入力と同じ長さであること
5. 名前の更新
   └─ vec_assign()で該当位置を更新
   └─ vec_as_names()で一意性チェック
6. 名前の適用
   └─ set_names()で新しい名前を設定
```

### フローチャート

```mermaid
flowchart TD
    A[rename_with開始] --> B[UseMethod dispatch]
    B --> C[rename_with.data.frame]
    C --> D[as_function]
    D --> E[eval_select]
    E --> F[.fn適用]
    F --> G{文字ベクトル?}
    G -->|No| H[エラー: must return character]
    G -->|Yes| I{同じ長さ?}
    I -->|No| J[エラー: wrong length]
    I -->|Yes| K[vec_assign]
    K --> L[vec_as_names]
    L --> M[set_names]
    M --> N[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 行の不変 | 行は影響を受けない | 常時 |
| BR-02 | 列順序の保持 | 列の順序は変更されない | 常時 |
| BR-03 | デフォルト全列 | .cols省略時は全列が対象 | .cols未指定時 |
| BR-04 | 一意性必須 | 結果の列名は一意である必要がある | 常時 |
| BR-05 | 同一長さ | 関数は入力と同じ長さを返す必要がある | 常時 |

### 計算ロジック

- `.fn`は列名のベクトルを受け取り、同じ長さの文字ベクトルを返す
- `~`構文（ラムダ関数）をサポート（例：`~ paste0("prefix_", .x)`）
- 追加引数は`.fn`に渡される

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | cli_abort | .fnが文字ベクトルを返さない場合 | 文字ベクトルを返す関数を使用 |
| - | cli_abort | .fnの結果長が異なる場合 | 入力と同じ長さを返す関数を使用 |
| - | vctrs error | 重複する名前が発生した場合 | 一意な名前になるよう関数を調整 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 列名の変更のみのため非常に高速
- データのコピーは発生しない

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

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

## 備考

- `paste0`を使用する際は`recycle0 = TRUE`を指定することで空選択時のエラーを回避可能
- tidyselect構文で特定の列のみを対象にできる（例：`starts_with("Sepal")`）

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: rename_with関数はrenameと同じファイルで定義されており、関数適用とバリデーションが主な処理。

**主要処理フロー**:
- **83-85行目**: rename_with関数定義（ジェネリック関数）
- **88-112行目**: rename_with.data.frame実装

#### Step 2: 関数変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rename.R | `R/rename.R` | as_functionの使用 |

**主要処理フロー**:
- **89行目**: as_function(.fn) - ラムダ関数（~構文）をサポート

#### Step 3: 列選択と関数適用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rename.R | `R/rename.R` | eval_selectと.fn適用 |

**主要処理フロー**:
- **90行目**: tidyselect::eval_select - 対象列の選択
- **94行目**: vec_slice - 選択した列名を取得
- **95行目**: .fn(sel, ...) - 関数を適用

#### Step 4: バリデーションと名前適用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | rename.R | `R/rename.R` | バリデーションロジック |

**主要処理フロー**:
- **97-100行目**: 文字ベクトルチェック
- **102-105行目**: 長さチェック
- **108行目**: vec_assign - 名前配列の更新
- **109行目**: vec_as_names - 一意性チェック

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

```
rename_with(.data, .fn, .cols, ...)
    │
    └─ UseMethod("rename_with")
           │
           └─ rename_with.data.frame(.data, .fn, .cols, ...)
                  │
                  ├─ as_function(.fn)
                  │      └─ ラムダ関数（~）をサポート
                  │
                  ├─ tidyselect::eval_select(enquo(.cols), .data)
                  │      └─ 対象列の位置を取得
                  │
                  ├─ names <- names(.data)
                  │
                  ├─ sel <- vec_slice(names, cols)
                  │
                  ├─ new <- .fn(sel, ...)
                  │      └─ 関数を適用
                  │
                  ├─ バリデーション
                  │      ├─ is_character(new) ?
                  │      └─ length(new) == length(sel) ?
                  │
                  ├─ names <- vec_assign(names, cols, new)
                  │
                  ├─ names <- vec_as_names(names, repair = "check_unique")
                  │
                  └─ set_names(.data, names)
```

### データフロー図

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

.data (data.frame)  ───▶ 列選択 ───▶ 関数適用 ───▶ バリデーション
      │                      │            │              │
      │                      ▼            ▼              ▼
      │                 cols位置      new名前     型・長さチェック
      │                      │            │              │
      └──────────────────────┴────────────┴──────────────┘
                                                         │
                                                         ▼
                                                   vec_assign
                                                         │
                                                         ▼
                                                   vec_as_names
                                                   (一意性チェック)
                                                         │
                                                         ▼
                                                   set_names
                                                         │
                                                         ▼
                                                 結果data.frame
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| rename.R | `R/rename.R` | ソース | rename_with関数の実装 |
| select-helpers.R | `R/select-helpers.R` | ソース | tidyselectヘルパーの再エクスポート |
