SAS (Base SAS)+
*==============================================================================;
* Create the input dataset;
*==============================================================================;
data concat;
input usubjid visitnum result$;
datalines;
101 1 Y
101 2 N
101 3 Y
102 1 Y
102 2 N
102 3 .
102 4 N
102 5 Y
;
run;
*==============================================================================;
*Concatenate non-missing results into a single string;
*==============================================================================;
proc sort data=concat;
by usubjid visitnum;
run;
data concat01;
set concat;
by usubjid visitnum;
length all_results $32767;
retain all_results;
if first.usubjid then all_results=result;
else if not missing(result) then all_results=catx(";",all_results,result);
if last.usubjid;
keep usubjid all_results;
run;- To collapse a character column across a subject into a single semicolon-separated string, we use
RETAINtogether withCATXand keep only the last row per subject. - We give
all_resultsa generous length ($32767) up front so the catx build has room to grow — the default length would truncate long concatenations. if first.usubjid then all_results = result;primes the string with the first value of the subject.- On every subsequent row,
catx(";", all_results, result)appends the current result with a semicolon separator, ignoring empty values automatically. if last.usubjid;is a subsettingif— it keeps only the final row per subject, which by now holds the fully-built string.- We
keep usubjid all_results;to drop the per-row columns and return one row per subject with the concatenated results. - After running, we check that each subject appears once in
concat01andall_resultsis a single string joining all non-missing results with semicolons.