Several conditions for IF statement

Hello ODK Team,

Apologies if this is poor syntax/understanding of ODK but I am trying to use the if function to automatically interpret results for enumerator ease.

Is it possible to use several results of previous calculations as conditions for several categories? e.g.

If ip_score= 0, and final_pt score = 0 and ph_score = 0 the category = "Normal appearance"

and

if ip_score=1 and final_pt score = 1 and ph_score = 0 the category = "Developing periportal fibrosis not excluded"

and so on.

This seemed to have worked for the first statement:
if((${ip_score}='0') and (${final_pt}='0') and (${ph_score}='0'), 'Normal appearance',0)

but I would (if possible) like to add more, I've tried this but doesn't seem to work:

if((${ip_score}='0') and (${final_pt}='0') and (${ph_score}='0'), 'Normal') && if((${ip_score}='1') and (${final_pt}='1') and (${ph_score}='0'), 'Developing periportal fibrosis not exlcuded')

Essentially I would like the form to automatically come up with the interpretation in this table:

I'd appreciate if you could let me know if I am being too ambitious or if there is a better way.

Thank you in advance

Hello @Germs ,

Yes tou can use nested IFs as long as they are mutually exclusive (each conditions result in a different set of outcome)

The the single if() woud look like
if(condition, value true, value false) if you want them mested, then the second if becomes the value false to its previous if() for example, we use ${v1} and ${v2} both answered with yes as 1 and no as 0 and we perform multiple condition checks as follows:

if(${v1} = 1 and ${v2} =1, 'both yes', if(${v1} = 1 and ${v2} = 0, 'v1 yes and v2 no', if(${v1} = 0 and ${v2} = 1, 'v1 no and v2 yes', 'Both no' )))

Remember:

  • close with as many parenthesis as you opened or in this case as many ifs as you have)
  • the value false to the last if() is your closing
  • use same data type for all values otherwise ODK might throw some conversion errors

I would recommend you read about if() and other conditional functions in the ODK docs (https://docs.getodk.org)

Hoping thia gives you an idea to what you were looking for

Best,
Jules R

2 Likes

Hi Jules,

Thank you very much for your reply!

I have tried what you suggested - three brackets for three ifs:

if(${ip_score}=0 and ${final_pt}=0 and ${ph_score}=0, 'No periportal fibrosis', if (${ip_score}=1 and ${final_pt}=1 and ${ph_score}=0, 'Developing periportal fibrosis not excluded', ${ip_score}=2 and ${final_pt}=1 and ${ph_score}=0, 'Possible periportal fibrosis')))

But got this error message:
: Invalid calculate for the bind attached to "${int_0}" : Unbalanced brackets or parentheses! in expression if( ${ip_score} =0 and ${final_pt} =0 and ${ph_score} =0, 'No periportal fibrosis', if ( ${ip_score} =1 and ${final_pt} =1 and ${ph_score} =0, 'Developing periportal fibrosis not excluded', ${ip_score} =2 and ${final_pt} =1 and ${ph_score} =0, 'Possible periportal fibrosis')))

Same with 4 brackets at the end.

Using 2 brackets at the end gave me this error message:

Something broke the parser. See above for a hint.
Error evaluating field 'int_0' (${interpretation}[1]/int_0[1]): The problem was located in Calculate expression for ${int_0}
XPath evaluation: cannot handle function 'if' requires 3 arguments. Only 4 provided.
Caused by: org.javarosa.xpath.XPathUnhandledException: The problem was located in Calculate expression for ${int_0}
XPath evaluation: cannot handle function 'if' requires 3 arguments. Only 4 provided.
... 10 more

I have read the if() docs extensively but can't quite work out how to translate it into a code that works.

Any insights would be much appreciated

There are only two ifs in this statement and the else for the second if has a condition and a then. Either remove the condition or complete the third if with it's own else ('other/error')

if(${ip_score}=0 and ${final_pt}=0 and ${ph_score}=0, 'No periportal fibrosis', if (${ip_score}=1 and ${final_pt}=1 and ${ph_score}=0, 'Developing periportal fibrosis not excluded', 'Possible periportal fibrosis'))

if(${ip_score}=0 and ${final_pt}=0 and ${ph_score}=0, 'No periportal fibrosis', if (${ip_score}=1 and ${final_pt}=1 and ${ph_score}=0, 'Developing periportal fibrosis not excluded', if(${ip_score}=2 and ${final_pt}=1 and ${ph_score}=0, 'Possible periportal fibrosis', 'last else')))

1 Like

Ah, I didn't realise I was missing an 'if' as well as a bracket!

With your help and that of Jules I finally managed to add the interpretation in the table to my form with this code:

if(${ip_score}=0 and ${final_pt}=0 and ${ph_score}=0, 'No periportal fibrosis', if (${ip_score}=1 and ${final_pt}=1 and ${ph_score}=0, 'Developing periportal fibrosis not excluded', if(${ip_score}=2 and ${final_pt}=1 and ${ph_score}=0, 'Possible periportal fibrosis', if(${ip_score}=4 and ${final_pt}=1 and ${ph_score}=0, 'Probable periportal fibrosis', if(${ip_score}=2 and (${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0, 'Periportal fibrosis', if(${ip_score}=4 and (${final_pt}= 4 or ${final_pt}=8) and ${ph_score}=0, 'Periportal fibrosis 1', if(${ip_score}=6 and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0,'Advanced periportal fibrosis', if(${ip_score}=8 and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0, 'Advanced periportal fibrosis 1', if((${ip_score}= 4 or ${ip_score}=6 or ${ip_score}=8) and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}='>3', 'Advanced periportal fibrosis + Portal Hypertension', 'last else')))))))))

Thank you so much

Edited this code further to reflect the table better in case it helps anyone:

if(${ip_score}=0 and ${final_pt}=0 and ${ph_score}=0, 'Normal Appearance - No periportal fibrosis', if(${ip_score}=1 and ${final_pt}=0 and ${ph_score}=0, 'No periportal fibrosis', if (${ip_score}=1 and ${final_pt}=1 and ${ph_score}=0, 'Developing periportal fibrosis not excluded', if(${ip_score}=2 and ${final_pt}=1 and ${ph_score}=0, 'Possible periportal fibrosis', if(${ip_score}=4 and ${final_pt}=1 and ${ph_score}=0, 'Probable periportal fibrosis', if(${ip_score}=2 and (${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0, 'Periportal fibrosis', if(${ip_score}=4 and (${final_pt}= 4 or ${final_pt}=8) and ${ph_score}=0, 'Periportal fibrosis 1', if(${ip_score}=6 and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0,'Advanced periportal fibrosis', if(${ip_score}=8 and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}=0, 'Advanced periportal fibrosis 1', if(${ip_score}>=4 and (${final_pt}=1 or ${final_pt}=4 or ${final_pt}=8) and ${ph_score}>=3, 'Advanced periportal fibrosis + Portal Hypertension', 'Please ensure filled in correctly/uninterpretable'))))))))))