BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
andyec
Fluorite | Level 6

I'm working with a dataset of lab values, and if an ID has at least 2 lab values within 7 days of each other, I would like to create a row of those values and associated dates. That way, I can look at the rows that have non-missing value2, value3, etc. Please see a simulated dataset below and the dataset I would like to create.

 

Table 1. Have

obsiddatevalue
115/30/1920
215/31/1920
316/1/1919
416/10/19177
517/7/19350
617/10/19200
721/3/19100
831/4/1999
933/6/1919
1033/8/1920
11312/8/191500

 

Table 2. Want

obsiddate1date2date3value1value2value3
115/30/195/31/196/1/19202019
216/10/19  177  
317/7/197/10/19 350200 
421/3/19  100  
531/4/19  99  
633/6/193/8/19 1920 
6312/8/19  1500  
1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Hi @andyec  The idea is basically to group the intervals and transpose the contents of the group to wide structure. 

 


data have;
	infile datalines ;
	input obs id date:MMDDYY10. value;
	format date MMDDYY10.;
	drop obs;
	datalines;
1	1	5/30/19	20
2	1	5/31/19	20
3	1	6/1/19	19
4	1	6/10/19	177
5	1	7/7/19	350
6	1	7/10/19	200
7	2	1/3/19	100
8	3	1/4/19	99
9	3	3/6/19	19
10	3	3/8/19	20
11	3	12/8/19	1500
;
run;

data temp;
 set have;
 by id;
 if dif(date)>7 then grp+1;
 if first.id then grp=1;
run;

proc sql noprint;
select max(m) into :m trimmed
from (select max(grp) as m from temp group by id);
quit;

%put &=m;

data want;
 do _n_= 1 by 1 until(last.grp);
  set temp;
  by id grp;
  array dt  date1-date&m;
  array v value1-value&m;
  dt(_n_)=date;
  v(_n_)=value;
 end;
 format date: mmddyy10.;
 drop date value grp;
run;


View solution in original post

9 REPLIES 9
ed_sas_member
Meteorite | Level 14

Hi @andyec 

 

You can try this:

data have;
	infile datalines dlm="09"x;
	input obs id date:MMDDYY10. value;
	format date MMDDYY10.;
	datalines;
1	1	5/30/19	20
2	1	5/31/19	20
3	1	6/1/19	19
4	1	6/10/19	177
5	1	7/7/19	350
6	1	7/10/19	200
7	2	1/3/19	100
8	3	1/4/19	99
9	3	3/6/19	19
10	3	3/8/19	20
11	3	12/8/19	1500
;
run;

data have_flag;
	do i=1 until(last.id);
		set have;
		format date7 MMDDYY10.;
		by id;
		retain date7;
		if first.id then date7 = date;
		if date-date7 > 7 then date7 = date;
	end;
run;

proc transpose data=have_flag out=have_tr1 prefix=date;
	var date;
	by id date7;
run;

proc transpose data=have_flag out=have_tr2 prefix=value;
	var value;
	by id date7;
run;

data want;
	merge have_tr1 have_tr2;
	by id date7;
	drop _name_ date7;
run;

 

Best,

Capture d’écran 2020-05-19 à 18.28.37.png

novinosrin
Tourmaline | Level 20

Hi @andyec  The idea is basically to group the intervals and transpose the contents of the group to wide structure. 

 


data have;
	infile datalines ;
	input obs id date:MMDDYY10. value;
	format date MMDDYY10.;
	drop obs;
	datalines;
1	1	5/30/19	20
2	1	5/31/19	20
3	1	6/1/19	19
4	1	6/10/19	177
5	1	7/7/19	350
6	1	7/10/19	200
7	2	1/3/19	100
8	3	1/4/19	99
9	3	3/6/19	19
10	3	3/8/19	20
11	3	12/8/19	1500
;
run;

data temp;
 set have;
 by id;
 if dif(date)>7 then grp+1;
 if first.id then grp=1;
run;

proc sql noprint;
select max(m) into :m trimmed
from (select max(grp) as m from temp group by id);
quit;

%put &=m;

data want;
 do _n_= 1 by 1 until(last.grp);
  set temp;
  by id grp;
  array dt  date1-date&m;
  array v value1-value&m;
  dt(_n_)=date;
  v(_n_)=value;
 end;
 format date: mmddyy10.;
 drop date value grp;
run;


andyec
Fluorite | Level 6

@ed_sas_member and @novinosrin thank you very much for your replies. I was able to get both to work with the simulated data provided.

 

@novinosrin when I use your code on the real dataset, I get an excessive number of value and date variables, and it seems to be the maximum amount of times an ID appears (not the maximum amount of times an ID appears to have a certain amount of values within 7 days). Any idea why this might be?

 

Lastly, I was wondering how I would add in one more additional variable that corresponds to every value. The variable is psource and can be seen in this post Count number of times within a timeframe by id, multiple occurrences by id possible .

 

 

ed_sas_member
Meteorite | Level 14

Hi @andyec 

 

Would the additional variable psource be splitted in psource1, psource2, psource3 as well? 

ed_sas_member
Meteorite | Level 14

Hi @andyec 

 

I have added a proc transpose step at the end of the program, just before the merge:

data have_flag;
	do i=1 until(last.id);
		set have;
		format date7 MMDDYY10.;
		by id;
		retain date7;
		if first.id then date7 = date;
		if date-date7 > 7 then date7 = date;
	end;
run;

proc transpose data=have_flag out=have_tr1 prefix=date;
	var date;
	by id date7;
run;

proc transpose data=have_flag out=have_tr2 prefix=value;
	var value;
	by id date7;
run;

proc transpose data=have_flag out=have_tr3 prefix=psource;
	var psource;
	by id date7;
run;

data want;
	merge have_tr1 have_tr2 have_tr3;
	by id date7;
	drop _name_ date7;
run;

Best,

novinosrin
Tourmaline | Level 20

Hi @andyec  My apologies, I overlooked something and that's very silly of me. First try this change and test in full and let me know if this works, and then I shall delve into your additional requirement. Sorry again

proc sql noprint;
select max(m) into :m trimmed
from (select count(grp) as m from temp group by id,grp);
quit;

%put &=m;
novinosrin
Tourmaline | Level 20

Okay good @andyec  Are you able to modify the code to get the additional variables too. Methinks, another array and assignment statement like the following should do

array p psource1-psource&m;
p(_n_)=psource;

should do. 🙂 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 9 replies
  • 765 views
  • 5 likes
  • 3 in conversation