Risk Score Calculater, how to make?

I am an internist in Japan and I use Text Blaze to fill out electronic medical records.

I would like to use Text Blaze to calculate a patient's risk score. For example, for a CHADS2 score, the score is determined by 5 questions and the indication for oral medication is determined.

With Text Blaze, I would like to set up a function and use an if statement to get +1 or +2 points when a question is answered.

I would like to create something like the following

Translated with DeepL Translate: The world's most accurate translator (free version)

Hey @Naritatsu_Saito, glad to see you coming up with some many cool ideas for Text Blaze. This is definitely possible. I've created the CHADS2 score calculator that you linked as a snippet:

{note: trim=yes}
CHF history? {formmenu: Yes; default=No; name=CHF; cols=6}
Hypertension history? {formmenu: Yes; default=No; name=hypertension; cols=6}
Age >= 75? {formmenu: Yes; default=No; name=age; cols=6}
Diabetes mellitus history? {formmenu: Yes; default=No; name=diabetes; cols=6}
Stroke or TIA symptoms previously? {formmenu: Yes; default=No; name=stroketia; trim=right; cols=6}
{if: CHF=="Yes"; trim=yes}{chfscore=1}{else}{chfscore=0}{endif}{if: hypertension=="Yes"}{hypertensionscore=1}{else}{hypertensionscore=0}{endif}{if: age=="Yes"}{agescore=1}{else}{agescore=0}{endif}{if: diabetes=="Yes"}{diabetesscore=1}{else}{diabetesscore=0}{endif}{if: stroketia=="Yes"}{stroketiascore=2}{else}{stroketiascore=0}{endif}
{chads2=chfscore+hypertensionscore+agescore+diabetesscore+stroketiascore}
{endnote: trim=yes}
CHADS₂ Score: {=chads2}

{if: chads2==0}Low risk of thromboembolic event. 1.9% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==1}Intermediate risk of thromboembolic event. 2.8% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==2}Intermediate risk of thromboembolic event. 4.0% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==3}High risk of thromboembolic event. 5.9% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==4}High risk of thromboembolic event. 8.5% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==5}Note: While history of stroke provides 2 points, most physicians would move these patients directly to the high risk group (>8.5% risk of event per year if no coumadin.)

By points directly:
High risk of thromboembolic event. 12.5% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.
{elseif: chads2==6}Note: While history of stroke provides 2 points, most physicians would move these patients directly to the high risk group (>8.5% risk of event per year if no coumadin.)

By points directly:
High risk of thromboembolic event. 18.2% risk of event per year if no coumadin.

The adjusted stroke rate was the expected stroke rate per 100 person-years derived from the multivariable model assuming that aspirin was not taken.{endif}

I wasn't sure if you wanted each contributing factor to be included in what's inserted when you use the snippet, but if you do you can just remove the {note} and {endnote} commands around them.

To give you a breakdown of what is happening in this snippet:

  • Each factor has a yes/no selector
  • Using the if/else command, each factor is given a score (0, 1 or 2)
  • The CHADS2 score is the total of each one of those factor's scores
  • Using an if and elseif command looking at the CHADS2 score, advice is placed at the bottom appropriate to the score
4 Likes

Thanks, that's what I want!!!

If anyone has other calculators they wanted, please post. Some of us can help make them and it helps multiple people.

1 Like

It would be great if you could recreate the PECARN score for me in Peds.

Thanks

1 Like

@Andre_Persaud welcome to the community! ask and ye shall receive :slight_smile:

Age: {formmenu: \<2 years; \>\=2 years; name=age}
{if: age="<2 years"}
GCS ≤14, palpable skull fracture or signs of AMS? {formmenu: default=; no; yes; name=q1}
AMS: Agitation, somnolence, repetitive questioning, or slow response to verbal communication
{elseif: age=">=2 years"; trim=left}
GCS ≤14 or signs of basilar skull fracture or signs of AMS? {formmenu: default=; no; yes; name=q3}
AMS: Agitation, somnolence, repetitive questioning, or slow response to verbal communication{endif}
{if: age="<2 years" AND q1="no"}
Occipital, parietal or temporal scalp hematoma; history of LOC ≥5 sec; not acting normally per parent or severe mechanism of injury? {formmenu: default=; no; yes; name=q2}
Severe mechanism: MVC with patient ejection, death of another passenger, rollover; pedestrian or bicyclist w/o helmet struck by motorized vehicle; fall from >0.9m or 3ft; head struck by high-impact object{endif: trim=yes}
{if: age=">=2 years" AND q3="no"}
History of LOC or history of vomiting or severe headache or severe mechanism of injury {formmenu: default=; no; yes; name=q4}
Motor vehicle crash with patient ejection, death of another passenger, or rollover; pedestrian or bicyclist without helmet struck by a motorized vehicle; falls of more than 1.5m/5ft; head struck by a high-impact object{endif}

