/* Permuted Block Randomization Schedule
This randomization assumes an equal number of subjects per treatment arm.
Provide block sizes, number of treatment arms, and total sample size. Each block size should be a multiple of the number of treatment arms. For example, a block size of 3 with only 2 treatment arms is not allowed.
Block sizes >10 are not recommended due to processing time required. */ %let blocks=2 4 6 8; %let ngroups=2; %let samplesize=100;
/* Specify an integer value for seed if you want to be able to reproduce the schedule. Otherwise, let seed=0 */ %let seed = 0;
%macro m1 (); %global list;
%let list = ; %do j = 1 %to &blocksize/&ngroups; %do i = 0 %to &ngroups-1; %let list = &list &i; %end; %end; %mend m1;
%macro SelectBlockSize(); %global blocksize;
proc datasets; delete allblocks; run; quit;
%let counter=1; %let current=%scan(&blocks,&counter); %do %until (¤t=); data blocks; blocksize=1*¤t; rand=ranuni(&seed); output; run; proc append data=blocks base=allblocks; run;
%let counter=%eval(&counter+1); %let current=%scan(&blocks,&counter); %end;
proc sort data=allblocks; by rand; run; data _null_; set allblocks; blockcheck=mod(blocksize,&ngroups); if blockcheck ne 0 then call symputx ('blockcheck',blocksize); else %let blockcheck=''; call symputx ('blocksize',blocksize); run;
%if &blockcheck ne '' %then %do; %put ; %put ERROR: Invalid block size for number of groups.; %put ***********************************************; %put Block size = &blockcheck; %put Number of groups = &ngroups; %put ***********************************************; %put ; %abort; %end; %mend SelectBlockSize;
%macro m2 (); proc datasets; delete assignment; run;
%selectblocksize; %m1; %let n = &blocksize; %let stop=0;
%do %until (&stop=1); %if (&n>&samplesize) %then %let stop=1; data test; array x {&blocksize} (&list); nfact=fact(dim(x)); do i = 1 to nfact; seq=allperm(i, of x[*]); if &seed=0 then rand=ranuni(&seed); else rand=ranuni(1+&seed); output; end; run;
proc sort data=test; by rand; run; data test2 (keep = treat blocksize); set test (obs=1 keep=x1-x&blocksize); array x {&blocksize} x1-x&blocksize; do i = 1 to &blocksize; treat=x[i]; blocksize=1*&blocksize; output; end; run;
proc append base=assignment data=test2; run;
%selectblocksize; %m1; %let n = %eval(&n+&blocksize); %end;
data assignment; set assignment; PatientID+1; run;
proc print data=assignment noobs; var PatientID treat; where patientid<=&samplesize; run; %mend m2; %m2;
... View more