Search code examples
loopssasdo-loops

Nested Do Loops in SAS


I'm trying to figure out how to nest these loops so that I can generate some multilevel data. I keep getting an error, though. I'm really new to SAS so I'm struggling to figure out how to fix this. Thanks for any help!

%macro MLM;
data x;
call streaminit(525600);
do rep=1 to 1000;
 
    %do a=1 %to 4;
    %if &a=1 %then %do; %let N=100; %end;
    %if &a=2 %then %do; %let N=250; %end;
    %if &a=3 %then %do; %let N=500; %end;
    %if &a=4 %then %do; %let N=1000; %end;

        do J=1 to &N;
        u0= RAND('NORMAL',0,1);
        w1= RAND('BERNOULLI',.5);
         
            do I=1 to (10000/&N);
    
                %do b = 1 %to 5;
                %if &b=1 %then %do; %let e=RAND('NORMAL',0,1); %end;
                %if &b=2 %then %do; %let e=RAND('UNIFORM'); %end;
                %if &b=3 %then %do; %let e=RAND('CHISQUARE', &N-1); %end;
                %if &b=4 %then %do; %let e=RAND('LOGNORMAL'); %end;
                %if &b=5 %then %do; %let e=RAND('BETA',1,1); %end;

                x1= RAND('BERNOULLI',.5);
                b0 = 2.5+ 1*w1+u0;
                b1 = 0.15;
                y=b0+b1*x1+&e;
                output; 
                %end; 
            end;
        end; 
    %end;
end; 
%mend MLM; run; %MLM; run;
        

I want to run 1000 simulations, with 4 sample sizes (a, N), then generate N samples, during which I want to simulate 5 different error distributions. So, in the end, I should get 1000x4x5 total samples.

Thanks again!


Solution

  • Removing the macro logic and simplifying it slightly gets you this, which seems to work correctly to me. Note I simplified the N to ensure it runs quickly. Note that I'm not verify the logic, assuming that's correct on your side.

        data x;
            call streaminit(525600);
    
            do rep=1 to 5;
    
                do a=1 to 4;
    
                    if a=1 then
                        N=100;
                    else if a=2 then
                        N=250;
                    else if a=3 then
                        N=500;
                    else if a=4 then
                        N=1000;
    
                    do J=1 to N;
                        u0=RAND('NORMAL', 0, 1);
                        w1=RAND('BERNOULLI', .5);
    
                        do I=1 to (2000/N);
    
                            do b=1 to 5;
    
                                if b=1 then
                                    e=RAND('NORMAL', 0, 1);
                                else if b=2 then
                                    e=RAND('UNIFORM');
                                else if b=3 then
                                    e=RAND('CHISQUARE', N-1);
                                else if b=4 then
                                    e=RAND('LOGNORMAL');
                                else if b=5 then
                                    e=RAND('BETA', 1, 1);
                                    
                                    
                                x1=RAND('BERNOULLI', .5);
                                b0=2.5+ 1*w1+u0;
                                b1=0.15;
                                y=b0+b1*x1+e;
                                output;
                            end;
                        end;
                    end;
                end;
            end;
        run;