# 機能設計書 57-cume_dist

## 概要

本ドキュメントは、dplyrパッケージにおける`cume_dist()`関数の機能設計を定義する。`cume_dist()`は累積分布を計算する比例ランキング関数である。

### 本機能の処理概要

**業務上の目的・背景**：データ分析において、各値がデータ全体の中でどの位置にあるかを累積分布の観点から評価したい場合がある。例えば、「この値以下のデータは全体の何%を占めるか」を知りたい場合である。`cume_dist()`は、このような累積分布関数（CDF）の値を計算するために設計された。

**機能の利用シーン**：累積分布の計算、パーセンタイルの算出、データの分布分析、相対的な位置の評価などに利用される。

**主要な処理内容**：
1. 入力ベクトルの各値について、それ以下の値の数をカウントする
2. カウントを観測数で除算して比率を計算する
3. 結果は0より大きく1以下の範囲となる
4. 欠損値（NA）は計算から除外され、結果もNAとなる

**関連システム・外部連携**：vctrsパッケージの`vec_rank()`関数を`ties = "max"`オプションで使用する。`vec_detect_complete()`を使用してNA以外の要素数を計算する。

**権限による制御**：本関数に権限による実行制御は存在しない。

## 関連画面

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

## 機能種別

計算処理 / 比例ランキング関数

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | vector / data.frame | Yes | 累積分布を計算する対象ベクトル | 順序付け可能な型であること |

### 入力データソース

Rのベクトルまたはデータフレーム。`mutate()`や`filter()`内で使用される場合は、現在処理中のグループのデータが対象となる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | numeric | 0より大きく1以下の範囲の数値ベクトル。各要素の累積分布値 |

### 出力先

関数の戻り値として返却される。通常は`mutate()`の結果としてデータフレームの列に格納される。

## 処理フロー

### 処理シーケンス

```
1. 入力ベクトル x を受け取る
2. vec_rank(x, ties = "max", incomplete = "na") でランクを計算
3. 非NA要素数で除算
4. 数値ベクトルとして結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: cume_dist] --> B[vec_rank を呼び出し]
    B --> C["ties='max', incomplete='na'"]
    C --> D[非NA要素数を計算]
    D --> E[ランク / 非NA要素数]
    E --> F["0 < 結果 <= 1 の数値ベクトルを返却"]
    F --> G[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | 範囲 | 結果は0より大きく1以下の範囲 | 常に適用 |
| BR-57-02 | 最大値 | 最大値の累積分布は常に1 | 常に適用 |
| BR-57-03 | NA処理 | 欠損値は計算から除外され、結果もNA | NA存在時 |
| BR-57-04 | タイ処理 | 同じ値には同じ累積分布値（最大ランク使用） | タイ存在時 |
| BR-57-05 | 以下カウント | 「以下」の値の数をカウント（等号含む） | 常に適用 |

### 計算ロジック

- 計算式: `vec_rank(x, ties = "max", incomplete = "na") / sum(vec_detect_complete(x))`
- 手動計算と等価: `sapply(x, function(xi) sum(x <= xi) / length(x))`
- 例: `c(5, 1, 3, 2, 2)` → `c(1.00, 0.20, 0.80, 0.60, 0.60)`
  - 1: 1/5 = 0.20（1以下は1つ）
  - 2: 3/5 = 0.60（2以下は3つ）
  - 3: 4/5 = 0.80（3以下は4つ）
  - 5: 5/5 = 1.00（5以下は5つ）

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

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

本関数はインメモリのベクトル操作のみを行い、データベース操作は行わない。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | 順序付けできない型の入力 | 順序付け可能な型を使用する |

### リトライ仕様

リトライは不要（同期的なインメモリ処理）。

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

トランザクション管理は不要（ステートレスな関数型処理）。

## パフォーマンス要件

- 計算量: O(n log n)（vec_rankによるソートが支配的）
- メモリ使用量: O(n)（出力ベクトル用）

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

特別なセキュリティ考慮事項はない。

## 備考

- SQLの`CUME_DIST()`ウィンドウ関数に相当
- `percent_rank()`と似ているが、計算方法が異なる
  - `percent_rank`: `(rank - 1) / (n - 1)`（0から1）
  - `cume_dist`: `rank / n`（0より大きく1以下）
- 統計学の累積分布関数（CDF）に対応

---

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

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

### 推奨読解順序

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

cume_dist関数は、vctrsパッケージのvec_rank関数を使用して実装されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | rank.R | `R/rank.R` | 比例ランキング関数のドキュメント（140-179行目） |

**読解のコツ**: ドキュメント内の手動計算例（166行目）で計算ロジックを理解できる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rank.R | `R/rank.R` | `cume_dist()`関数の定義（176-178行目） |

**主要処理フロー**:
1. **176行目**: `cume_dist(x)`関数のシグネチャ
2. **177行目**: `vec_rank(x, ties = "max", incomplete = "na") / sum(vec_detect_complete(x))`
   - `vec_rank(..., ties = "max")`: タイには最大ランクを使用
   - `sum(vec_detect_complete(x))`: 非NA要素数

#### Step 3: percent_rankとの比較

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rank.R | `R/rank.R` | 146-150行目でcume_distとpercent_rankの違いを理解 |

**主要処理フロー**:
- **146-147行目**: cume_distは「以下」の値の数を計算
- **148-150行目**: percent_rankは「より小さい」値の数を計算
- 分母も異なる: cume_distは`n`、percent_rankは`n-1`

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

```
cume_dist(x)
    │
    ├─ vec_rank(x, ties = "max", incomplete = "na") [ランク計算]
    │
    └─ vec_detect_complete(x) [非NA要素検出]
           └─ sum() [非NA要素数カウント]
```

### データフロー図

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

x = [5,1,3,2,2]   ───▶  cume_dist(x)               ───▶  [1.00, 0.20, 0.80, 0.60, 0.60]
                         │
                         ├─▶ vec_rank(ties="max") → [5,1,4,3,3]
                         │   (タイには最大ランク: 2が2つなので両方3)
                         │
                         └─▶ / 5 → [1.00, 0.20, 0.80, 0.60, 0.60]

比較: percent_rank(x)の場合                          [1.00, 0.00, 0.75, 0.25, 0.25]
                                                      (計算方法が異なる)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| rank.R | `R/rank.R` | ソース | cume_dist関数の実装 |
| test-rank.R | `tests/testthat/test-rank.R` | テスト | 比例ランキング関数のテスト（3-22行目） |
