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

Trying to recode the following into more condensed code

sickday1=S30Q4_30d_1+S30Q5_30d_1+S30Q6_30d_1+S30Q7_30d_1; sickday2=S30Q4_30d_2+S30Q5_30d_2+S30Q6_30d_2+S30Q7_30d_2; sickday3=S30Q4_30d_3+S30Q5_30d_3+S30Q6_30d_3+S30Q7_30d_3;

this format continues until sickday30.

I was able to do so the following with the following in a data statement:

%macro sick (i); sicksday&i. = S30Q4_30d_&i.+S30Q5_30d_&i.+S30Q6_30d_&i.+S30Q7_30d_&i.; %mend; %array(num, values = %numlist(1-30)); %do_over(num, macro=sick);

or with the following code

array sickday {30}; array S30Q4_30d{} S30Q4_30d_1 -- S30Q4_30d_30; array S30Q5_30d{} S30Q5_30d_1--S30Q5_30d_30; array S30Q6_30d{} S30Q6_30d_1--S30Q6_30d_30; array S30Q7_30d{} S30Q7_30d_1--S30Q7_30d_30; do i = 1 to 30; drinksday{i} = S30Q4_30d[i]+S30Q5_30d[i]+S30Q6_30d[i]+S30Q7_30d[i]; end;

 

However my problem arises in that I actually need sickday1- sickday60, but the variables sickday31 to sickday60 are coded as follows: sickday31=S30Q4_60d_1+S30Q5_60d_1+S30Q6_60d_1+S30Q7_60d_1; sickday32=S30Q4_60d_2+S30Q5_60d_2+S30Q6_60d_2+S30Q7_60d_2; etc. where the numbering of the newly created variable no longer matches the endings of the variables used to calculate it. I also think my code to create the first 30 variables could be somewhat improved. I've tried a few ways to do this but nothing is working properly. 

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

How about a technique of listing all the vars in one long array, then looping through the array by appropriate step sizes?

 

Consider;

 

  array sq {*}  s30q4_30d_1-s30q4_30d_30   s30q4_60d_1-S30q4_60d_30

                      s30q5_30d_1-s30q5_30d_30   s30q5_60d_1-S30q5_60d_30

                      s30q6_30d_1-s30q6_30d_30   s30q6_60d_1-S30q6_60d_30

                      s30q7_30d_1-s30q7_30d_30   s30q7_60d_1-S30q7_60d_30;   /* 4 lists of 60 vars each */

 

   /* Now get 60 sums */

  array sickdays {60} (60*0);

  do S=1 to 60;

     do J=S to dim(sq) by 60;

        sickdays{s}=sickdays{s}+sq{j};

     end;

  end;

 

You could also make array SQ into a 2-dimensional array {60*4}  then sum each column over its 4 rows, then all loops would increment by 1 as in:

 

  do s=1 to 60;

    do r=1 to 4;  sickdays{s}=sickdays{s}+sq{s,r}; end;

  end;

 

Compact code.  No macro needed.

 

Regards,

Mark

--------------------------
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

--------------------------

View solution in original post

6 REPLIES 6
rs84
Calcite | Level 5

I got it to work using the following code but would really like if someone can help with something simpler, perhaps only using arrays without using the %do_over and %array macros.

 

%macro sick (i);
sick day&i. = S30Q4_30d_&i.+S30Q5_30d_&i.+S30Q6_30d_&i.+S30Q7_30d_&i.;
%mend;
%array(num, values = %numlist(1-30));
%do_over(num, macro= sick);
%macro sick 2 (j, k);
sickday&j. = S30Q4_60d_&k.+S30Q5_60d_&k.+S30Q6_60d_&k.+S30Q7_60d_&k.;
%mend;
%array(num2, values = %numlist(31-60));
%array(num3, values = %numlist(1-30));
%do_over(num2 num3, macro= sick2);

Reeza
Super User

To be honest, not being able to read your code isn't helping your question at all.

 

Rather than dealing with all 30 vars and how many every summaries, can you simplify your problem to maybe 5 and the corresponding sums?Adding some sample data to test with would be helpful as well.

 

I'm 99% certain you can do this with arrays.

mkeintz
PROC Star

How about a technique of listing all the vars in one long array, then looping through the array by appropriate step sizes?

 

Consider;

 

  array sq {*}  s30q4_30d_1-s30q4_30d_30   s30q4_60d_1-S30q4_60d_30

                      s30q5_30d_1-s30q5_30d_30   s30q5_60d_1-S30q5_60d_30

                      s30q6_30d_1-s30q6_30d_30   s30q6_60d_1-S30q6_60d_30

                      s30q7_30d_1-s30q7_30d_30   s30q7_60d_1-S30q7_60d_30;   /* 4 lists of 60 vars each */

 

   /* Now get 60 sums */

  array sickdays {60} (60*0);

  do S=1 to 60;

     do J=S to dim(sq) by 60;

        sickdays{s}=sickdays{s}+sq{j};

     end;

  end;

 

You could also make array SQ into a 2-dimensional array {60*4}  then sum each column over its 4 rows, then all loops would increment by 1 as in:

 

  do s=1 to 60;

    do r=1 to 4;  sickdays{s}=sickdays{s}+sq{s,r}; end;

  end;

 

Compact code.  No macro needed.

 

Regards,

Mark

--------------------------
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

--------------------------
Reeza
Super User

@mkeintz small typo in the variable names - second and fourth set starts with 30 rather than S30?

mkeintz
PROC Star

@Reeza

 

thank you. now corrected.

--------------------------
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

--------------------------
rs84
Calcite | Level 5

Thank you, was very helpful. I was stuck thinking about the problem in a certain way and your solution is simple but just what I needed.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1159 views
  • 1 like
  • 3 in conversation