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

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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