RESULTS
{if: age="<2 years" AND q1="no" AND q2="no"}PECARN recommends No CT; Risk of ciTBI <0.02%, “Exceedingly Low, generally lower than risk of CT-induced malignancies.”

{elseif: age="<2 years" AND q1="no" AND q2="yes"}PECARN recommends observation over imaging, depending on provider comfort; 0.9% risk of clinically important Traumatic Brain Injury.

Consider the following when making imaging decisions: Physician experience, worsening signs/symptoms during observation period, age <3 months, parent preference, multiple vs. isolated findings: patients with certain isolated findings (i.e., no other findings suggestive of TBI), such as isolated LOC, isolated headache, isolated vomiting, and certain types of isolated scalp hematomas in infants >3 months have ciTBI risk substantially <1%.

{elseif: age="<2 years" AND q1="yes"}PECARN recommends CT; 4.4% risk of clinically important Traumatic Brain Injury.

{elseif: age=">=2 years" AND q3="yes"}PECARN recommends CT; 4.3% risk of clinically important Traumatic Brain Injury.

{elseif: age=">=2 years" AND q3="no" AND q4="no"}PECARN recommends No CT; Risk <0.05%, “Exceedingly Low, generally lower than risk of CT-induced malignancies.”

{elseif: age=">=2 years" AND q3="no" AND q4="yes"}PECARN recommends observation over imaging, depending on provider comfort; 0.9% risk of clinically important Traumatic Brain Injury.

Consider the following when making imaging decisions: Physician experience, worsening signs/symptoms during observation period, age <3 months, parent preference, multiple vs. isolated findings: patients with certain isolated findings (i.e., no other findings suggestive of TBI), such as isolated LOC, isolated headache, isolated vomiting, and certain types of isolated scalp hematomas in infants >3 months have ciTBI risk substantially <1%.{endif}

important note: I am not a medical professional and the accuracy of this snippet should be independently reviewed. I recreated it exactly as it was in MDcalc and verified my results against theirs, but I do not have the expertise to say that the results and advice are accurate.

3 Likes

I was going to try working on this but @Andrew_Hall beat me. :laughing:

