# 機能設計書 39-c_across

## 概要

本ドキュメントは、dplyrパッケージの `c_across()` 関数の機能設計を記述する。この関数は `rowwise()` と組み合わせて使用し、行ごとに複数の列の値を1つのベクトルに結合する。

### 本機能の処理概要

`c_across()` は、指定された列の値を現在の行で結合し、1つのベクトルとして返す関数である。主に `rowwise()` で行ごとのグループ化が行われたデータフレームに対して、行単位の集計（行ごとの合計、平均など）を行う際に使用される。

**業務上の目的・背景**：データ分析において、行方向の集計が必要な場面がある。例えば、各レコードの複数の測定値の平均、行ごとの最大値・最小値、複数の特徴量を結合した計算などが該当する。通常の `c()` では tidy-select 構文が使えないが、`c_across()` を使用することで、柔軟な列選択と行ごとのベクトル結合が可能になる。また、`vctrs::vec_c()` を内部で使用することで、型の安全性が保証される。

**機能の利用シーン**：
- 行ごとの合計・平均の計算
- 行ごとの最大値・最小値の取得
- 複数列の値を使った行単位の計算
- 行ごとの条件判定（いずれかの値がNAか等）

**主要な処理内容**：
1. データマスクを取得
2. 列選択（cols）をtidyselectで評価
3. 現在の行の選択された列の値を取得
4. `vctrs::vec_c()` で値を結合してベクトルを返す

**関連システム・外部連携**：tidyselectパッケージの `eval_select()` に依存。vctrパッケージの `vec_c()` に依存。

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

## 関連画面

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

## 機能種別

データ操作 / 行方向結合

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cols | tidy-select | Yes（推奨） | 結合する列の選択。省略時はすべての列が選択されるが、非推奨警告が出る | tidyselect構文に従う |

### 入力データソース

データマスク環境（通常は `rowwise()` されたデータフレームの `mutate()` 内から呼び出される）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (返り値) | vector | 選択された列の値を結合したベクトル。各呼び出しで現在の行の値のみが含まれる |

### 出力先

呼び出し元への戻り値として返却（通常は`sum()`や`mean()`などの関数に渡される）

## 処理フロー

### 処理シーケンス

```
1. データマスクの取得
   └─ peek_mask()で現在のデータマスクを取得

2. 列選択のクォート
   └─ enquo(cols)で列選択式をクォート

3. 列選択の評価
   └─ c_across_setup()で列名を取得
   └─ tidyselect::eval_select()で評価

4. 現在の行の値を取得
   └─ mask$current_cols(vars)で値を取得

5. ベクトルの結合
   └─ vec_c()で値を結合
   └─ .name_spec = zap()で名前を削除

6. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[peek_mask でマスク取得]
    B --> C[cols をクォート]
    C --> D{cols が指定されたか}
    D -->|No| E[非推奨警告を発行]
    E --> F[everything を使用]
    D -->|Yes| F
    F --> G[c_across_setup で列を取得]
    G --> H[mask$current_cols で値を取得]
    H --> I[vec_c で結合]
    I --> J[ベクトルを返却]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | 行単位評価 | `rowwise()` と組み合わせて使用し、各行で個別に評価される | rowwiseデータの場合 |
| BR-39-02 | 型安全性 | `vec_c()` により、異なる型の列は安全に結合される | 常時 |
| BR-39-03 | 列選択必須 | cols の省略は非推奨（バージョン1.1.0から警告） | cols が省略された場合 |
| BR-39-04 | 名前削除 | 結果のベクトルからは列名が削除される | 常時 |

### 計算ロジック

行ごとに選択された列の値を結合: `vec_c(col1[row], col2[row], ..., colN[row])`

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 列名エラー | colsで存在しない列を指定した場合 | 正しい列名を指定 |
| - | 型変換エラー | 結合できない型の列を指定した場合 | 型を揃えるか、適切な列を選択 |

### リトライ仕様

該当なし（同期処理）

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

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

## パフォーマンス要件

特に定義なし。行ごとに呼び出されるため、大量のデータでは遅くなる可能性がある。

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

特になし

## 備考

- `across()` がtibbleを返すのに対し、`c_across()` はベクトルを返す
- `rowwise()` と組み合わせて使用することが想定されている
- 列名の省略は非推奨であり、明示的に指定することが推奨される
- `vctrs::vec_c()` により型の安全性が保証される

---

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

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

### 推奨読解順序

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

rowwiseデータとデータマスクの仕組みを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | rowwise.R | `R/rowwise.R` | rowwise()の実装と行ごとの評価 |
| 1-2 | data-mask.R | `R/data-mask.R` | データマスクの実装 |

**読解のコツ**: `c_across()` は `rowwise()` されたデータフレームで使用され、各行で個別に評価される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | across.R | `R/across.R` | c_across関数本体（397-410行目） |

**主要処理フロー**:
1. **398行目**: `peek_mask()` でデータマスクを取得
2. **399行目**: `enquo(cols)` で列選択式をクォート
3. **401-404行目**: cols が省略された場合の警告と everything() への置換
4. **406行目**: `c_across_setup()` で列名を取得
5. **408行目**: `mask$current_cols(vars)` で値を取得
6. **409行目**: `vec_c(!!!cols, .name_spec = zap())` で結合

#### Step 3: セットアップ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | across.R | `R/across.R` | c_across_setup関数（546-564行目） |

**主要処理フロー**:
- **547行目**: `enquo(cols)` でクォート
- **551行目**: `quo_set_env_to_data_mask_top()` で環境を調整
- **553行目**: `mask$get_current_data(groups = FALSE)` でデータを取得
- **555-560行目**: `tidyselect::eval_select()` で列を評価

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

```
c_across(cols)
    │
    ├─ peek_mask()                      [dplyr]
    │
    ├─ enquo()                          [rlang]
    │
    ├─ c_across_missing_cols_deprecate_warn() [dplyr] (必要な場合)
    │
    ├─ c_across_setup()                 [dplyr]
    │      │
    │      ├─ quo_set_env_to_data_mask_top()
    │      │
    │      └─ tidyselect::eval_select() [tidyselect]
    │
    ├─ mask$current_cols()              [dplyr]
    │
    └─ vec_c()                          [vctrs]
```

### データフロー図

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

rowwiseデータ ─────────▶ mutate ─────────────────────▶ 結果列追加
     │                      │
     │                      ▼
     │                 c_across()
     │                      │
     │     ┌────────────────┼────────────────┐
     │     ▼                ▼                ▼
     └──▶ 列w[行i]       列x[行i]        列y[行i]
              │                │                │
              └────────────────┼────────────────┘
                               ▼
                          vec_c()
                               │
                               ▼
                      結合されたベクトル
                               │
                               ▼
                   sum() / mean() / etc.
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| across.R | `R/across.R` | ソース | c_across関数の定義（397-410行目） |
| across.R | `R/across.R` | ソース | c_across_setup関数（546-564行目） |
| rowwise.R | `R/rowwise.R` | ソース | rowwise()の実装 |
| data-mask.R | `R/data-mask.R` | ソース | データマスクの実装 |
