Skip to content

Add join_smq() to expand SMQ lists into per-LLT dictionary rows#15

Open
billdenney wants to merge 1 commit into
mainfrom
claude/goofy-wu-a0bc15
Open

Add join_smq() to expand SMQ lists into per-LLT dictionary rows#15
billdenney wants to merge 1 commit into
mainfrom
claude/goofy-wu-a0bc15

Conversation

@billdenney

Copy link
Copy Markdown
Member

Fixes #14. Adds an exported join_smq() that turns the SMQ definitions parsed by read_meddra() into the flat per-LLT term list needed to merge against coded adverse events and to build SMQ*/CQ* variables.

Summary

Fixes #14. Adds an exported join_smq() that turns the SMQ definitions
parsed by read_meddra() (smq_list.asc + smq_content.asc) into the flat
per-LLT term list needed to merge against coded adverse events and to build
SMQ*/CQ* variables.

join_smq(data) returns one row per (SMQ × LLT × SOC path) with the full
SOC → HLGT → HLT → PT → LLT hierarchy plus SMQ identity and member
attributes (term_scope, term_category, term_weight, term_status).

How it works

  • Sub-SMQ recursionterm_level == 0 rows reference a child SMQ and are
    flattened recursively via a cycle-safe worklist.
  • PT → LLT expansionterm_level == 4 PT members expand to all LLTs of
    the PT, with scope/category inherited.
  • Direct LLT membersterm_level == 5 attach to the single LLT.

It reuses join_meddra() for the hierarchy and uses inner_join, so orphan
terms with no hierarchy match are dropped rather than emitting all-NA rows
(the one intentional departure from join_meddra()'s tolerant left_joins).

Output columns use the same snake_case names as join_meddra(). Per the
agreed design, the vignette documents a recipe to rename to the SAS/ADaM short
names from the issue (soccd, lltcd, ptcd, …).

Changes

  • New: R/join_smq.R (join_smq() + internal flatten_smq_content() /
    flatten_smq_one()), tests/testthat/test-join_smq.R, man/join_smq.Rd.
  • Updated: NAMESPACE (export), NEWS.md, vignettes/meddra-read.Rmd
    (new "Expanding an SMQ into dictionary terms" section + rename table),
    inst/WORDLIST, CLAUDE.md.

Testing

  • devtools::test() — all pass (7 new tests: PT, LLT, sub-SMQ, cycle-safety,
    missing-file, empty-content, empty-list paths).
  • Coverage — 100% of R/join_smq.R (covr).
  • devtools::check() — 0 errors, 0 warnings; only environmental NOTEs
    (.git present; clock check).
    join_smq() returns one row per (SMQ x LLT x SOC path) with the full SOC -> HLGT -> HLT -> PT -> LLT hierarchy plus SMQ identity and member attributes (term_scope, term_category, term_weight, term_status). It:
  • recursively resolves sub-SMQ references (term_level 0, cycle-safe);
  • expands PT members (term_level 4) down to all of the PT's LLTs, with scope inherited; and
  • attaches LLT members (term_level 5) directly.

It reuses join_meddra() for the hierarchy and uses inner_join so orphan terms with no hierarchy match are dropped rather than emitting all-NA rows. Column names match join_meddra() (snake_case); the vignette adds a recipe for renaming to the SAS/ADaM short names.

Also: regenerated NAMESPACE + man/join_smq.Rd, extended the vignette SMQ section, updated NEWS.md, CLAUDE.md, and inst/WORDLIST. Tests cover PT, LLT, sub-SMQ, cycle-safety, missing-file, and empty-input paths (100% coverage of R/join_smq.R); R CMD check passes with no new NOTEs.

Fixes #14. Adds an exported join_smq() that turns the SMQ definitions
parsed by read_meddra() into the flat per-LLT term list needed to merge
against coded adverse events and to build SMQ*/CQ* variables.

join_smq() returns one row per (SMQ x LLT x SOC path) with the full
SOC -> HLGT -> HLT -> PT -> LLT hierarchy plus SMQ identity and member
attributes (term_scope, term_category, term_weight, term_status). It:

* recursively resolves sub-SMQ references (term_level 0, cycle-safe);
* expands PT members (term_level 4) down to all of the PT's LLTs, with
  scope inherited; and
* attaches LLT members (term_level 5) directly.

It reuses join_meddra() for the hierarchy and uses inner_join so orphan
terms with no hierarchy match are dropped rather than emitting all-NA
rows. Column names match join_meddra() (snake_case); the vignette adds a
recipe for renaming to the SAS/ADaM short names.

Also: regenerated NAMESPACE + man/join_smq.Rd, extended the vignette SMQ
section, updated NEWS.md, CLAUDE.md, and inst/WORDLIST. Tests cover PT,
LLT, sub-SMQ, cycle-safety, missing-file, and empty-input paths (100%
coverage of R/join_smq.R); R CMD check passes with no new NOTEs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
R/join_smq.R 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Function request - SMQ expansion

1 participant