DATA Step, Macro, Functions and more

Whut an I not getting?

Reply
Frequent Contributor
Posts: 126

Whut an I not getting?

In the code below, it seems to me that the first argument in the second IF statement (if valid_ct ge 1) will never be true and so it will never be processed. And yet it seems that it is being processed. Can someone explain why?

 

DATA c (drop=encdate dob);

    set b;

    by edipn encdate2;

   retain valid_ct;

      Days = encdate2 - dob2;

   dose+1;

   if first.edipn then

     do; dose=1; valid_ct=0;

     end;

   valid=0;

 

   if valid_ct ge 1 and ( encdate2 - lag1(encdate2)) ge 24 then

     do; valid=1; valid_ct = valid_ct+1;

     end;

  else

  if ( dose=1 or valid_ct=0 ) and (encdate2 - dob2 ) ge 360 then

    do; valid=1; valid_ct = valid_ct+1 ;

    end;

Super User
Posts: 10,550

Re: Whut an I not getting?

What leads you to believe the test will never be true?

The variable valid_ct has the RETAINED across iterations of the data step. So if the second part of that comparison is true enough times within each value of EDIPN then valid_ct gets set to 2.

 

If EDIPN isn't repeated at least 3 times I can see valid_ct not exceeding 1.

Frequent Contributor
Posts: 126

Re: Whut an I not getting?

Thanks for the reply!

 

I guess I don't understand what' going on with the Retain and first.edipn

 

I was thinking that if first.edipn is true then valid_ct gets set to 0 else it is empty. What does valid_ct get set to when first.edipn is false?

Super User
Posts: 10,550

Re: Whut an I not getting?

RETAIN is used to retain the value of variables when reading new records from a data set. Note: if you use a variable in the data set you'll like not see the results you expect.

 

FIRST and LAST a special predicates that look at the variables by sort order. If the data isn't sorted by those variables you'll get an error unless you use NOTSORTED (be very careful with this).  If First.edipn instructs SAS to do the the following operations for each the first of the edipn values occurring. Note the DO END construct assigns initial values to two variables.

If the record is not the first one for that edipn, then the program goes to the next instruction. You can use FIRST. and LAST. for any of the variables on the BY statement.

 

If you have something you want done only on the last value of edipn you could use If last.edipn then do; <something>; If there is only one record for a value of edipn then it is both first and last.

 

Note that the LAG1(encdate2) will be pointing to the value of the previous edipn for each First.edipn value except the first record where it is missing. So you might look into that bit of logic (and not(first.edipn) perhaps).

 

The DOSE + 1; line has an Implied RETAIN so that it counts each record within the edipn.

 

Super User
Posts: 5,260

Re: Whut an I not getting?

As @ballardw stated, it will primarily retain it's value from previous iterations. It get augmented by 1 if any of the other if statements are true.
If you are using DMS SAS you try using the data step debugger to understand how your data step executes and how values are assigned.
If not, insert put statements to track the executions in the log.
Data never sleeps
Ask a Question
Discussion stats
  • 4 replies
  • 181 views
  • 0 likes
  • 3 in conversation