I have five different treatments for the patients in my dataset.
I am trying to create a prior treatment variable that has the following response options: surgery+other treatment, immunotherapy+other treatment, radiotherapy+other treatment, chemotherapy+hormonal treatment, surgery, immunotherapy, radiotherapy, chemotherapy, hormonal treament, none of listed treatments.
I would like my data to look similar to the data below:
Pt # surgery immunerx radiotherapy chemotherapy hormonal priorrx
1 yes yes no yes no surgery+other treatment
2 yes no yes no no surgery+other treatment
3 yes no no no no surgery
4 no yes yes yes no immunerx+other treatment
5 no yes no no no immunerx
6 no no yes no no radiotherapy
and so on...
I have a variable for surgery, immunotherapy, radiotherapy, chemotherapy and hormonal therapy with response options of Yes/No.
I was trying to create a do loop to cover all the different permutations and combinations. I am getting a note and errors in the log. I feel like it must be something simple, but can't figure out what I am doing wrong. In my code the else if statements are colored purple. I know that something is wrong based on that also.
Please find the portion of the log below with the errors and notes:
2705 *-----------------;
2706 *calculate priorrx;
2707 *-----------------;
2708
2709 if surgery='Yes' or immunerx='Yes' or
2709! radiotherapy='Yes' or chemotherapy='Yes' or hormonal='Yes'
2709! then do;
2710 if surgery='Yes and (immunerx='Yes' or
--------------------
-------------------
-------------------
---------------
-----------------
---------------------------
49 49
49
49
49
49
---
388
---
76
2710! radiotherapy='Yes' or chemotherapy='Yes' or
2710! hormonal='Yes') then priorrx='surgery+other treatment';
2711 else if surgery='Yes' and (immunerx='No' and
2711! radiotherapy='No' and chemotherapy='No' and
2711! hormonal='No') then priorrx='surgery';
-----------------
49
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
ERROR 388-185: Expecting an arithmetic operator.
ERROR 76-322: Syntax error, statement will be ignored.
2712
2713 else if surgery='No' and immunerx='Yes' and
----------------
---------------------
-------------------
---------------
-----------------
----------------------------
49 49
49
49
49
49
2713! (radiotherapy='Yes' or chemotherapy='Yes' or
2713! hormonal='Yes') then priorrx='immunotherapy+other
2713! treatment';
2714 else if immunerx='Yes' and (radiotherapy='No' and
2714! chemotherapy='No' and hormonal='No') then
------------------
49
2714! priorrx='immunotherapy';
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
2715
2716 else if immunerx='No' and radiotherapy='Yes' and
--------------------
---------------------
---------------
-----------------
--------------------------------
49 49
49
49
49
2716! (chemotherapy='Yes' or hormonal='Yes') then
2716! priorrx='radiotherapy+other treatment';
2717 else if radiotherapy='Yes' and (chemotherapy='No'
2717! and hormonal='No') then priorrx='radiotherapy';
-----------------
49
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
2718
2719 else if radiotherapy='No' and chemotherapy='Yes' and
--------------------
----------------
----------------
--------------------------------
49 49
49
49
2719! hormonal='Yes' then priorrx='chemotherapy+hormonal
2719! treatment';
2720 else if chemotherapy='Yes' and homronal='No'
----------------
49
2720! then priorrx='chemotherapy';
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
2721
2722 else if chemotherapy='No' and hormonal='Yes' then
----------------
----------------
49 49
2722! priorrx='hormonal treatment';
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
2723
2724 else priorrx='none of listed treatments';
2725
2726 end;
2727
--
49
NOTE 49-169: The meaning of an identifier after a quoted string
might change in a future SAS release. Inserting
white space between a quoted string and the
succeeding identifier is recommended.
Any help that could be provided would be greatly appreciated. I am using SAS 9.4 TS Level 1M3.
Thanks.
100% correct. Switch the order of these two:
else priorrx='none of listed treatments';
end;
Post the actual code used please.
The immediate problem is that you are missing a closing quote here:
2710 if surgery='Yes and
Sometimes when you fix one problem, it reveals another. We'll have to wait and see.
Please find the actual code below:
data analysis;
retain blind studyid usubjid siteid racegr1 racegrp country cntrygrp age visceral nonvisceral;
length totcomorbid racegrp cntrygrp $20 visit combined_site totmetsites $200;
set analysisallp1 analysisallp2;
where itt='Yes';
if comorbid=0 then totcomorbid='0';
else if comorbid=1 then totcomorbid='1';
else totcomorbid='2 or more';
if ^missing(orgnnuminv) then do;
if orgnnuminv = 0 or orgnnuminv=1 then totmetsites = '0 to 1';
else if orgnnuminv>1 then totmetsites='2 and above';
end;
else totmetsites = 'Missing';
*-----------------;
*calculate priorrx;
*-----------------;
if surgery='Yes' or immunerx='Yes' or radiotherapy='Yes' or chemotherapy='Yes' or hormonal='Yes' then do;
if surgery='Yes' and (immunerx='Yes' or radiotherapy='Yes' or chemotherapy='Yes' or hormonal='Yes') then priorrx='surgery+other treatment';
else if surgery='Yes' and (immunerx='No' and radiotherapy='No' and chemotherapy='No' and hormonal='No') then priorrx='surgery';
else if surgery='No' and immunerx='Yes' and (radiotherapy='Yes' or chemotherapy='Yes' or hormonal='Yes') then priorrx='immunotherapy+other treatment';
else if immunerx='Yes' and (radiotherapy='No' and chemotherapy='No' and hormonal='No') then priorrx='immunotherapy';
else if immunerx='No' and radiotherapy='Yes' and (chemotherapy='Yes' or hormonal='Yes') then priorrx='radiotherapy+other treatment';
else if radiotherapy='Yes' and (chemotherapy='No' and hormonal='No') then priorrx='radiotherapy';
else if radiotherapy='No' and chemotherapy='Yes' and hormonal='Yes' then priorrx='chemotherapy+hormonal treatment';
else if chemotherapy='Yes' and hormonal='No' then priorrx='chemotherapy';
else if chemotherapy='No' and hormonal='Yes' then priorrx='hormonal treatment';
else priorrx='none of listed treatments';
end;
label OVRLRESP="Visit Overall Response-INV"
risk="Prognostic risk level"
icmstdtn="Imputed conmed start date (numeric)"
icmendtn="Imputed conmed end date (numeric)";
run;
I think I figured out the issue. I think the else statement needs to go afte the end statement, if my thinking is correct.
I woudl not want to track all that branching and elses and else ifs.
I would be more likely to do something like:
if surgery = 'Yes' and (immunerx = 'No' and radiotherapy = 'No' and chemotherapy = 'No'
and hormonal = 'No') then priorrx = 'Surgery';
if surgery = 'Yes' and (immunerx = 'Yes' or radiotherapy = 'Yes' or chemotherapy = 'Yes'
or hormonal = 'Yes') then priorrx = 'Surgery plus other treatment';
if surgery = 'No' and immunerx = 'Yes' and (radiotherapy = 'No' and chemotherapy = 'No'
and hormonal = 'No') then priorrx = 'Immunerx';
if surgery = 'No' and immunerx = 'Yes' and (radiotherapy = 'Yes' or chemotherapy = 'Yes'
or hormonal = 'Yes') then priorrx = 'Immunerx plus other treatment';
if surgery = 'No' and immunerx = 'No' and radiotherapy = 'Yes' and (chemotherapy = 'No'
and hormonal = 'No') then priorrx = 'radiotherapy';
if surgery = 'No' and immunerx = 'No' and radiotherapy = 'Yes' and (chemotherapy = 'Yes'
or hormonal = 'Yes') then priorrx = 'Radiotherapy plus other treatment';
etc
100% correct. Switch the order of these two:
else priorrx='none of listed treatments';
end;
I've been known to build a text variable consisting of 1 and 0 for Yes and No in order for a list of variables and then using a custom format to display the value.
A brief example:
Proc format library=work; value $FakeBinary '11' = 'Both Yes' '10' = 'Only first Yes' '01' = 'Only 2nd Yes' '00' = 'Both No' ; run; data junk; input v1 $ v2 $; FakeBin = cats(v1='Yes',v2='Yes'); format FakeBin FakeBinary.; datalines; Yes Yes Yes No No Yes No No ; run;
Of course the real world does need to consider the cases where one of your dichotomous Yes/No variables is actually missing as well if that is possible.
The format approach I find useful because I know that if I have 4 variables that I need to 2**4 cases and if the combinations get a bit tricky then the IF/Then/Else code can be come very complex. But in a format I can have the values laid out nicely so that I can see that the first, third and 5th items are all 1 and assign the formatted value easily. (Yes 5 variables means 32 possibilities to consider)
I don't like using that many nested if-statements. In the past various flags were stored in a single numeric variable, to save memory. So, i translated the "Yes" to 1 and "No" to 0, concatenated the 1s and 0s and used a format to get the requested text. The data-step has been reduced to the creation of priorrx.
proc format;
value priorrxFmt
1 = 'hormonal treatment'
2 = 'chemotherapy'
3 = 'chemotherapy+other treatment'
4 = 'radiotherapy'
5-7 = 'radiotherapy+other treatment'
8 = 'immunotherapy'
9-15 = 'immunotherapy+other treatment'
16 = 'Surgery'
17-31 = 'Surgery+other treatment'
other = 'none of listed treatments'
;
run;
data want;
length binaryString $ 5 priorrx $ 40;
set have;
array t surgery immunerx radiotherapy chemotherapy hormonal;
do i = 1 to dim(t);
binaryString = cats(binaryString, ifc(t{i} = 'Yes', '1', '0'));
end;
priorrx = put(input(binaryString, binary5.), priorrxFmt.);
drop binaryString;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.