turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

Topic Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

07-26-2015 03:00 AM

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(1ampSize), 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;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to tbanh

07-26-2015 07:05 AM

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.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Rick_SAS

07-26-2015 05:40 PM

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

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to tbanh

07-26-2015 06:34 PM

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.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Rick_SAS

07-28-2015 05:37 PM

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(1ampSize), 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;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to tbanh

07-29-2015 08:55 AM

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;