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
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.