I'm trying to use an array to change my dataset from multiple rows per patient to a single row per patient with many columns. It was working perfectly until I tried adding a second array for another medication type and goofed something up. I'm not seeing what I messed up; need another pair of eyes to take a look. Here's the code I'm using. The error is array subscript out of range, and the log shows that I=11. Please help!!!
DATA MEDS ;
SET GET_COUNTS ;
BY PATIENT_ID ;
FORMAT CLINDAMYCIN CEPHALOSPORIN FLOUROQUINOLONE VANCOMYCIN PPI 1. ;
RETAIN CLINDAMYCIN CEPHALOSPORIN FLOUROQUINOLONE VANCOMYCIN PPI ;
* 1 = YES, 0 = NO ;
CLINDAMYCIN = 0 ;
CEPHALOSPORIN = 0 ;
FLOUROQUINOLONE = 0 ;
VANCOMYCIN = 0 ;
PPI = 0 ;
ARRAY ABX[*] $ 15. ABX1 - ABX10 ;
RETAIN ABX1 - ABX10 ;
IF FIRST.PATIENT_ID THEN DO I = 1 TO 10 ;
ABX[I] = ' ' ;
END ;
ABX[ABX_COUNT] = ABX_NAME ;
DO I = 1 TO 10 ;
IF ABX[I] = 'CLINDAMYCIN' THEN CLINDAMYCIN = '1' ;
END ;
DO I = 1 TO 10 ;
IF ABX[I] IN ('CEFUROXIME', 'CEFPROZIL', 'CEFACLOR', 'CEFTRIAXONE', 'CEFOTAXIME' )
THEN CEPHALOSPORIN = '1' ;
END ;
DO I = 1 TO 10 ;
IF ABX[I] IN ('CIPROFLOXACIN', 'LEVOFLOXACIN', 'GATIFLOXACIN', 'MOXIFLOXACIN', 'OFLOXACIN' )
THEN FLOUROQUINOLONE = '1' ;
END;
DO I = 1 TO 10 ;
IF ABX[I] = 'VANCOMYCIN' THEN VANCOMYCIN = '1' ;
END ;
IF LAST.PATIENT_ID THEN OUTPUT ;
KEEP PATIENT_ID AGEGRP GENDER STUDY_GRP ABX_COUNT ABX1 - ABX10 CLINDAMYCIN CEPHALOSPORIN FLOUROQUINOLONE VANCOMYCIN PPI ;
RUN ;
This statement
ABX[ABX_COUNT] = ABX_NAME ;
is the most likely culprit. Variable I will always be 11 after a do loop that counts to 10 has finished.
So look for the values of abx_count in your dataset.
Please post test data in the form of a datastep in teh post (use the {i} window to add code in). Its also very hard to read your code which is all in upcase. From what I can tell roughly all you are doing is setting a flag based on the drug, so you could just transpose the data. Its very hard to tell however without some inputs and some required output. Note, I would avoid using real information (I recognise those drug names for instance).
Adding example:
proc transpose data=have out=inter1 prefix=abx; by patient_id; var abx_med; run; proc transpose data=have out=inter2 prefix=other; by patient_id; var othervar; run; data want; merge inter1 inter2; by patient_id; abx_c=catx(',',of abx:); do i=1 to countw(abx_c,","); select(scan(abx_c,i,",")); when("CEF.....) var1=1; ... end; end; run;
Do also note that whilst you make the drug variables numeric, you are assigning characters to them later in your code, not good practice:
CLINDAMYCIN = 0 ; <= numeric
IF ABX[I] = 'CLINDAMYCIN' THEN CLINDAMYCIN = '1' ; <=char
This statement
ABX[ABX_COUNT] = ABX_NAME ;
is the most likely culprit. Variable I will always be 11 after a do loop that counts to 10 has finished.
So look for the values of abx_count in your dataset.
Thank you. Is there a way to stop the DO loop once the desired result is found?
You are correct! I have an initial count of 0. The eleven was not the problem!
Thank you!!!
Yes, although it will require that you fix some earlier details. Right now, you have:
DO I = 1 TO 10 ;
IF ABX[I] = 'CLINDAMYCIN' THEN CLINDAMYCIN = '1' ;
END ;
Since CLINDAMYCIN was created as a numeric variable, remove the quotes around '1'.
To end the loop once a match is found:
DO I = 1 TO 10 until (CLINDAMYCIN = 1);
IF ABX[I] = 'CLINDAMYCIN' THEN CLINDAMYCIN = 1 ;
END ;
Note that this has nothing to do with your original problem, which still requires investigating ABX_COUNT.
Alternatively to the "until" approach you can use a leave instruction.
Inside any do loop:
do <loop control>;
<code>;
if condition is true then Leave;
<more code to execute when the condition is not true>
end;
Will exit the do loop before hitting the bottom end
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 16. 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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: