Stream: terminology
Topic: Nested codes for clinical status in AllergyIntolerance
Morten Ernebjerg (Mar 21 2022 at 06:47):
A colleague asked me why the code "resolved" from the AllergyIntolerance clinical status code is nested under "inactive". I was a little puzzled as I had implicitly assumed the standard code sets bound directly to a code
field would always be flat sets of mutually exclusive codes. If the nesting is intended, would it not mean that the meanings of the codes "inactive" and "resolved" overlap? Specifically (ignoring the principle of using the most specific code available), would it not mean that formally, it would not be incorrect to put "inactive" even if the actual state is "resolved"?
Robert McClure (Apr 01 2022 at 20:30):
@Jay Lyle @Russell Leftwich
Michael Lawley (Apr 01 2022 at 20:34):
That's hard to answer because the CodeSystem doesn't state a value for hierarchyMeaning!
Grahame Grieve (Apr 01 2022 at 21:23):
I had implicitly assumed the standard code sets bound directly to a code field would always be flat sets of mutually exclusive codes
no there are many examples where this is not the case
Grahame Grieve (Apr 01 2022 at 21:24):
If the nesting is intended, would it not mean that the meanings of the codes "inactive" and "resolved" overlap?
yes. Specifically, resolved means inactive. @Michael Lawley is correct that there's no explicit hierarchyMeaning but that should be taken to mean that it's subsumption based (btw, Michael, that's an error now, so won't be true in R5)
Jay Lyle (Apr 01 2022 at 21:33):
The intention is that "resolved" is a subclass of "inactive." I.e., all resolved instances are inactive; inactive instances may be resolved. Feedback is welcome on how useful (or problematic) this is.
"Inactive" is clearly valid, and applicable to cases of "resolved". Whether it would be permissible to use only the parent code is a question we haven't addressed, and may want to leave to the profile level.
@Michael Lawley That's an issue I had with the ConceptMap equivalence property, since I can imagine multiple axes for a map. But in the case of a value set, being a constraint on the range of an element, I would only expect a subclass relationship. Are there other use cases?
Michael Lawley (Apr 01 2022 at 21:50):
grouped-by
, is-a
, part-of
, classified-with
are the possible values for hierarchyMeaning.
grouped-by
's definition is particularly broad:
No particular relationship between the concepts can be assumed, except what can be determined by inspection of the definitions of the elements (possible reasons to use this: importing from a source where this is not defined, or where various parts of the hierarchy have different meanings).
But also part-of
would mean that the parent-concept is not a generalised substitutable concept for the child-concept.
Jay Lyle (Apr 02 2022 at 14:55):
I'm not suggesting there are not other kinds of relationships, just that when you create a value set for an element, you are specifying a concept domain. The members of that set may have refinement relationships (E coli O25:H4, refinement of E coli O25) but not syntactical navigation ("Infection caused by Escherichia coli (disorder)", caused by E coli O25).
Unless there is a use case for such a thing?
Morten Ernebjerg (Apr 04 2022 at 11:51):
Thanks for the input, clearly my assumptions were off! @Jay Lyle in terms of feedback on this: The use of overlapping codes on different hierarchy levels in standard places like AllergyIntolerance.clinicalStatus
seems to put an extra burden on implementers (and/or end users):
- It forces implementers to always keep the parent-child logic in mind when coding, e.g. every time I want to check if smt. is "inactive", I need to also check whether it is "resolved"
- It is hard to present overlapping codes clearly in a UI. If they are simply put as different options in a drop-down menu, users will most likely assume that they are non-overlapping. Hence, they will be confused about whether to use e.g.
inactive
orresolved
since both may indeed be correct in some cases. To guide users well, some sort of hierarchical (or otherwise fancy) visualization is needed - obviously fine for SNOMED & co, but seems a lot of effort for status codes.
I think this is compounded by the fact that the parent-child nature of the codes is easy to miss when perusing the ValueSet page & that the formal meaning of such a hierarchy might not even be entirely clear (cf. comment from @Michael Lawley). I could absolutely see myself getting tripped up by this, even though I am a relatively seasoned "FHIR user".
Note that the above argument do not apply to ValueSets that use codes from different levels, as long as codes never overlap semantically.
Grahame Grieve (Apr 04 2022 at 13:22):
every time I want to check if smt. is "inactive", I need to also check whether it is "resolved"
yes. Indeed. So you should check whether the code is subsumed by inactive as a matter of course.
Grahame Grieve (Apr 04 2022 at 13:23):
I think this is compounded by the fact that the parent-child nature of the codes is easy to miss when perusing the ValueSet page
oh? where? That shouldn't happen
Russell Leftwich (Apr 05 2022 at 03:13):
@Robert McClure Agree with @Jay Lyle resolved is a subclass of inactive. Allergy/intolerance is a risk of future reaction to a substance, is in most cases a clinical judgement that is testable only by direct challenge with the substance. There are many mechanisms of reaction that we group under this term (allergy/intolerance) for risk of future reaction. In recent years it has been demonstrated in hundreds of individuals with penicillin allergy that 90% have NO reaction when challenged with penicillin. They are certainly inactive. Whether they are "resolved" would depend on the certainty that they were ever allergic to penicillin. If there is strong documentation that they were, then the allergy/intolerance is both inactive and resolved.
Morten Ernebjerg (Apr 05 2022 at 06:52):
yes. Indeed. So you should check whether the code is subsumed by inactive as a matter of course.
Right, all of this can of course be correctly handled in code. Needless to say, developers have the responsibility to pay attention to the details & laziness is no excuse. I merely wanted to say that the increased medical precision & expressivity offered by the use of nested & overlapping codes in this context does come at the price of a somewhat higher implementer burden/risk of error (especially in contexts where no terminology server is available)
I think this is compounded by the fact that the parent-child nature of the codes is easy to miss when perusing the ValueSet page
oh? where? That shouldn't happen
I think it is indeed correctly documented on the allergyintolerance-clinical ValueSet Page. What I meant was merely that the signs that "resolved" is a child code that overlaps with "inactive" are very easy to overlook if you peruse the page without knowing about this in advance. The different code levels are given by the "Lvl" column entries, but as far as I can tell, the fact that "resolved" is a child of "inactive" is only indicated by the fact that "resolved" is slightly indented in the "Code" column. AFAIK, the levels alone don't give information about parent-child links as the VS could have included non-overlapping codes from different levels. As an implementer, I would personally have preferred a "louder" indication of the nesting and an in-place explanation of what the levels & parent-child link imply.
Grahame Grieve (Apr 05 2022 at 06:57):
well, there is some documentation in the page. Do you have wording suggestions?
Morten Ernebjerg (Apr 05 2022 at 07:38):
I suppose one could add a further column and explicitly indicate child-parent links. If multiple code level are included, one could also include minimal usage guidance directly below the table. So smt. like this (not sure if the guidance text is appropriate...)
Lvl | Code | Sub type of (is-a child) | Display | Definition | Canonical Status |
---|---|---|---|---|---|
0 | active | Active | The subject is currently experiencing, or is at risk of, a reaction to the identified substance. | ~active | |
0 | inactive | Inactive | The subject is no longer at risk of a reaction to the identified substance. | ~inactive | |
1 | resolved | inactive | Resolved | A reaction to the identified substance has been clinically reassessed by testing or re-exposure and is considered no longer to be present. Re-exposure could be accidental, unplanned, or outside of any clinical setting. | ~resolved |
Use of nested codes: Where available codes have parent-child relations and hence overlap in meaning, producing systems should attempt to provide the most specific code applicable. Receiving systems must correctly handle parent-child code relations.
Michael Lawley (Apr 05 2022 at 09:48):
Of course, Lvl only works as a unique value for trees, not DAGs (where each parent concept may have a different Lvl).
I would omit that column and label the Sub type column Parent (is-a)
instead -- "Parent" because that's the relevant property, and "(is-a)" from the value of .hierarchyMeaning
.
Grahame Grieve (Apr 05 2022 at 11:35):
that approach really really doesn't scale. It's fine when there's a few parent/child relationships, but when there's 100s....
Michael Lawley (Apr 05 2022 at 11:43):
I would only ever put in the list of parents -- I would be afraid if a concept had 100s of parents!
Grahame Grieve (Apr 05 2022 at 12:22):
I mean, 100s of parents across the entire code system, not for a single code (I've seen... 10... ?)
Michael Lawley (Apr 05 2022 at 21:18):
I was still imagining one row per code and the 'parent' column would have a comma-separated list of codes. Clearly not ideal for 10 parents, but still workable?
Grahame Grieve (Apr 05 2022 at 21:24):
I don't think it's workable for anything but small code systems. try this one:
Grahame Grieve (Apr 05 2022 at 21:26):
https://terminology.hl7.org/CodeSystem-v3-ActCode.html
Michael Lawley (Apr 05 2022 at 21:35):
oh - I see you're already doing what I was suggesting, only the parent column is "hidden" on the righthand side of the table.
Grahame Grieve (Apr 05 2022 at 22:01):
so I am. Well, that code system is a little special
Morten Ernebjerg (Apr 07 2022 at 07:05):
Right, that looks pretty good already - though, as mentioned, it's very easy to miss on the right edge (not visible even on my large monitor unless I explicitly pan right). Would it be possible to also render this column on corresponding ValuseSet pages?
Grahame Grieve (Apr 07 2022 at 07:19):
it's possible. I think it would be a negative value contribution to the page
Morten Ernebjerg (Apr 07 2022 at 07:39):
You mean it would just clutter the page? My own feeling is that it would be a net plus (certainly would be for me personally).
Grahame Grieve (Apr 07 2022 at 07:39):
well you can make a task and ask the vocab committee to vote on it
Morten Ernebjerg (Apr 07 2022 at 07:42):
Sounds sensible :+1: - will do.
Morten Ernebjerg (Apr 08 2022 at 08:38):
JIRA was effectively down yesterday but now managed to create a ticket: FHIR-36742.
Last updated: Apr 12 2022 at 19:14 UTC