BookmarkSubscribeRSS Feed
eric2
Calcite | Level 5

data a;
input subject $ visit $ labdt $ cd1 $ cd2 $ cd3 $ cd4 $;
cards;
101 1 15JUN15 17JUN15 18JUN15 29JUN15 31AUG15
101 2 20JUN15 17JUN15 18JUN15 29JUN15 31AUG15
101 3 01AUG15 17JUN15 18JUN15 29JUN15 31AUG15
102 1 19JUN15 17JUN15 28JUN15 29JUN15 31SEP15
102 1 28JUN15 17JUN15 28JUN15 29JUN15 31SEP15
;
run;

data b;
set a;
by subject visit;
array vis[*] cd1-cd4;
do i = 1 to dim(vis);

if input(labdt,date9.) le input(vis[i],date9.) then chk=vlabel(vis[i]);
else if input(labdt,date9.) < input(vis[i],date9.) and input(labdt,date9.) ge input((vis[i+1]),date9.)
then chk=vlabel(vis[i+1]);
end;

run;

 

why isnt chk assgined properly. basically i want to check if labdt falls between which cdx variables?

 

thk

7 REPLIES 7
Reeza
Super User

You should consider a binary search method instead of looping through the entire array as well...though it's likely the easiest approach.

 

You don't have a LEAVE, which you should, once your condition is met, otherwise, it will check each i regardless.

 

 

 

 

eric2
Calcite | Level 5

thx LEAVE worked ..

 

thx again

Astounding
PROC Star

If that's all you did, you will get error messages on some days, and not on other days.  It depends on what is in the data.  If you get as far as I=4, then what do you think will happen when your code references vis[I+1] ??

ballardw
Super User

Do you get the same invalid data notes that I do when I run your code? 31SEP15 is not a valid date.

 

Is there any reason the dates weren't created as date values with the appropriate informat when created? I find that having actual date values usually simplifies code a lot.

 

You might show what your are expecting to get for a result.

I think that you may have the direction of your comparisons backwards in the ELSE if, your loop is going to attempt to execute one too many times for most cases. If you want to stop as soon as you find the boundary value/variable the below shows an example.

data a;
input subject $ visit $ labdt $ cd1 $ cd2 $ cd3 $ cd4 $;
cards;
101 1 15JUN15 17JUN15 18JUN15 29JUN15 31AUG15
101 2 20JUN15 17JUN15 18JUN15 29JUN15 31AUG15
101 3 01AUG15 17JUN15 18JUN15 29JUN15 31AUG15
102 1 19JUN15 17JUN15 28JUN15 29JUN15 30SEP15
102 1 28JUN15 17JUN15 28JUN15 29JUN15 30SEP15
;
run;

data b;
   set a;
   by subject visit;
   array vis[*] cd1-cd4;
   do i = 1 to (dim(vis) -1);

      if input(labdt,date7.) le input(vis[i],date7.) then do; 
         chk=vlabel(vis[i]);
         leave;
      end;
      else if input(labdt,date7.) ge input(vis[i],date7.) and input(labdt,date7.) le input((vis[i+1]),date7.)
      then do;
         chk=vlabel(vis[i+1]);
         leave;
      end;
   end;

run;

 This assumes that the cd1 to cd4 are sorted in ascending order.  

eric2
Calcite | Level 5

i could have used full dates instead of date7.   i believe the date will fall under one category only so do you think backward will produce different result than the current one?

ballardw
Super User

@eric2 wrote:

i could have used full dates instead of date7.   i believe the date will fall under one category only so do you think backward will produce different result than the current one?


If I understand your question, likely the choice of date7 vs date9 shouldn't matter. I just try  to match the informat to actual range of characters/digits I have as there are some times that a longer informat than the value may cause problems.

 

If the original dates had been read using date7 informat then the comparison code would be much cleaner and easier to follow.

Plus if you need to do anything else, such as the difference between the test date and the boundary date you would have to convert the values again to use intck function.

PGStats
Opal | Level 21

If CD1 <= CD2 <= CD3 <= CD4 then you must stop the loop as soon as labdt <= CDi

 

data b;
set a;
array vis[*] cd1-cd4;
do i = 1 to dim(vis);

    if input(labdt,date9.) le input(vis[i],date9.) then do;
        chk=vlabel(vis[i]);
        leave;
        end;
    end;

run;

 

 

PG

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 7 replies
  • 746 views
  • 0 likes
  • 5 in conversation