# Trial phase and sponsor mix across sixteen conditions

## Question

How many interventional studies does ClinicalTrials.gov hold for sixteen conditions, how many are tagged Phase 3, and what share carry an industry lead sponsor?

## Method

Endpoint: `https://clinicaltrials.gov/api/v2/studies`, called with python3 `urllib` and the User-Agent `pgx-gap-map-research/1.0 (public data note; python-urllib)`. Retrieval date 2026-10-30, 14:36 UTC. Cap 40 requests, 0.4 s sleep; forty were used, two failed.

Count-only queries sent `pageSize=1&countTotal=true` and read `totalCount`:

- `query.cond=<condition>&pageSize=1&countTotal=true&filter.advanced=AREA[StudyType]INTERVENTIONAL`
- `...&filter.advanced=AREA[StudyType]INTERVENTIONAL AND AREA[Phase]PHASE3` (and `...AREA[LeadSponsorClass]INDUSTRY`)

Conditions (`query.cond` literals): type 2 diabetes; hypertension; Alzheimer disease; Parkinson disease; schizophrenia; major depressive disorder; tuberculosis; malaria; HIV infections; hepatitis C; breast cancer; lung cancer; pancreatic cancer; sickle cell disease; cystic fibrosis; chronic kidney disease.

A single `filter.advanced` accepts a boolean expression (type 2 diabetes: 9,910 interventional; 1,647 Phase 3), so the interventional restriction sits inside every query, not only the denominator.

The full matrix did not fit the cap (16 × 6 phases + 8 sponsor classes = 224 queries): Phase 3 was kept for all sixteen and industry for two; other cells are absent, not zero.

Both failures came from `/api/v2/stats/field/values`, which answers HTTP 400 `Invalid prefix in parameter name: query.cond`; logged in `raw.json` under `failures`.

A 1,000-record page per condition (`pageSize=1000&sort=StudyFirstPostDate:asc`) was also fetched as a shortcut; those counts sit in `data.csv` with a `_sampled` suffix and are not results.

## Results

| Condition | Interventional | Phase 3 | Phase 3 share |
|---|---:|---:|---:|
| type 2 diabetes | 9,910 | 1,647 | 16.6% |
| hypertension | 9,137 | 1,376 | 15.1% |
| Alzheimer disease | 3,415 | 387 | 11.3% |
| Parkinson disease | 3,873 | 418 | 10.8% |
| schizophrenia | 3,606 | 532 | 14.8% |
| major depressive disorder | 3,294 | 524 | 15.9% |
| tuberculosis | 1,158 | 181 | 15.6% |
| malaria | 1,241 | 218 | 17.6% |
| HIV infections | 8,225 | 988 | 12.0% |
| hepatitis C | 1,895 | 443 | 23.4% |
| breast cancer | 13,233 | 1,564 | 11.8% |
| lung cancer | 11,458 | 1,410 | 12.3% |
| pancreatic cancer | 4,035 | 297 | 7.4% |
| sickle cell disease | 867 | 119 | 13.7% |
| cystic fibrosis | 1,215 | 196 | 16.1% |
| chronic kidney disease | 4,318 | 684 | 15.8% |

- The sixteen hold 80,880 interventional registrations, 10,984 tagged Phase 3 (13.6% pooled). Totals run from 867 (sickle cell disease) to 13,233 (breast cancer). Sickle cell disease is the only complete census (867 of 867); its counted Phase 3 records, 119, match the API total.
- Phase 3 share runs from 7.4% (pancreatic cancer) to 23.4% (hepatitis C), median 14.9%; ten of the sixteen sit between 11% and 16%.
- Phase tags overlap, so buckets cannot be summed. For chronic kidney disease, Phase 2 returns 754 and Phase 3 returns 684, while the OR query returns 1,363: 75 studies carry both tags and appear in each single-phase count.
- Industry counts exist for two conditions: breast cancer 2,863 of 13,233 (21.6%) and lung cancer 3,962 of 11,458 (34.6%). The archived page put lung cancer at 28.4%, 6.2 points lower, and its Phase 3 shares ran a median 7.9 points high.

## What this does and does not show

1. Coverage is partial: five phase values (Early Phase 1, Phase 1, Phase 2, Phase 4, NA) have no condition-level count, and no sponsor class was counted except industry, for two conditions; nothing here speaks to NIH, OTHER, NETWORK, FED, AMBIG, INDIV or UNKNOWN lead sponsors.
2. Phase counts are not mutually exclusive: 75 chronic kidney disease studies carry both Phase 2 and Phase 3. A Phase 3 share is the fraction of a condition's interventional registrations whose Phase field includes PHASE3, not the fraction that are Phase 3 alone.
3. The 1,000-record pages are not a random sample. Sorted by first-post date they take the oldest registrations, overstating Phase 3 share by a median 7.9 points (range −0.5 to +22.3) and miss the lung cancer industry share. They are kept for audit, not used as estimates.
4. `query.cond` is the registry's match for a literal phrase; synonym or hierarchical expansion was not tested, so a count means "what ClinicalTrials.gov returns for that string", not a case definition.
5. Registrations, not trials conducted: all statuses are included, records are self-reported, and a study appears once however many countries it runs in.
6. Sponsor class is the lead sponsor, not the funder; the API also returns `OTHER_GOV`, absent from the requested eight-class list.

## Reproduce

```bash
curl -sG "https://clinicaltrials.gov/api/v2/studies" --data-urlencode "query.cond=type 2 diabetes" \
  --data-urlencode "pageSize=1" --data-urlencode "countTotal=true" \
  --data-urlencode "filter.advanced=AREA[StudyType]INTERVENTIONAL AND AREA[Phase]PHASE3" \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['totalCount'])"
```

The sweep, 0.4 s apart:

```python
import csv, json, time, urllib.parse, urllib.request
UA = "pgx-gap-map-research/1.0 (public data note; python-urllib)"
CONDS = [r["condition"] for r in csv.DictReader(open("data.csv"))]
for c in CONDS:
    for adv in ("AREA[StudyType]INTERVENTIONAL",
                "AREA[StudyType]INTERVENTIONAL AND AREA[Phase]PHASE3"):
        q = urllib.parse.urlencode({"query.cond": c, "pageSize": 1, "countTotal": "true",
                                    "filter.advanced": adv}, safe="[]():,")
        req = urllib.request.Request("https://clinicaltrials.gov/api/v2/studies?" + q,
                                     headers={"User-Agent": UA})
        print(c, json.load(urllib.request.urlopen(req))["totalCount"])
        time.sleep(0.4)
```

`raw.json` stores every response verbatim, keyed by query string, plus the request log; `data.csv` is rebuilt from those bodies; medians and pooled shares come from its rows.

## Publication status

**Draft.** Auto-generated from public API responses; requires editorial review before publication.
