Statistical programming, matrix languages, and more

How to loop through different sample size conditions?

Reply
Contributor
Posts: 41

How to loop through different sample size conditions?

Hi all,

I have created a macro called Simulation that outputs a longitudinal dataset with repeated measures for each subject. One problem that I'm having is that I cannot figure out how to loop through different sample sizes. As of right now, the macro can take one sample size and output the dataset. However, what I want to do is give the macro several sample size conditions and have the macro loop through each one and create a dataset. Is this possible? The code is below:

%macro Simulation;

    proc iml;

        beta = &Beta.;

        Cov_Random_Effects = &CovRandom.;

        Cov_Errors = &CovError.;

        SampSize = &SampSize.;

        TimeVec = {0, 2, 4, 6};

        TimePoints = nrow(TimeVec);

        NumItemPer = &NumItemPer.;

        Mean_Errors = 0;

        Mean_Random_Effects = j(1, nrow(Cov_Random_Effects), 0);

       

        Random_Effects = shape(

                            repeat(

                                randnormal(

                                            SampSize*NumItemPer,

                                            Mean_Random_Effects,

                                            Cov_Random_Effects

                                               ),

                                    1,

                                    TimePoints

                                    ),

                                SampSize*TimePoints*NumItemPer,

                                nrow(Cov_Random_Effects)

                                );

        Random_Errors = randnormal(SampSize*NumItemPer*TimePoints, Mean_Errors, Cov_Errors);

        Intercept = J(SampSize*NumItemPer*TimePoints, 1, 1);

        Time = repeat(TimeVec,SampSize*NumItemPer, 1);

        XDesign = Intercept||Time;

        Response = XDesign*Beta + Intercept#Random_Effects[,1] + Time#Random_Effects[,2] + Random_Errors;

        Subject = repeat(colvec(repeat(T(1Smiley FrustratedampSize), 1, TimePoints)), NumItemPer, 1);

        Iter = repeat(colvec(repeat(T(1:NumItemPer), 1, SampSize*TimePoints)), 1, 1);

        Data = Subject||Response||Time||Iter;

        Cname = {"Subject" "Response" "Time" "Iter"};

        create SimulatedData

        from Data[c=Cname];

        append from Data;

        close SimulatedData;

    quit;

    proc mixed data = SimulatedData;

    by Iter;

    class Subject;

    ods output CovParms = cp SolutionF = fixed_effects;

    model Response = Time / s ddfm = &ddfm.;

    repeated / subject = Subject;

    random int Time / subject = subject type = &CovStructure.;

    run;

    proc means data = fixed_effects noprint;

    var Estimate StdErr;

    class Effect;

    output out = Means mean(Estimate StdErr) = MeanFE MeanSE;

     run;

%mend Simulation;

%let Beta = {16.7611, 0.6602};

%let CovRandom = {1.9211 0,

                   0 .0228};

%let CovError = 1.8787;

%let SampSize = 5;

%let NumItemPer = 50;

%let ddfm = KR;

%let CovStructure = vc;

%Simulation;

SAS Super FREQ
Posts: 3,420

Re: How to loop through different sample size conditions?

Your simulation is excellent! Very efficient. No loops. Well done!

You have two parameters that determine the sample size: the number of subjects and the number of time points for each subject.  Based on the names of your variables, it looks like you want to vary the number of subjects, which appears to be controlled by the SampSize macro variable.  Is that correct?

Are you trying to run a series of simulations to see how the number of subjects affects the results, maybe as part of a power and sample size study?

If you are doing a sample size study, I suggest that you add an iteration loop in the PROC IML step:

do SampSize = 5 to 40 by 5;

...

end;

and add an extra BY group variable to your PROC MIXED and PROC MEANS calls:

PROC MIXED;

by SampSize Iter;

...

run;

PROC MEANS;

by SampSize;

...

run.

Contributor
Posts: 41

Re: How to loop through different sample size conditions?

Hi Rick,

Thanks for the response and the compliment. Yes, I am running a sample size study and the SampSize macro variable controls the number of Level-2 subjects. One question I have is whether the "do SampSize = 5 to 40 by 5" step is before the proc iml step or within the proc iml step? Secondly, must I create a SampSize variable for my dataset? The log in SAS is telling me that there is no "SampSize" variable to group the analyses by. Also, it seems that when somewhere in the code, the condition for SampSize = 5 is created, then for SampSize = 10, but the SampSize = 10 condition is overwriting the SampSize = 5 dataset. Any ideas as to what is going on?

