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

Hey everyone-

I'm racking my brain on this one. I'm trying to use a do loop combined with arrays and macro variables to build out a dataset.

Let's assume that I have a series of cat variables (cat_1-cat_23) and dog variables (dog_1-dog_23) in my dataset that I'm attempting to manipulate in an array. I want to write a loop where the array uses the cat variables the first time through, and the dog variables the second time.

Here's how I'm attempting to build the code. I realize you can simplify this whole thing by attempting not to loop things, but for the more complicated application I'm attempting to use this for, looping is necessary.

%let prefix1=cat;

%let prefix2=dog;

%macro catsndogs;

data rewrite;

     set my_data_set;

%do j=1 %to 2;

    array array1

  • &&prefix&j._1-&&prefix&j._23;
  •     array array2

  • total&j._1- total&j._23;
  •     do i=1 to 23;

        array2=array[1]-5;

        end;

    run;

    %end;

    %mend;

    %catsndogs;

       

    My instinct is that the first time through it would resolve things like this:

    &&prefix&j._1 = &prefix1._1 =  cat_1

    Instead, it resolves like this:

    &&prefix&j._1 = &prefix1_1 = This doesn't exist, so it bombs out.

    How can I rig the syntax so that the syntax resolves to array array1

  • cat_1-cat_23 the first time, and array1
  • dog_1-dog_23 the second time?
  • Thanks!

    1 ACCEPTED SOLUTION

    Accepted Solutions
    Astounding
    PROC Star

    You will have to modify your approach.  Even if you overcome this error, you will get a DATA step error.  The DATA step does not allow you to repeat the definition of the same array name.  Even these statements would generate an error if they appeared in the same DATA step:

    array array1 {23} cat_1 - cat_23;

    array array1 {23} cat_1 - cat_23;

    If you were to change the second statement to use dog instead of cat, it would still generate the error.  Array names cannot be defined more than once in the same DATA step.

    To answer your original question, you need to add another dot, for example:

    &&prefix&j.._1

    The first dot delimits &j, the second delimits &prefix1/&prefix2.

    View solution in original post

    5 REPLIES 5
    Astounding
    PROC Star

    You will have to modify your approach.  Even if you overcome this error, you will get a DATA step error.  The DATA step does not allow you to repeat the definition of the same array name.  Even these statements would generate an error if they appeared in the same DATA step:

    array array1 {23} cat_1 - cat_23;

    array array1 {23} cat_1 - cat_23;

    If you were to change the second statement to use dog instead of cat, it would still generate the error.  Array names cannot be defined more than once in the same DATA step.

    To answer your original question, you need to add another dot, for example:

    &&prefix&j.._1

    The first dot delimits &j, the second delimits &prefix1/&prefix2.

    keeks137
    Calcite | Level 5

    I think I just got it to work actually with the addition of the second period, so thanks much for that!!!

    I'll be back to post my full code as soon as I get a moment, to show you the more complicated version. I'll also make sure it's working as I would expect.

    Thanks again!

    keeks137
    Calcite | Level 5

    I eventually ended up creating multiple datasets within the loop, and then merged them together. Here's the code I used:

    %let groups=5;

    %let pre1=cta;

    %let qs1=23;

    %let pre2=ctb;

    %let qs2=18;

    %let pre3=ctc;

    %let qs3=4;

    %let pre4=cm2;

    %let qs4=24;

    %let pre5=cf5;

    %let qs5=13;

    %macro profile;

    %do j=1 %to &groups;

    data rewrite&j (keep=occasions &&pre&j.._1-&&pre&j.._&&qs&j t_&&pre&j.._1-t_&&pre&j.._&&qs&j);

       set step1;

       array array1

  • &&pre&j.._1-&&pre&j.._&&qs&j;
  •    array array2

  • t_&&pre&j.._1-t_&&pre&j.._&&qs&j;
  • do i=1 to &&qs&j;

       if array1 = 5 then array2=1;

    end;

    run;

    proc sort data=rewrite&j; by occasions; run;

    %end;

    %mend;

    %profile;

    data final_rewrite;

       merge rewrite1-rewrite&groups;

       by occasions;

    run;

    What the code does is it loops through 5 times and creates five datasets. Each new dataset creates a new array of variables. I used the %pre type variables to indicate what the prefix of the variable names are, and the %qs variables to indicate how many questions there were that used that prefix. So, the first time through, it manipulates cta_1-cta_23. After the loop is done, it merges all of the information together so that I have everything in a single dataset.

    Thanks to Astounding's advice, I got the macro variables to resolve properly, and after that it was just a matter of figuring out how I could include array statements in a loop, since you can't utilize something like "array1" twice.

    Thank you everyone!

    Reeza
    Super User

    Consider defining a two dimensional array instead of 1?

    Then use the j as the index for the second dimension?

    keeks137
    Calcite | Level 5

    I'll look into this tomorrow.

    Thanks for your help!

    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!

    What is Bayesian Analysis?

    Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

    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
    • 5 replies
    • 907 views
    • 3 likes
    • 3 in conversation