OHDSI Home | Forums | Wiki | Github

834 Orphan Codes in Observation Table

We store medical history through reference to ICD codes . These icd codes would be our observation_source_value in the table. For the observation table, we have 843 orphan codes for medical history. What I mean by orphan codes is that these codes do not have a concept_code in the observation domain. 500 of them have a matching concept code in the condition domain. But again, this is medical history so they are observations. Where can I submit this list to add to future versions of the vocabulary? Thank you

There is a Condition Type of 43542353, which is “Observation recorded from EHR”. I wonder if these shouldn’t go in the Condition_occurrence table with that condition type instead of the Observation table. I see that the definition of Observation includes ‘medical history’, but these seem to be more like conditions, albeit self reported.

Just a thought.

Yeah but since observation records do not belong to any one domain could we include condition concepts? The effort to convert to the condition_occurrence table would be considerable since these data are at different levels and places in our source system.

@idontknow:

(Expressive login name. :))

Can you dump the extra codes right here? We are always collecting obsolete or otherwise not standard codes that are not included in the general distributions.

We will be cleaning those up, @roger.carlson. But thanks for point it out. It is confusing.

@Christian_Reich Yes it is :smile:

I tried uploading the list, but it says this feature is not allowed for new users. Is there another way to submit them through a link? I predict there will be more orphan codes too in the future the more our patient population and data range expands.

In the meantime, do you recommend we map these codes with a concept_id of 0 or map them to condition concepts when we submit the observation file?

Thank you!

@idontknow,
you can post the script that difines codes not having Observation domain:
for example
–look on the domain of concepts ICDs are mapped to
select a.concept_id, a.concept_name, a.vocabulary_id from concept a
join concept_relationship r on a.concept_id = r.concept_id_1
left join concept b on b.concept_id = r.concept_id_2 and b.domain_id =‘Observation’
where a.vocabulary_id like ‘ICD%’ and relationship_id =‘Maps to’ and r.invalid_reason is null
and lower (a.concept_name) like ‘%history%’
and b.concept_id is null
–count = 54
;
–look on the domain of ICD concepts itself
select a.concept_id, a.concept_name, a.vocabulary_id from concept a
where
a.domain_id !=‘Observation’
and a.vocabulary_id like ‘ICD%’
and lower (a.concept_name) like ‘%history%’
–count = 59

So I’m wondering how did you find 843 orphan codes.
You can try to send me this list as a private message (not sure if it will work, but can try)
or post a script generating the list

This code list was generated by left joining our institution’s history table so the comprehensive list cannot be generated just from the vocabularies. Since I am restricted from posting the list in the forums I will post in the All of Us email group. When it is decided when a new user gets to upload documents? Thanks.

You can create the google doc and post the link.

@idontknow You have access to upload docs now

I hope you won’t mind if I piggy-back off of this discussion to try to understand the problem conceptually. I don’t know if I’m not understanding the question, or if my understanding of OMOP is flawed.

As I understand it, the issue is that: @idontknow stores medical history by referencing ICD codes. And according to the definition of the Observation table, medical history should go into observation.

The OBSERVATION table captures clinical facts about a Person obtained in the context of examination, questioning or a procedure. Any data that cannot be represented by any other domains, such as social and lifestyle facts, medical history, family history, etc. are recorded here.

Since this history is recorded as ICD codes and these codes are not present in the Observation vocabulary as standard concepts, they don’t know what standard concepts to store.

However, these ICD codes are represented in the Condition_occurrence vocabulary. The definition of which is this:

Conditions are records of a Person suggesting the presence of a disease or medical condition stated as a diagnosis, a sign or a symptom, which is either observed by a Provider or reported by the patient. Conditions are recorded in different sources and levels of standardization, for example:

Medical claims data include diagnoses coded in ICD-9-CM that are submitted as part of a reimbursement claim for health services and EHRs may capture Person Conditions in the form of diagnosis codes or symptoms.

According to my current (and admittedly imperfect) understanding of OMOP, it seems to me that these records should be stored in the Conditions table and not the Observation table. Because they have a diagnosis code associated with them and it is reported by the patient, and are stored in the EHR, they seem to be conditions, not observations even though they represent history.

