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

Hi -

 

I want to write a code nested if then do end within the %do and %end macro, not sure how to make it work, right now my code looks like this:

%macro change;
%local n;
data want;
   set data;
   %do n = 0 %to 23;
   if start_hour = &n. then do
   inter&n = 60 - minute(start_time);
   inter&n+1 = minute(stop_time);
   end;
   %end;
   ;
run;
%mend change;
%change;

The results that I want is to get the inter0 = 60-minute(start_time); inter1 = minute(stop_time); and same goes with inter1, inter2  etc.

 

My solution now is to write each one separately in each macro, like this: (but this does not seem to be very efficient)

%macro change;
%local n;
data want;
   set one;
   %do n = 0 %to 23;
   if start_hour = &n. then do
   inter&n. = 60 - minute(start_time);
   end;
   %end;
   ;
run;
%mend change;
%change;

%macro change;
%local n;
data one_inter;
   set one_inter;
   %do n = 0 %to 23;
   if stop_hour = &n. then do
   inter&n. = minute(stop_time);
   end;
   %end;
   ;
 run;
 %mend change;
 %change;

Do anyone has any idea?

 

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You need to post some example data so we can understand what you are actually trying to do.

Your first macro is not going to generate SAS to do what you want.

In particular this line:

inter&n+1 = minute(stop_time);

Will generate code like:

inter0 +   1 = minute(stop_time);

Which is basically going to setup INTER0 as a count of the number of times that STOP_TIME has a value where the minute number is equal to 1.

 

Perhaps you meant to write:

inter&n = 60 - minute(start_time);
inter%eval(&n+1) = minute(stop_time);

But the problem with that is that then the result of your %DO would be to generate assignment statements that look like they might overwrite each other.

inter0 = 60 - minute(start_time);
inter1 = minute(stop_time);
inter1 = 60 - minute(start_time);
inter2 = minute(stop_time);

But I think the end result of this fixed macro code would really be the same thing you would get if you just used a program like this without any macro code.

data want;
  set have;
  array inter (0:24) inter0-inter24 ;
  if 0<= start_hour <= 23 then do;
    inter(int(start_hour))=60 - minute(start_time);
    inter(int(start_hour)+1)=minute(stop_time);
  end;
run;

Which is going to generate a strange set of mainly missing variables like:

         s           s
         t      s    t
         a      t    a
         r      o    r                                    i  i  i  i  i  i  i  i  i  i  i  i  i  i  i
         t      p    t   i   i   i   i  i  i  i  i  i  i  n  n  n  n  n  n  n  n  n  n  n  n  n  n  n
         _      _    _   n   n   n   n  n  n  n  n  n  n  t  t  t  t  t  t  t  t  t  t  t  t  t  t  t
         t      t    h   t   t   t   t  t  t  t  t  t  t  e  e  e  e  e  e  e  e  e  e  e  e  e  e  e
 O       i      i    o   e   e   e   e  e  e  e  e  e  e  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
 b  i    m      m    u   r   r   r   r  r  r  r  r  r  r  1  1  1  1  1  1  1  1  1  1  2  2  2  2  2
 s  d    e      e    r   0   1   2   3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4

 1  1   0:30   0:40  0  30  40   .   .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
 2  2   2:22   5:55  2   .   .  38  55  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

 

View solution in original post

3 REPLIES 3
Reeza
Super User

In a data step why not use a regular DO/THEN/END loop?

panda
Quartz | Level 8

Thar makes sense. I figure out a way to solve my problem just now, it works but maybe regular do end also work:

%macro change;
%local n;
data two_inter;
   set two;
   %do n = 0 %to 23;
   %let m = %eval(&n+1);
   if start_hour = &n. then do
   inter&n = 60 - minute(start_time);
   inter&m = minute(stop_time);
   end;
   %end;
   ;
run;
%mend change;
%change;
Tom
Super User Tom
Super User

You need to post some example data so we can understand what you are actually trying to do.

Your first macro is not going to generate SAS to do what you want.

In particular this line:

inter&n+1 = minute(stop_time);

Will generate code like:

inter0 +   1 = minute(stop_time);

Which is basically going to setup INTER0 as a count of the number of times that STOP_TIME has a value where the minute number is equal to 1.

 

Perhaps you meant to write:

inter&n = 60 - minute(start_time);
inter%eval(&n+1) = minute(stop_time);

But the problem with that is that then the result of your %DO would be to generate assignment statements that look like they might overwrite each other.

inter0 = 60 - minute(start_time);
inter1 = minute(stop_time);
inter1 = 60 - minute(start_time);
inter2 = minute(stop_time);

But I think the end result of this fixed macro code would really be the same thing you would get if you just used a program like this without any macro code.

data want;
  set have;
  array inter (0:24) inter0-inter24 ;
  if 0<= start_hour <= 23 then do;
    inter(int(start_hour))=60 - minute(start_time);
    inter(int(start_hour)+1)=minute(stop_time);
  end;
run;

Which is going to generate a strange set of mainly missing variables like:

         s           s
         t      s    t
         a      t    a
         r      o    r                                    i  i  i  i  i  i  i  i  i  i  i  i  i  i  i
         t      p    t   i   i   i   i  i  i  i  i  i  i  n  n  n  n  n  n  n  n  n  n  n  n  n  n  n
         _      _    _   n   n   n   n  n  n  n  n  n  n  t  t  t  t  t  t  t  t  t  t  t  t  t  t  t
         t      t    h   t   t   t   t  t  t  t  t  t  t  e  e  e  e  e  e  e  e  e  e  e  e  e  e  e
 O       i      i    o   e   e   e   e  e  e  e  e  e  e  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
 b  i    m      m    u   r   r   r   r  r  r  r  r  r  r  1  1  1  1  1  1  1  1  1  1  2  2  2  2  2
 s  d    e      e    r   0   1   2   3  4  5  6  7  8  9  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4

 1  1   0:30   0:40  0  30  40   .   .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
 2  2   2:22   5:55  2   .   .  38  55  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

 

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
  • 3 replies
  • 486 views
  • 2 likes
  • 3 in conversation