Hi,
I'm trying to count the number of admissions between two dates in SAS. Data set N =1290. I think an array could solve the problem, but I don't know how to write the syntax. Please help if you can.
I would like to capture total number of visits that occurred between:
INQFROM (inquiry from date is date the patient was discharge home) & INQ30TO (inquiry to date which is the last date of follow up). NC1ADMIT - NC5ADMIT are the hospital readmission dates over the course of 90 days. I am only interested in hospital readmission that occurred within the first 30 days. Here is a sample of what my data set looks like. Thanks so much!
STUDY_ID | INQFROM | INQ30TO | NC1ADMIT | NC2ADMIT | NC3ADMIT | NC4ADMIT | NC5ADMIT | VISIT30DAYS -manual cal. | VISIT30DAYS -SAS |
101 | 5/30/2016 | 6/29/2016 | 6/7/2016 | 8/14/2016 | 1 | ? | |||
102 | 9/23/2016 | 10/23/2016 | 0 | ? | |||||
103 | 1/23/2017 | 2/22/2017 | 5/22/2017 | 0 | ? | ||||
104 | 9/7/2017 | 10/7/2017 | 9/24/2017 | 1 | ? | ||||
105 | 11/24/2016 | 12/24/2016 | 0 | ? | |||||
106 | 3/26/2017 | 4/25/2017 | 6/14/2017 | 6/20/2017 | 6/30/2017 | 7/12/2017 | 7/24/2017 | 0 | ? |
107 | 8/7/2017 | 9/6/2017 | 0 | ? | |||||
108 | 8/15/2018 | 9/14/2018 | 9/18/2018 | 0 | ? | ||||
109 | 9/25/2019 | 10/25/2019 | 10/24/2019 | 1 | ? | ||||
110 | 12/3/2019 | 1/2/2020 | 1/1/2020 | 1 | ? | ||||
111 | 10/18/2018 | 11/17/2018 | 10/30/2018 | 11/16/2018 | 2 | ? | |||
112 | 3/16/2019 | 4/15/2019 | 4/2/2019 | ||||||
113 | 6/8/2017 | 7/8/2017 | 6/22/2017 | 7/3/2017 | 7/17/2017 | ||||
114 | 2/16/2017 | 3/18/2017 | 2/18/2017 | ||||||
115 | 2/5/2018 | 3/7/2018 | |||||||
116 | 7/25/2016 | 8/24/2016 | |||||||
117 | 12/4/2018 | 1/3/2019 | 12/11/2018 | ||||||
118 | 1/30/2017 | 3/1/2017 | 2/25/2017 | 4/8/2017 |
Assuming these are actual SAS date values and not character strings
/* UNTESTED CODE */
data want;
set have;
array x nc1admit nc2admit nc3admit nc4admit nc5admit;
visit30days=0;
do i=1 to dim(x);
if inqfrom<=x(i)<=inq30to then visit30days=visit30days+1;
end;
drop i;
run;
Assuming these are actual SAS date values and not character strings
/* UNTESTED CODE */
data want;
set have;
array x nc1admit nc2admit nc3admit nc4admit nc5admit;
visit30days=0;
do i=1 to dim(x);
if inqfrom<=x(i)<=inq30to then visit30days=visit30days+1;
end;
drop i;
run;
I would set it up like the following:
data blah;
set yourdata;
array ncd {5} nc1admit nc2admit nc3admit nc4admit nc5admit;
nvisits=0;
do i = 1 to dim(ncdates);
if inq30from le ncd(i) le inq30to then nvisits=nvisits+1;
end;
drop i;
run;
If I knew that there are no cases where nc1admit date could be missing but the other four could not (e.g. dates have to be filled 1-5 without skipping) then I would change to this to save processing time:
data blah;
set yourdata;
array ncd {5} nc1admit nc2admit nc3admit nc4admit nc5admit;
nvisits=0;
do i = 1 to dim(ncdates)-nmiss(of ncd(*));
if inq30from le ncd(i) le inq30to then nvisits=nvisits+1;
end;
drop i;
run;
Thank you this one works!
This assumes that the dates are all SAS date values. If not, go back and make them so.
data want; set have; array a NC1ADMIT NC2ADMIT NC3ADMIT NC4ADMIT NC5ADMIT; do i=1 to dim(a); visit30days= sum(visit30days,(inqfrom le a[i] le inq30from)); end; drop i; run;
This uses the SAS behavior of a logical comparison returns 1 or 0 for "true" or "false".
As you work with SAS you will find that names NC1ADMIT and NC2ADMIT for sequential values is cumbersome.
If you name then NCADMIT1 and NCADMIT2, etc, then you can use a list in data step code such as
Array a NCADMIT1 - NCADMIT5 ;
to reference all 5 sequential variables. There are several places that can be handy. But if the sequence indicator is buried in the middle then you have to list the entire variable list every time.
@JeffMeyers wrote:
I'm curious about this version. If all 5 NCXADMIT variables are missing does visit30days also get left missing in this case instead of 0? Would it be better to declare it as 0 first?
Definitely agree with you on the variable naming conventions.
Because of the logical compare a miss value for the admit will make the comparison false and the result is 0. So you get a result of 0 or 1 for every comparison, missing or not. So the SUM always has a value to work with.
data example; input d; x=1; y=5; result= (x le d le y); datalines; 0 1 3 5 6 . ;
@JeffMeyers wrote:
Nice, that's slick. Thanks for explaining.
And of course that would NOT work with : visitcount + (x le d le y)
without initializing the visitcount to 0 as the + operator requires both values to be non-missing.
You probably know that but just in case someone else reading this isn't familiar (yet) with the + behavior.
data have;
input STUDY_ID $ (INQFROM INQ30TO NC1ADMIT NC2ADMIT NC3ADMIT NC4ADMIT NC5ADMIT ) ( :mmddyy10.);
format INQFROM INQ30TO NC1ADMIT NC2ADMIT NC3ADMIT NC4ADMIT NC5ADMIT mmddyy10.;
infile cards truncover;
cards;
101 5/30/2016 6/29/2016 6/7/2016 8/14/2016
102 9/23/2016 10/23/2016
103 1/23/2017 2/22/2017 5/22/2017
104 9/7/2017 10/7/2017 9/24/2017
105 11/24/2016 12/24/2016
106 3/26/2017 4/25/2017 6/14/2017 6/20/2017 6/30/2017 7/12/2017 7/24/2017
107 8/7/2017 9/6/2017
108 8/15/2018 9/14/2018 9/18/2018
109 9/25/2019 10/25/2019 10/24/2019
110 12/3/2019 1/2/2020 1/1/2020
111 10/18/2018 11/17/2018 10/30/2018 11/16/2018
;
run;
data want;
set have;
array nc[*] NC:;
array vis[999] _temporary_;
call missing(of vis[*]);
do i=1 to dim(nc);
if ^ missing(nc[i]) then
do;
if nc[i] < intnx('days',INQFROM,30) then
vis[i]=1;
end;
end;
VISIT30DAYS =sum(of vis[*]);
drop i;
run;
Thanks everyone for your help! I was pulled to help with a grant application so haven't had time to test the codes. I plan to test each of them at some point next week.
Again, your help is very much appreciated!
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.