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

Hey everyone,

 

I've got 2 columns of data: x (a unique person identifier) and y (a date at which an action was performed by x). Some x'es occur more than once, and thus take up multiple rows. I've got the 2 columns sorted by x then by y so I have a list of all actions for each person's identifier and when they occurred. I would like to count the number of times that a person has performed an action in the past 90 days prior to date y, for all rows. My data (and my desired output) looks something like this:

 

 

     x                y                    desired output

 

   a1154        7/1/2018                     3

 

   a1154        6/22/2018                   2

 

   a1154        6/1/2018                     1

 

   a1154        5/25/2018                   0

 

   a2266       11/11/2018                  0

 

   a2266       1/1/2017                     0

 

   a1997       5/12/2018                   0

 

   a2111       5/18/2016                   1

 

   a2111       5/15/2016                   0

 

 

To do this, I am using lags. I am creating two variables (emp<n> and dd<n>) that use lag1, lag2, ... lag365 to compare each row with the nth row underneath it to see if there is an x match and if y is within the 90 day mark. I am doing this using macros. Here is my code:

 

macro check;

data macro_output;

set datasource;

do p=1 to 365;

emp&p = lag&p(x);

dd&p = lag&p(y)

end;

mend check;

check;

macro still;

data finaloutput;

set macro_output;

output = 0;

n=1;

do until (n >= Last.x );

do p=1 to 365;

if x = emp&p & y < dd&p+90 then output = p;

end;

n=n+1;

end;

mend still;

still;

run;

 

 

 

When I run this, I get the error "ERROR 180-322: Statement is not valid or it is used out of proper order".

 

This error is occurring inside "run;", and SAS is telling me that the affected code is "%LET_CLIENTTASKLABEL=;" at line 59 and log line 51. 

 

 

 

I have absolutely no idea what this means. From other threads and questions, I have seen this error usually attributed to a missing semicolon or a typo in the code. However, I do not believe this is the case here. I am writing this as a manually coded program inside Enterprise Guide 7.1. Would anyone please be able to help me figure this error out? Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Hi @jonesj22   I have absolutely no clue or understanding of the objective in having a macro here assuming my understanding of the logic i.e from what you wrote "I would like to count the number of times that a person has performed an action in the past 90 days prior to date y, for all rows"

 

Assuming i understand this bit

 

The logic seems far too simple.

 


data have;
     input x         $       y      :mmddyy10.   ;           
format y mmddyy10.;
 cards;
   a1154        7/1/2018                     3
   a1154        6/22/2018                   2
   a1154        6/1/2018                     1
   a1154        5/25/2018                   0
   a2266       11/11/2018                  0
   a2266       1/1/2017                     0
   a1997       5/12/2018                   0
   a2111       5/18/2016                   1
   a2111       5/15/2016                   0
   ;

 
proc sql;
create table want as
select a.*,sum( intnx('days',a.y,-90)<=b.y<a.y) as count 
from have a, have b
where a.x=b.x 
group by a.x,a.y
order by a.x, a.y desc;
quit;

 

If I overlooked something, please correct me. Thank you!

 

 

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

place this command at the top of your program and run it again

 

options mprint symbolgen mlogic;

Then show us the ENTIRE SAS log, not just the error message. To do this, click on the {i} icon and paste the ENTIRE log into the window that appears.

--
Paige Miller
novinosrin
Tourmaline | Level 20

Hi @jonesj22   I have absolutely no clue or understanding of the objective in having a macro here assuming my understanding of the logic i.e from what you wrote "I would like to count the number of times that a person has performed an action in the past 90 days prior to date y, for all rows"

 

Assuming i understand this bit

 

The logic seems far too simple.

 


data have;
     input x         $       y      :mmddyy10.   ;           
format y mmddyy10.;
 cards;
   a1154        7/1/2018                     3
   a1154        6/22/2018                   2
   a1154        6/1/2018                     1
   a1154        5/25/2018                   0
   a2266       11/11/2018                  0
   a2266       1/1/2017                     0
   a1997       5/12/2018                   0
   a2111       5/18/2016                   1
   a2111       5/15/2016                   0
   ;

 
proc sql;
create table want as
select a.*,sum( intnx('days',a.y,-90)<=b.y<a.y) as count 
from have a, have b
where a.x=b.x 
group by a.x,a.y
order by a.x, a.y desc;
quit;

 

If I overlooked something, please correct me. Thank you!

 

 

jonesj22
Calcite | Level 5

This is exactly what I was looking to do, thank you. I am not nearly as proficient in SQL querying as I am in coding, and as such I did not even consider this approach to the problem. 

Tom
Super User Tom
Super User

Looks like a simple self join will let you calculate that.

data have ;
  input x $ y :yymmdd. desired ;
  format y yymmdd10.;
cards;
a1154 2018-07-01 3
a1154 2018-06-22 2
a1154 2018-06-01 1
a1154 2018-05-25 0
a2266 2018-11-11 0
a2266 2017-01-01 0
a1997 2018-05-12 0
a2111 2016-05-18 1
a2111 2016-05-15 0
;
proc sql ;
create table want as
select a.*,count(b.y) as count
from have a
left join have b
on a.x=b.x 
and b.y between a.y-90 and a.y-1
group by a.x,a.y,a.desired
;
quit;
proc print;
run;
Obs      x               y    desired    count

 1     a1154    2018-05-25       0         0
 2     a1154    2018-06-01       1         1
 3     a1154    2018-06-22       2         2
 4     a1154    2018-07-01       3         3
 5     a1997    2018-05-12       0         0
 6     a2111    2016-05-15       0         0
 7     a2111    2016-05-18       1         1
 8     a2266    2017-01-01       0         0
 9     a2266    2018-11-11       0         0

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 979 views
  • 0 likes
  • 4 in conversation