There is a design question though. If you want to minimize user input, you can have questions for the user that are dependent on the answer (as shown in Andrew's example). Or you can make all questions available for the user (age, GSC, other signs of AMS, skull fracture, severe injury, etc.). This way is more time-consuming but more thorough as it may make the user double-check a symptom was not missed.

So, there's a bit of a design question depending on what you want. One philosophy in medicine when designing things is that you don't want to make things too fast (which turns off critical thinking) and you don't want to make too slow (which is too resource-intensive).

1 Like

Thanks!

I think @Andrew_Hall stays true to the PECARN model. PECARN workflow is linear with Yes/No questions until/if you get a YES.

About Framingham. I asked chat GPT but it's not 100%

@Pharmacie_Marziali This looked like a great use-case so I went ahead and built it following the PDF that you provided.

Please note that I am not a medical professional and the output of this snippet should be verified for accuracy.

Gender: {formmenu: male; female; name=gender}

Age: {formmenu: 30-34; 35-39; 40-44; 45-49; 50-54; 55-59; 60-64; 65-69; 70-74; 75+; name=age} -- Risk Points: {if: gender="male"}{agerisk=0 if age="30-34" else 2 if age="35-39" else 5 if age="40-44" else 7 if age="45-49" else 8 if age="50-54" else 10 if age="55-59" else 11 if age="60-64" else 12 if age="65-69" else 14 if age="70-74" else 15}{elseif: gender="female"}{agerisk=0 if age="30-34" else 2 if age="35-39" else 4 if age="40-44" else 5 if age="45-49" else 7 if age="50-54" else 8 if age="55-59" else 9 if age="60-64" else 10 if age="65-69" else 11 if age="70-74" else 12}{endif}{=agerisk}

HDL-C (mmol/L): {formmenu: >1.6; 1.3-1.6; 1.2-1.29; 0.9-1.19; <0.9; name=hdlc} -- Risk Points: {hdlcrisk=-2 if hdlc=">1.6" else -1 if hdlc="1.3-1.6" else 0 if hdlc="1.2-1.29" else 1 if hdlc="0.9-1.19" else 2}{=hdlcrisk}

Total Cholesterol: {formmenu: <4.1; 4.1-5.19; 5.2-6.19; 6.2-7.2; >7.2; name=cholesterol} -- Risk Points: {if: gender="male"}{cholesterolrisk=0 if cholesterol="<4.1" else 1 if cholesterol="4.1-5.19" else 2 if cholesterol="5.2-6.19" else 3 if cholesterol="6.2-7.2" else 4}{elseif: gender="female"}{cholesterolrisk=0 if cholesterol="<4.1" else 1 if cholesterol="4.1-5.19" else 3 if cholesterol="5.2-6.19" else 4 if cholesterol="6.2-7.2" else 5}{endif}{=cholesterolrisk}

Systolic Blood Pressure (mmHg): {formmenu: <120; 120-129; 130-139; 140-149; 150-159; 160+; name=systolicbp} {formmenu: Not Treated; Treated; name=bptreated} -- Risk Points: {if: gender="male"}{if: bptreated="Not Treated"}{systolicbprisk=-2 if systolicbp="<120" else 0 if systolicbp="120-129" else 1 if systolicbp="130-139" else 2 if systolicbp="140-149" else 2 if systolicbp="150-159" else 3}{elseif: bptreated="Treated"}{systolicbprisk=0 if systolicbp="<120" else 2 if systolicbp="120-129" else 3 if systolicbp="130-139" else 4 if systolicbp="140-149" else 4 if systolicbp="150-159" else 5}{endif}{elseif: gender="female"}{if: bptreated="Not Treated"}{systolicbprisk=-3 if systolicbp="<120" else 0 if systolicbp="120-129" else 1 if systolicbp="130-139" else 2 if systolicbp="140-149" else 4 if systolicbp="150-159" else 5}{elseif: bptreated="Treated"}{systolicbprisk=-1 if systolicbp="<120" else 2 if systolicbp="120-129" else 3 if systolicbp="130-139" else 5 if systolicbp="140-149" else 6 if systolicbp="150-159" else 7}{endif}{endif}{=systolicbprisk}

Smoker? {formmenu: no; yes; name=smoker} -- Risk Points: {smokerrisk=4 if (gender="male" and smoker="yes") else 0 if (gender="male" and smoker="no") else 3 if (gender="female" and smoker="yes") else 0}{=smokerrisk}

Diabetes? {formmenu: no; yes; name=diabetes} -- Risk Points: {diabetesrisk="statin-indicated condition" if diabetes="yes" else 0}{=diabetesrisk}

Total Points: {totalpoints=agerisk+hdlcrisk+cholesterolrisk+systolicbprisk+smokerrisk}{=totalpoints}

10-Year CVD Risk %: {if: gender="male"}{tenyearcvdrisk="<1" if totalpoints<-2 else 1.1 if totalpoints=-2 else 1.4 if totalpoints=-1 else 1.6 if totalpoints=0 else 1.9 if totalpoints=1 else 2.3 if totalpoints=2 else 2.8 if totalpoints=3 else 3.3 if totalpoints=4 else 3.9 if totalpoints=5 else 4.7 if totalpoints=6 else 5.6 if totalpoints=7 else 6.7 if totalpoints=8 else 7.9 if totalpoints=9 else 9.4 if totalpoints=10 else 11.2 if totalpoints=11 else 13.3 if totalpoints=12 else 15.6 if totalpoints=13 else 18.4 if totalpoints=14 else 21.6 if totalpoints=15 else 25.3 if totalpoints=16 else 29.4 if totalpoints=17 else ">30" if totalpoints>17 else ""}{elseif: gender="female"}{tenyearcvdrisk="<1" if totalpoints<-2 else "<1" if totalpoints=-2 else 1 if totalpoints=-1 else 1.2 if totalpoints=0 else 1.5 if totalpoints=1 else 1.7 if totalpoints=2 else 2 if totalpoints=3 else 2.4 if totalpoints=4 else 2.8 if totalpoints=5 else 3.3 if totalpoints=6 else 3.9 if totalpoints=7 else 4.5 if totalpoints=8 else 5.3 if totalpoints=9 else 6.3 if totalpoints=10 else 7.3 if totalpoints=11 else 8.6 if totalpoints=12 else 10 if totalpoints=13 else 11.7 if totalpoints=14 else 13.7 if totalpoints=15 else 15.9 if totalpoints=16 else 18.51 if totalpoints=17 else 21.5 if totalpoints=18 else 24.8 if totalpoints=19 else 27.5 if totalpoints=20 else ">30" if totalpoints>20 else ""}{endif}{=tenyearcvdrisk}

Heart Age (in years): {if: gender="male"}{heartage="<30" if totalpoints<0 else 30 if totalpoints=0 else 32 if totalpoints=1 else 34 if totalpoints=2 else 36 if totalpoints=3 else 38 if totalpoints=4 else 40 if totalpoints=5 else 42 if totalpoints=6 else 45 if totalpoints=7 else 48 if totalpoints=8 else 51 if totalpoints=9 else 54 if totalpoints=10 else 57 if totalpoints=11 else 60 if totalpoints=12 else 64 if totalpoints=13 else 68 if totalpoints=14 else 72 if totalpoints=15 else 76 if totalpoints=16 else ">80" if totalpoints>16 else ""}{elseif: gender="female"}{heartage="<30" if totalpoints<1 else 31 if totalpoints=1 else 34 if totalpoints=2 else 36 if totalpoints=3 else 49 if totalpoints=4 else 42 if totalpoints=5 else 45 if totalpoints=6 else 48 if totalpoints=7 else 51 if totalpoints=8 else 55 if totalpoints=9 else 59 if totalpoints=10 else 64 if totalpoints=11 else 68 if totalpoints=12 else 73 if totalpoints=13 else 79 if totalpoints=14 else ">80" if totalpoints>14 else ""}{endif}{=heartage}

Overall Risk Level

Risk LevelInitiate Treatment If:Primary Target (LDL-C)Alternate Target
{if: (gender="male" and totalpoints>14) or (gender="female" and totalpoints>17) and diabetesrisk=0}High
FRS >=20%
• Consider treatment in all (Strong, High)• ≤2 mmol/L or ≥50% decrease in LDL-C (Strong, Moderate)• Apo B ≤0.8 g/L or

• Non-HDL-C ≤2.6 mmol/L (Strong, High){endif}
{if: (gender="male" and (totalpoints>10 and totalpoints<15)) or (gender="female" and (totalpoints>12 and totalpoints<18)) and diabetesrisk=0}Intermediate
FRS 10-19%
• LDL-C ≥3.5 mmol/L (Strong, Moderate)
• For LDL-C <3.5 mmol/L consider if:
• Apo B ≥1.2 g/L
• OR Non-HDL-C ≥4.3 mmol/L
(Strong, Moderate)

Men ≥50 and women ≥60 with 1 risk factor: low HDL-C, impaired fasting glucose, high waist circumference, smoker, hypertension
• ≤2 mmol/L or ≥50% decrease in LDL-C (Strong, Moderate)• Apo B ≤0.8 g/L or • Non-HDL-C ≤2.6 mmol/L (Strong, Moderate){endif}
{if: (gender="male" and totalpoints<11 and diabetesrisk=0) OR (gender="female" and totalpoints<13 and diabetesrisk=0)}Low
FRS <10%
• statins generally not indicated• statins generally not indicated• statins generally not indicated{endif}
{if: diabetesrisk<>0}Statin-indicated conditions• Clinical atherosclerosis
• Abdominal aortic aneurysm
• Diabetes mellitus Age ≥ 40 years 15-Year duration for age ≥ 30 years (DM1) Microvascular disease
• Chronic kidney disease (age ≥ 50 years) eGFR <60 mL/min/1.73 m2 or ACR > 3 mg/mmol
 
{endif}

2 Likes

Thanks !!

For the table, in male need to add, :

{if: (gender="male" and totalpoints>14) and diabetesrisk=0 or (gender="female" and totalpoints>17) and diabetesrisk=0}

Thanks so much again

Good catch!! Just to be safe, I think it'd be best written like this:

{if: ((gender="male" and totalpoints>14) or (gender="female" and totalpoints>17)) and diabetesrisk=0}

1 Like