# 機能設計書 6-select

## 概要

本ドキュメントは、dplyrパッケージの`select`関数に関する機能設計書です。`select`関数は、データフレームから列を選択し、オプションでリネームする機能を提供します。

### 本機能の処理概要

`select`関数は、tidy-select構文を使用してデータフレームから列を選択するデータ操作関数です。列名、列位置、列の範囲（`a:z`）、ヘルパー関数（`starts_with()`、`where()`等）を使用して柔軟に列を指定できます。選択と同時にリネームも可能です（`new_name = old_name`構文）。

**業務上の目的・背景**：データ分析において、必要な列のみを抽出することは基本的かつ重要な操作です。SQLのSELECT句に相当する機能を提供し、tidyverse流の簡潔な構文で列の選択・リネームが可能です。特に多数の列を持つデータフレームから、分析に必要な列のみを取り出す際に有用です。

**機能の利用シーン**：
- 分析に必要な列のみを抽出
- 列名のリネーム
- 特定のパターンを持つ列の選択（例：数値列のみ）
- 列の順序変更

**主要な処理内容**：
1. tidy-select式の評価（`tidyselect::eval_select`）
2. グループ化変数の保持確認
3. 列のサブセット化（`dplyr_col_select`）
4. 列名の設定（リネーム対応）

**関連システム・外部連携**：
- tidyselect: tidy-select構文のパース・評価
- rlang: quosureとデータマスキング機能

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

## 関連画面

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

## 機能種別

データ操作（列の選択）/ データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| .data | data.frame | Yes | 処理対象のデータフレーム | data.frameまたはその派生クラス |
| ... | tidy-select | No | 選択する列の指定（tidy-select構文） | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | .dataと同じ型 | 選択された列を含むデータフレーム |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. tidy-select式の評価
   └─ tidyselect::eval_select()でカラム位置を取得
2. グループ化変数の確認
   └─ ensure_group_vars()で欠落したグループ変数を先頭に追加
3. 列のサブセット化
   └─ dplyr_col_select()で列を選択
4. 列名の設定
   └─ set_names()でリネームを適用
```

### フローチャート

```mermaid
flowchart TD
    A[select開始] --> B[UseMethod dispatch]
    B --> C[select.data.frame]
    C --> D[tidyselect::eval_select]
    D --> E{grouped_df?}
    E -->|Yes| F[ensure_group_vars]
    E -->|No| G[dplyr_col_select]
    F --> G
    G --> H[set_names]
    H --> I[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 行の不変 | 行は影響を受けない | 常時 |
| BR-02 | グループ変数の保持 | グループ化変数は自動的に保持される | grouped_df使用時 |
| BR-03 | 列順序の指定 | 出力列の順序は選択順に従う | 常時 |
| BR-04 | リネーム構文 | `new_name = old_name`でリネーム可能 | - |
| BR-05 | 属性の保持 | データフレーム属性は保持される | 常時 |

### 計算ロジック

- tidy-select構文で列位置を計算
- グループ変数が選択されていない場合、自動的に先頭に追加
- リネーム指定があれば新しい名前を適用

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | abort | listに対してselectを呼び出した場合 | data.frameを使用 |
| - | tidyselect error | 存在しない列を指定した場合 | 正しい列名を指定 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 列の選択のみのため非常に高速
- 行データのコピーは最小限

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

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

## 備考

- tidy-select構文は`?dplyr_tidy_select`で詳細を確認可能
- ヘルパー関数: `starts_with()`, `ends_with()`, `contains()`, `matches()`, `num_range()`, `where()`, `everything()`, `last_col()`等

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: select関数は非常にシンプルで、主な処理はtidyselectパッケージに委譲されている。

**主要処理フロー**:
- **53-55行目**: select関数定義（ジェネリック関数）
- **62-76行目**: select.data.frame実装

#### Step 2: tidyselectとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.R | `R/select.R` | eval_selectの呼び出し |

**主要処理フロー**:
- **65-69行目**: tidyselect::eval_select()でカラム位置を取得
- expr(c(...))で複数の選択式を結合

#### Step 3: グループ変数の保持を理解する

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

**主要処理フロー**:
- **80-102行目**: ensure_group_vars関数
- **81行目**: グループ変数の位置を取得
- **84-98行目**: 欠落したグループ変数を先頭に追加

#### Step 4: 列選択の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | generics.R | `R/generics.R` | dplyr_col_select関数 |

**主要処理フロー**:
- **224-264行目**: dplyr_col_select関数
- 1次元の`[`演算子で列を選択
- 属性の復元処理

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

```
select(.data, ...)
    │
    └─ UseMethod("select")
           │
           ├─ select.list  → abort("select() doesn't handle lists.")
           │
           └─ select.data.frame(.data, ...)
                  │
                  ├─ tidyselect::eval_select(expr(c(...)), data)
                  │      └─ tidy-select構文をパースし列位置を返す
                  │
                  ├─ ensure_group_vars(loc, .data, notify = TRUE)
                  │      └─ グループ変数が欠落していれば先頭に追加
                  │
                  ├─ dplyr_col_select(.data, loc)
                  │      └─ .data[loc]で列を選択
                  │
                  └─ set_names(out, names(loc))
                         └─ リネーム適用
```

### データフロー図

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

.data (data.frame)  ───▶ tidy-select評価 ───▶ グループ変数確認 ───▶ 列選択
      │                       │                      │               │
      │                       ▼                      ▼               ▼
      │                  loc (integer)        loc補完        .data[loc]
      │                       │                      │               │
      └───────────────────────┴──────────────────────┴───────────────┘
                                                                     │
                                                                     ▼
                                                              set_names
                                                                     │
                                                                     ▼
                                                            結果data.frame
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.R | `R/select.R` | ソース | select関数の実装 |
| generics.R | `R/generics.R` | ソース | dplyr_col_select |
| select-helpers.R | `R/select-helpers.R` | ソース | tidyselectヘルパーの再エクスポート |
| colwise-select.R | `R/colwise-select.R` | ソース | select_at/if/all（非推奨） |