Thanks,

Tim

SAS Super FREQ
Posts: 3,420

Re: How to loop through different sample size conditions?

Inside the loop. You can use the DO statement to replace

SampSize = &SampSize.;

Put the END statement before the CLOSE statement.

Yes, you need to construct a vector that contains the sample size and append it to the DATA variable and add the variable name to CName.

Contributor
Posts: 41

Re: How to loop through different sample size conditions?

Hi Rick,

So I have modified the original code. I have appended the SampSize condition to the original dataset. The problem is, the code is still not looping through the different sample sizes. Could you look at the code below and see if there's still something I should be doing. Thanks!

%macro Simulation;

    proc iml;

        beta = &Beta.;

        Cov_Random_Effects = &CovRandom.;

        Cov_Errors = &CovError.;

        %do SampSize = 5 %to 10 %by 5;

        SampSize = &SampSize.;

        TimeVec = {0, 2, 4, 6};

        TimePoints = nrow(TimeVec);

        NumItemPer = &NumItemPer.;

        Mean_Errors = 0;

        Mean_Random_Effects = j(1, nrow(Cov_Random_Effects), 0);

       

        Random_Effects = shape(

                            repeat(

                                randnormal(

                                            SampSize*NumItemPer,

                                            Mean_Random_Effects,

                                            Cov_Random_Effects

                                               ),

                                    1,

                                    TimePoints

                                    ),

                                SampSize*TimePoints*NumItemPer,

                                nrow(Cov_Random_Effects)

                                );

        Random_Errors = randnormal(SampSize*NumItemPer*TimePoints, Mean_Errors, Cov_Errors);

        Intercept = J(SampSize*NumItemPer*TimePoints, 1, 1);

        Time = repeat(TimeVec,SampSize*NumItemPer, 1);

        XDesign = Intercept||Time;

        Response = XDesign*Beta + Intercept#Random_Effects[,1] + Time#Random_Effects[,2] + Random_Errors;

        Subject = repeat(colvec(repeat(T(1Smiley FrustratedampSize), 1, TimePoints)), NumItemPer, 1);

        Iter = repeat(colvec(repeat(T(1:NumItemPer), 1, SampSize*TimePoints)), 1, 1);

        SampSize = repeat(colvec(repeat(T(SampSize), 1, SampSize*TimePoints*NumItemPer)), 1, 1);

        Data = Subject||Response||Time||Iter||SampSize;

        Cname = {"Subject" "Response" "Time" "Iter" "SampSize"};

        create SimulatedData

        from Data[c=Cname];

        append from Data;

    %end;

        close SimulatedData;

    quit;

    proc mixed data = SimulatedData;

    by SampSize Iter;

    class Subject;

    ods output CovParms = cp SolutionF = fixed_effects;

    model Response = Time / s ddfm = &ddfm.;

    repeated / subject = Subject;

    random int Time / subject = subject type = &CovStructure.;

    run;

    proc means data = fixed_effects noprint;

    by SampSize;

    var Estimate StdErr;

    class Effect;

    output out = Means mean(Estimate StdErr) = MeanFE MeanSE;

     run;

%mend Simulation;

%let Beta = {16.7611, 0.6602};

%let CovRandom = {1.9211 0,

                   0 .0228};

%let SampSize = 10;

%let CovError = 1.8787;

%let NumItemPer = 50;

%let ddfm = KR;

%let CovStructure = vc;

%Simulation;

SAS Super FREQ
Posts: 3,420

Re: How to loop through different sample size conditions?

1) You do not need a macro %DO loop. An ordinary IML DO loop will suffice.

2) You need to move the CREATE statement outside the DO loop because you only want to create the data set one time, but append to it many times.

Here's the shell:

proc iml;
    beta = &Beta.;
    Cov_Random_Effects = &CovRandom.;
    Cov_Errors = &CovError.;

    Cname = {"Subject" "Response" "Time" "Iter" "SampSize"};
    Data = j(1, ncol(CName), .); /* specify that data are numerical vars */
    create SimulatedData from Data[c=Cname];
    do SampSize = 5 to 10 by 5;   /* for each sample size ... */
       /* ...simulate multiple samples for this sample size... */

       Size = SampSize + 0*Iter;
       Data = Subject||Response||Time||Iter||Size;
       append from Data;               /* ...and write this simulation to disk *.
   end;
close SimulatedData;
quit;

Ask a Question
Discussion stats
  • 5 replies
  • 423 views
  • 6 likes
  • 2 in conversation