BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
CorinneT
Obsidian | Level 7

Hi,

Could someone help me, please? I lack method and practice.

I'd like to use an iterative loop with the row of data that

1)I repeat 12 times, I have the program below:

 * Total number of infusions;

    if TT1  ne . then TT1_adm = 1 ; else TT1_adm = 0 ;

    …….

    if TT12  ne . then TT12_adm = 1 ; else TT12_adm = 0 ;

 

I done, but it not works:

%let i=1;

do i=1 to 12;

                if TT&i  ne . then TT&i _adm = 1 ;

                  else TT&i _adm = 0 ;

            nb_tot_adm= sum (of TT&i _adm) ;

           sum_TTX = sum(of TT&i ) ;

end;

2) if I would like, to repeat n times, the same program above, please. How could I go?

 

Thx, in advance for all your answers  

  

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Technically, you can do this using macros similar to the way you began.  However, it is not recommended for inexperienced programmers.  You are likely to make many mistakes and syntax errors along the way, enough to discourage you from wanting to use this approach.  For the record, though, here is what it might look like:

 

%macro loop (n=);
   %local i;
   nb_tot_adm = 0;
   sum_TTX = 0;
   %do i=1 to &n;
      iif TT&i ne . then TT&i._adm = 1;
      else TT&i._adm=0;
      nb_tot_adm + TT&i._adm;
      sum_TTX + TT&i;
   %end;
data want;
set have;
%loop (n=12)
run;

You can change the value for N when you call the macro, choosing whatever is appropriate for your current data set.  Also, you don't necessarily have to create 12 sets of variables.  One set would do, since you can accumulate their values inside the loop. instead of waiting to create them all first.

 

Finally, from  your origianl post it's not 100% clear that you have 12 variables to begin with.  Perhaps you actually have 1 variable with 12 observations.  The programming would be very different in that case, and very easy.

View solution in original post

6 REPLIES 6
mkeintz
PROC Star

You are trying to make a loop using macros when you should be using arrays:

 

  array tt {12} ;
  array adm {12} tt1_adm tt2_adm tt3_adm tt4_adm  tt5_adm  tt6_adm
                 tt7_adm tt8_adm tt9_adm tt10_adm tt11_adm tt12_adm;

  do i=1 to 12;
   if tt{i} ne . then adm{i}=1;
   else adm{i}=0;
  end;
  nb_tot_adm=sum(of adm{*});
  sum_TTX = sum(of TT{*}) ;

This first array statement has no specific variables names assigned to the 12 elements of TT, so it assumes TT1, TT2,... TT12.  It just appends a 1, then a 2, etc. to the root "tt".

 

But that technique can't be used when you need 12 variables named TT1_ADM, TT2_ADM, ... TT12_ADM.   If you don't insist on those particular names, then I suggest making the second array declaration simple, as in:

  array adm {12} TTADM1-TTADM12;

which will generate names TTADM1, TTADM2, ... TTADM12.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
CorinneT
Obsidian | Level 7

Thank you so much for your fast response.

 

But if I whant to repeat more than 12 times for exemple n times. I could replace n when I would like by 12 or 20 for example. So, the method with an array doesn't work, when you do know the dimension of array? 

I have you got another way, please? I I would like generalize to n times

Tom
Super User Tom
Super User

@CorinneT wrote:

Thank you so much for your fast response.

 

But if I whant to repeat more than 12 times for exemple n times. I could replace n when I would like by 12 or 20 for example. So, the method with an array doesn't work, when you do know the dimension of array? 

I have you got another way, please? I I would like generalize to n times


I don't understand what you are saying.

 

But to answer the question.  You KNOW the dimension of an ARRAY before you write the CODE.  For the ARRAY statement to work you need to either specify the dimension.

array xx [10];

Or list all of the variables.

array xx xx1-xx10;

If you can explain what you are trying to do then perhaps we can help you write some code.

So far we appear to have an XY problem.

ballardw
Super User

@CorinneT wrote:

Thank you so much for your fast response.

 

But if I whant to repeat more than 12 times for exemple n times. I could replace n when I would like by 12 or 20 for example. So, the method with an array doesn't work, when you do know the dimension of array? 

I have you got another way, please? I I would like generalize to n times


First provide an example input data set an what you expect for the output.

Your statements in your attempt can be taken to mean several different things are attempted and you need to clarify them. They need clarification because you overwrite the summed values with each iteration and the space between TT&i and the _adm is just plain incorrect syntax and including both of them inside an iteration raises questions about just exactly what sum value you want for the two variables.

nb_tot_adm= sum (of TT&i _adm) ;
 sum_TTX = sum(of TT&i ) ;

If you have any sort of Identification variable, or combination that uniquely identifies the record this will work to build the tt01_adm variables poor of a choice as that is and doesn't require knowing anything about how many TT variables there were. Still need clarification of the totals.

%let n=25;
/* create an example data set*/
data junk;
   array t {*} tt1-tt&n;
   do id= 1 to 10;
      do i=1 to dim(t);
        t[i]=rand('integer',2)-1;
      end;
      output;
   end;
run;
/* given any input data set with some sort of ID
   and those variables
*/
data reshaped;
   set junk;
   by id;
   array t(*) tt: ;
   do i= 1 to dim(t);
      val=t[i];
      vn =vname(t[i]);
      idvar=vn;
      output;
      val=(t[i] ne .);
      idvar=catt(vn,'_adm');
      output;
   end;
   drop  tt: ;
run;

proc transpose data=reshaped out=trans(drop=_name_);
   by id;
   var val;
   id idvar;
run;

better for building the adm variables would be

data reshaped;
   set junk;
   by id;
   array t(*) tt: ;
   do i= 1 to dim(t);
      val=t[i];
      vn =vname(t[i]);
      idvar=vn;
      output;
      val=(t[i] ne .);
      idvar=catt('adm_',vn);
      /* or 
      idvar=catt('tt_adm',i);
      */
      output;
   end;
   drop  tt: ;
run;

It may be that another pass through the data using

sum(of tt: )

sum(of adm_tt: )

 

If you are intending to do some sort of diaganol sum of tt1, tt1-tt2, tt1-tt3, tt1-tt4 , ..., tt1-ttN then that needs a better description (and can be done in the Reshaped data step)

 

CorinneT
Obsidian | Level 7

Thanks. It's what I'm pending. I will run it tomorrow.

Astounding
PROC Star

Technically, you can do this using macros similar to the way you began.  However, it is not recommended for inexperienced programmers.  You are likely to make many mistakes and syntax errors along the way, enough to discourage you from wanting to use this approach.  For the record, though, here is what it might look like:

 

%macro loop (n=);
   %local i;
   nb_tot_adm = 0;
   sum_TTX = 0;
   %do i=1 to &n;
      iif TT&i ne . then TT&i._adm = 1;
      else TT&i._adm=0;
      nb_tot_adm + TT&i._adm;
      sum_TTX + TT&i;
   %end;
data want;
set have;
%loop (n=12)
run;

You can change the value for N when you call the macro, choosing whatever is appropriate for your current data set.  Also, you don't necessarily have to create 12 sets of variables.  One set would do, since you can accumulate their values inside the loop. instead of waiting to create them all first.

 

Finally, from  your origianl post it's not 100% clear that you have 12 variables to begin with.  Perhaps you actually have 1 variable with 12 observations.  The programming would be very different in that case, and very easy.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 6 replies
  • 935 views
  • 1 like
  • 5 in conversation