Thanks, Rick. Your careful reading of the post is greatly appreciated, and your remarks were right on target. Below is the syntax that does exactly what I had intended. I added some additional comments and tried to pretty up the syntax a bit. Happy holidays! Keenan /***************************************************** Simulating Two-Group Multivariate Data For Two Conditions Using Parameter Values Residing in Data Set ******************************************************/ /* Inputting study conditions in "parent" data set Cormat; Each line contains values used for simulation study*/ DATA Cormat; INPUT Var1 Covar1 Covar2 Var2 Meanres1 Meanres2 N NumSamples Cond Esy1 Esy2; DATALINES /* 2 conditions now included with N differing across conditions */; 1 .5 .5 1 0 0 50 10 1 .5 .5 1 .5 .5 1 0 0 30 10 2 .5 .5 ; /* Macro to SCAN through cormat data file Will read each line of data sequentially from cormat data file*/ %MACRO SCANLOOP(Cormat,Field1,Field2,Field3,Field4,Field5,Field6,Field7,Field8,Field9,Field10,Field11); /* First provide the number of records in cormat */ DATA _NULL_; IF 0 THEN SET &cormat NOBS=X; CALL SYMPUT('RECCOUNT',X); STOP; RUN; /* Loop from one to number of records */ %DO I=1 %TO &RECCOUNT; /* Advance to the Ith record */ DATA _NULL_; SET &Cormat (FIRSTOBS=&I OBS=&I); /* Store the variables of interest in macro variables */ CALL SYMPUT('Var1',&Field1); CALL SYMPUT('Covar1',&Field2); CALL SYMPUT('Covar2',&Field3); CALL SYMPUT('Var2',&Field4); CALL SYMPUT('Meanres1',&Field5); CALL SYMPUT('Meanres2',&Field6); CALL SYMPUT('N',&Field7); CALL SYMPUT('NumSamples',&Field8); CALL SYMPUT('Cond',&Field9); CALL SYMPUT('ESY1',&Field10); CALL SYMPUT('ESY2',&Field11); STOP; RUN; /* Creates data set with 2 groups with Group size = N/2 and reps = Numsamples, retains study parameters; */ /* Does this for each study condition */ DATA Group; Cond=&Cond; DO Reps = 1 to &Numsamples; DO ID = 1 to &N; IF ID le &N/2 then T = 0; ELSE T=1; OUTPUT; END; END; RUN; DATA Group; SET Group; IF T = 1 THEN DO; PredY1 = &Esy1; PredY2 = &Esy2; END; ELSE IF T = 0 THEN DO; PredY1 = 0; PredY2 = 0; END; OUTPUT; RUN; /* Proc datasets appends Group data sets from each study condition */ PROC DATASETS; APPEND BASE=AllGroup DATA=Group; RUN; QUIT; /* Obtaining residuals from multivariate normal distribution using values from cormat */ PROC IML; Cond = &Cond; USE Cormat; READ POINT &I VAR {Var1 Covar1 Covar2 Var2} INTO Vector; Cov = SHAPE (vector, 2, 2); CLOSE Cormat; USE Cormat; READ POINT &I VAR {Meanres1 Meanres2} INTO mean; CLOSE Cormat; USE Cormat; READ POINT &I VAR {N} INTO N; READ POINT &I VAR {Numsamples} INTO Numsamples; READ POINT &I VAR {Cond} INTO Cond; CLOSE Cormat; Newcond = REPEAT ({&Cond},N*Numsamples); R = RANDNORMAL(N*Numsamples, Mean, Cov); Reps = COLVEC(repeat(T(1:Numsamples), 1, N)); /* 1,1,1,...,2,2,2,...,3,3,3,... */ Z = Reps || R || Newcond; CREATE MVN FROM Z[c={"Reps" "R1" "R2" "Cond"}]; APPEND FROM Z; CLOSE MVN; QUIT; /* Proc datasets appends MVN data sets from each study condition */ PROC DATASETS; APPEND BASE=Allmvn DATA=mvn; RUN; QUIT; %END; %MEND SCANLOOP; /* Call SCANLOOP macro */ %SCANLOOP(Cormat,Var1,Covar1,Covar2,Var2,Meanres1,Meanres2,N,NumSamples,Cond,Esy1,Esy2); RUN; /* Merging fixed data set with residuals data set */ /* Creating Observed Y scores as predicted plus residual */ /* ALLDATA contains simulated data for all study conditions */ Data ALLDATA; merge Allgroup Allmvn; Y1 = PredY1 + R1; Y2 = PredY2 + R2; RUN;
... View more