I need to concatenate 2 or more variables if both are present like below
%if SECREAS1 ne '' and SECREAS2 ne '' %then %do;
sec_reasons=catx(';', SECREAS1,SECREAS2);
%end;
%if SECREAS1 ne '' and SECREAS2 eq '' %then %do;
sec_reasons=SECREAS1;
%end;
But if i have another reason like SECREAS3 and SECREAS4 then it will be more complex to do. is there any better way to do.
subj | SECREAS1 | SECREAS2 | SECREAS3 | SECREAS4 |
101 | Adverse event | Withdraw by consent | ||
102 | LOC | Other | LOC | Withdraw by consent |
103 | Withdraw by consent | LOC | Withdraw by consent | Other |
Its been mentioned time and time again, post test data in the form of a datastep, as text in the post, and show what output you want.
What do you want the output when all four are present, all cat'd? If so then:
catx(',',of screas:);
Should be fine, if it is only pairs, what is the precedence? Should it be Loc: <reas1>,<reas 2> etc.?
Its been mentioned time and time again, post test data in the form of a datastep, as text in the post, and show what output you want.
What do you want the output when all four are present, all cat'd? If so then:
catx(',',of screas:);
Should be fine, if it is only pairs, what is the precedence? Should it be Loc: <reas1>,<reas 2> etc.?
i do not have test data for this case but making a code which can work on any number of condtions.
the below one suggested by you works well
catx(',',of screas:);
but i am thinking how can i control the %if conditions.
If i have value only in sec_reason1 then it should be displayed as it is but if i have values in sec_reason1 and sec_reason2 then it should concatenate with semicolon in middle the same if we have values in the rest of sec_reasons3 or 4(in case if we have).
%if is macro language, nothing to do with datastep language, they are very different and for different purposes.
If you are making general code for a library or something like that then you will have a functional design specification document which clearly shows all inputs outputs, explains logic, program flow, checks performed etc. So you should have a good idea of the inputs you will get. The cat functions will only concatenate when there is a value present, but that might not cover all eventualities.
Another point, why do you have SCREAS1-x. In standard CDISC models screen fail reasons would be held in SUPPDS domain as:
QNAM QVAL
SCRNREAS ...
And this would only capture where there is data, so to get a complete list of reason you would do:
data want; set suppds (where=(qnam="SCRNREAS")); by usubjid; length reas $2000; reas=ifc(first.usubjid,qval,catx(';',reas,qval)); if last.usubjid then output; run;
Or combine that somehow into existing domain modelling code.
%if SECREAS1 ne '' and SECREAS2 ne '' %then %do;
sec_reasons=catx(';', SECREAS1,SECREAS2);
%end;
an interesting mixture of datastep and macro code, most likely not working as expected.
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.