# 機能設計書 56-percent_rank

## 概要

本ドキュメントは、dplyrパッケージにおける`percent_rank()`関数の機能設計を定義する。`percent_rank()`はパーセンタイルランクを計算する比例ランキング関数である。

### 本機能の処理概要

**業務上の目的・背景**：データ分析において、各値がデータ全体の中でどの位置にあるかを0から1の範囲の比率で表現したい場合がある。例えば、試験の成績がクラス全体の上位何%に位置するか、売上高が市場全体のどの位置にあるかを計算する場合である。`percent_rank()`は、このような「相対的な位置」を比率で表現するために設計された。

**機能の利用シーン**：パーセンタイル順位の計算、データの正規化（0-1範囲へのスケーリング）、相対的な順位の比較、分布における位置の特定などに利用される。

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

**関連システム・外部連携**：内部で`min_rank()`関数を使用してランキングを計算する。vctrsパッケージの`vec_detect_complete()`を使用してNA以外の要素数を計算する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | numeric | 0から1の範囲の数値ベクトル。各要素のパーセンタイルランク |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 入力ベクトル x を受け取る
2. min_rank(x) でランクを計算
3. 各ランクから1を引く（0始まりに調整）
4. 非NA要素数から1を引いた値で除算
5. 数値ベクトルとして結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: percent_rank] --> B[min_rank でランク計算]
    B --> C[ランク - 1]
    C --> D[非NA要素数を計算]
    D --> E["(ランク - 1) / (非NA要素数 - 1)"]
    E --> F[0-1の数値ベクトルを返却]
    F --> G[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | 範囲 | 結果は0から1の範囲 | 常に適用 |
| BR-56-02 | 最小値 | 最小値のパーセンタイルランクは0 | 常に適用 |
| BR-56-03 | 最大値 | 最大値のパーセンタイルランクは1 | 常に適用 |
| BR-56-04 | NA処理 | 欠損値は計算から除外され、結果もNA | NA存在時 |
| BR-56-05 | タイ処理 | 同じ値には同じパーセンタイルランク | タイ存在時 |

### 計算ロジック

- 計算式: `(min_rank(x) - 1) / (sum(vec_detect_complete(x)) - 1)`
- 手動計算と等価: `sapply(x, function(xi) sum(x < xi) / (length(x) - 1))`
- 例: `c(5, 1, 3, 2, 2)` → `c(1.00, 0.00, 0.75, 0.25, 0.25)`
  - 1は最小値なので0
  - 5は最大値なので1
  - 2は下から2番目の値（2つあるが両方0.25）

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | 順序付けできない型の入力 | 順序付け可能な型を使用する |
| - | 計算エラー | 要素数1の場合（0/0） | NaNが返される（仕様） |

### リトライ仕様

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

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

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

## パフォーマンス要件

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

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

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

## 備考

- SQLの`PERCENT_RANK()`ウィンドウ関数に相当
- `cume_dist()`と似ているが、計算方法が異なる
- 要素数1の場合はNaN（0/0）となる点に注意

---

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

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

### 推奨読解順序

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

percent_rank関数は、min_rank関数とvctrsの完全性チェック関数を組み合わせて実装されている。

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

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

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

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

**主要処理フロー**:
1. **170行目**: `percent_rank(x)`関数のシグネチャ
2. **171行目**: `(min_rank(x) - 1) / (sum(vec_detect_complete(x)) - 1)`
   - `min_rank(x)`: 各値のランク（1始まり）
   - `- 1`: 0始まりに調整
   - `sum(vec_detect_complete(x))`: 非NA要素数
   - `- 1`: 範囲を0-1にするための調整

#### Step 3: 関連関数との比較

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

**主要処理フロー**:
- **148-150行目**: percent_rankは「より小さい値の数」を計算
- **146-147行目**: cume_distは「以下の値の数」を計算
- 両者の違いは「以下」vs「より小さい」

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

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

### データフロー図

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

x = [5,1,3,2,2]   ───▶  percent_rank(x)            ───▶  [1.00, 0.00, 0.75, 0.25, 0.25]
                         │
                         ├─▶ min_rank(x) → [5,1,4,2,2]
                         │
                         ├─▶ min_rank(x) - 1 → [4,0,3,1,1]
                         │
                         └─▶ / (5 - 1) → [1.00, 0.00, 0.75, 0.25, 0.25]
```

### 関連ファイル一覧

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