BookmarkSubscribeRSS Feed
monday89
Fluorite | Level 6

I have a 1) reference table for medications and 2) patient level data for medications

 

Reference table for medications

med_id med_name
1 ABC
2 DEF
3 GHI
4 JKL
5 MNO
6 PQR
7 STU
8 VWX
9

YZ

 

2) Patient Level Data

patientId med_name medication
123 ABC 1
123 GHI 1
123 JKL 1
123 PQR 1
456 DEF 1
456 GHI 1

 

 

What I want to do is that join both reference med and patient level but indicate the patients that are not on certain medications. 

 

patientId med_name medication
123 ABC 1
123 DEF 0
123 GHI 1
123 JKL 1
123 MNO 0
123 PQR 1
123 STU 0
123 VWX 0
123 YZ 0
456 ABC 0
456 DEF 1
456 GHI 1
456 JKL 0
456 MNO 0
456 PQR 0
456 STU 0
456 VWX 0
456 YZ 0

 

What I did was:

proc sql;

select a.*, b.med_name

from patient left join medtable a on med_name = med_name;quit;

 

2 REPLIES 2
Tom
Super User Tom
Super User

So you want to expand the number of observations so there is one observation for every medication for each patient?

Do you want the MEDICATION variable to be copied over, but set to zero on the new observations?  Or are you looking for new variable that is 1 when the observation was in the patient table and zero when it wasn't?

Here is a straight forward way to do this. First make a skeleton of the final dataset that has all of the possible observations. Then merge it with your patient data.

proc sql ;
create table skeleton as
select patientid,med_name
from (select distinct patientid from patient)
   , (select distinct med_name from medtable)
order by patientid,med_name
;
quit;

data want;
  merge skeleton patient(in=in2);
  by patientid med_name;
  want = in2;
run;
       patient
Obs      Id       med_name    medication    want

  1      123        ABC            1          1
  2      123        DEF            .          0
  3      123        GHI            1          1
  4      123        JKL            1          1
  5      123        MNO            .          0
  6      123        PQR            1          1
  7      123        STU            .          0
  8      123        VWX            .          0
  9      456        ABC            .          0
 10      456        DEF            1          1
 11      456        GHI            1          1
 12      456        JKL            .          0
 13      456        MNO            .          0
 14      456        PQR            .          0
 15      456        STU            .          0
 16      456        VWX            .          0

 

PGStats
Opal | Level 21

With SQL, use a cross join:

 

data names;
input med_id med_name :$3.;
datalines;
1 ABC
2 DEF
3 GHI
4 JKL
5 MNO
6 PQR
7 STU
8 VWX
9 YZ
;
data meds;
input patientId   med_name :$3.   medication;
datalines;
123     ABC     1
123     GHI     1
123     JKL     1
123     PQR     1
456     DEF     1
456     GHI     1
;

proc sql;
select 
	a.patientId,
	b.med_name,
	coalesce(c.medication, 0) as medication
from
(select distinct patientId from meds) as a cross join
(select distinct med_name from names) as b left join
meds as c on a.patientId=c.patientId and b.med_name=c.med_name;
quit;
PG

sas-innovate-2024.png

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.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 435 views
  • 0 likes
  • 3 in conversation