I have a list of opioids that need to flag for. I need to flag for these opioids in the variable called MEDS which is a free form text variable.
There are about 40-50 opioids that I need to flag for.
My current solition is to do a simple prxmatch for each of the 40-50 opioids (not very efficient). For example:
data opioid_analysis; set medeval.opioid; /*Opiod Flagging*/ if prxmatch("m/Butrans|Codeine|Dalmacol|Demerol\/pethidine|Dilaudid|Dimetapp-C|Dimethane|Duragesic|Hycodan|Hydromorph Contin|Kadian|Lenoltec|Methadone|Methoxacet/oi", MED_REC_PMED1)> 0 then opioid = 1; else opioid=0; run;
I'm wondering how others might tackle this problem?
None of the opioids have anything really in common in the string name. Is there a better way to ensure that I capture all the opioids? A more efficient way rather than having to spell out all the opioids like this?
thanks in advance!
Here's an expansion of what I think @Ksharp's array suggestion may have been getting at.
data want; set medval.opioid; array drugs {4} $ 40 _temporary_ ('Butrans' 'Codeine' 'Dalmacol' 'Demerol'); do i = 1 to dim (drugs); opioid = Findw(MED_REC_PMED1,drugs[i],'I')>0; if opioid = 1 then leave; /* stops searching a the first one found*/ end; run;
This demonstrates searching for 4 values, to use more the index on the array {4} would have to match the number of drugs searched, and enter each drug inside the () following the pattern. The 40 is to set the length of character values if the maximum length of any name is greater then increase, or reduce as seems likely.
If you want to know which is found you could add:
(before the Do loop)
length Found $ 40; Number here should match the array element size.
Inside the do loop:
Found = drugs[i];
1) Hash Table
2)PROC FORMAT
3) Array:
data x;
array x{50} $ 40 ('xx' 'yy' .....);
flag=( name in x);
Thanks @Ksharp I think this might be a littel over my head as I don't really understand your answer.
Does anyone else have any other ideas or can elaborate on the answer a bit so I can understand.
Here's an expansion of what I think @Ksharp's array suggestion may have been getting at.
data want; set medval.opioid; array drugs {4} $ 40 _temporary_ ('Butrans' 'Codeine' 'Dalmacol' 'Demerol'); do i = 1 to dim (drugs); opioid = Findw(MED_REC_PMED1,drugs[i],'I')>0; if opioid = 1 then leave; /* stops searching a the first one found*/ end; run;
This demonstrates searching for 4 values, to use more the index on the array {4} would have to match the number of drugs searched, and enter each drug inside the () following the pattern. The 40 is to set the length of character values if the maximum length of any name is greater then increase, or reduce as seems likely.
If you want to know which is found you could add:
(before the Do loop)
length Found $ 40; Number here should match the array element size.
Inside the do loop:
Found = drugs[i];
thanks @ballardw! that helps me understand. I'll have to do a bit more research!
If you don't have a big table, you also could try SQL. data key; input k $20.; cards; Butrans Codeine Dalmacol Demerol ; run; data have; input id $20.; cards; BBButrans Ceine Dcol Demerolll ; run; proc sql; select *,case when exists(select * from have,key where id=a.id and upcase(id) contains strip(upcase(k))) then 1 else 0 end as opioid from have as a; quit;
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.