In addition, the definition of Observation says that it is for data that cannot be stored in other tables, and since this medical history can be stored in another table (Condition_occurrence) it should be stored there.

Am I misunderstanding something fundamental here?

@roger.carlson:

The issue is not that these medical history facts are Conditions or Observations. They are Conditions. The problem is the time stamp. Conditions have to be time stamped when they happened, not when the patient said “When I was a boy I broke my leg”. In the latter case it is an Observation, with the observation_concept_id “history of”, and the value_as_concept_id the Condition. However, if the patient knows the leg was broken 2-Feb-1975 you can store this as a condition with the condition_start_date=2-Feb-1975.

Makes sense?

There are ideas of how to allow for fuzzy dates, when the accurate date really doesn’t matter (like for these Conditions that happen before the Observation Period). Currently, no solution has been implemented.

Thanks, @Christian_Reich . That does make sense. I knew I was missing something.

In our source system, we consider these codes medical history and observations because they are hidden behind the medical history form that the doctor goes through with the patient and when yes or no is selected a diagnosis code record is selected. There is no record of ‘Yes’ or ‘No’. The codes are populated in a set of columns for positive medical history (includes the diag code) and a separate set of columns (includes the diag code) for negative medical history e.g. no personal history of. Now the list has jumped to 1309 codes. orphan_src_codes.xlsx (53.4 KB)

Question, I saw about 45 records for no personal history in the vocabularies. Should there be more or are we just mostly tracking when somebody has a positive medical history in observation table? Thanks.

select *
from CONCEPT
where (concept_name like ‘%No history%’ or concept_name like ‘No history%’ or concept_name like ‘%No personal%’ or concept_name like ‘No medical history%’)
and ((domain_id in (‘Observation’)))

@idontknow:

Thanks for the list, but remind me: What makes them orphan codes again? Looks like we have them nicely in the CONCEPT table for ICD9CM.

Well, they are not in the observation domain. Can I pull the condition concepts that these codes match into the observation table so they are not orphans?

Wait. The Concepts have the domain they have. Not the domain @idontknow wants them to have (since he doesn’t know anyway! :slight_smile: )

Look: The Concept that goes into OBSERVATION.observation_concept_id must be of the domain “Observation”. The Concept that goes into OBSERVATION.value_as_concept_id can be anything. So, plug these Condition concepts in there, and all is good.

The name I came up with because I could not think of a username at the time.
https://sites.google.com/view/ehrupload/omop-tables/observation

It says valid observation concepts are not to be enforced from any domain so they do not necessarily need to be observation domain. That is why I was asking if condition concept ids can be observation concept ids when the concept code matches and the vocabulary id is the same. See this query here. There are already 3092 concepts with icd9/10 codes just like how we code it in our source system so I am not sure what the issue is adding more.

select count(*)
from EDW_MARTS.OMOP_CONCEPT
where domain_id in (‘Observation’) and
vocabulary_id in (‘ICD9CM’,‘ICD10CM’,‘ICD9’)

Value_as_concept_id is for values eg ‘present’, ‘negative’, etc so it does not make sense for them to be condition concepts.

Thankfully most of the other questions I have had people have been helpful. This thread can be closed. We will just populate observation_concept_id with 0 since there does not seem to be a solution that makes sense here.

@idontknow:

Now I realize you are from the All-of-Us program, so understand where you are coming from. @cukarthik and @Robert_Carroll will tell you how they want to have your data collected, and they may have their own interim collection rules as you guys are building your resource. I am only talking about generic OMOP here.

You are right. The OBSERVATION table (sometime called “garbage can” by some folks) is the catch-all table for things that won’t fit anywhere else. That is why the domain is not enforced. So, nominally, you could put in there anything you want, including Condition Concepts combined with a “present” Concept as value_as_concept_id.

You could. But you don’t want to. It will break OMOP conventions and the ability to apply standardized research applications, such as ATLAS. If an ICD code maps to a Condition Concept you record that in the CONDITION_OCCURRENCE table. If there is a code in a medical or family history field, it goes as “History of” or “Family history of” into the OBSERVATION.observation_concept_id field, while the actual mapped Condition Concept goes into the value_as_concept_id field. That’s the rule. If the ICD is mapped to an Observation Domain Concept you put it into the observation_concept_id field as well.

Let me know.

t