Just to conclude, thanks to @FreelanceReinh ,
this is a working version from a to z:
data exampleData;
infile cards ;
input i j xij nj;
cards;
1 1 0 3
1 2 2 3
1 3 3 3
1 4 1 1
1 5 2 3
1 6 4 4
1 7 3 3
1 8 2 2
1 9 2 2
1 10 1 1
1 11 2 3
1 12 2 2
1 13 3 3
1 14 2 2
1 15 0 2
1 16 2 3
1 17 2 3
1 18 2 3
1 19 2 2
1 20 1 1
1 21 2 2
2 1 2 3
2 2 3 3
2 3 3 3
2 4 1 1
2 5 3 3
2 6 4 4
2 7 3 3
2 8 2 2
2 9 1 2
2 10 1 1
2 11 2 3
2 12 2 2
2 13 3 3
2 14 2 2
2 15 2 2
2 16 2 3
2 17 2 3
2 18 3 3
2 19 2 2
2 20 1 1
2 21 2 2
;;;;
run;
/* infil=input datafile -
should contain i, j, xij, and nj(NOTE: Path to file should be enclosed in single quotes.)
num_c=number of clusters(patients) */
%macro clustpro (infil=, num_c=);
/* Dataset created from data file */
data tmp;
set &infil.;
run;
/* number of tests initialized to 2 */
%let num_t=2;
/* Input data set sorted by i */
proc sort data=tmp;
by i;
run;
/* Length of num_t and num_c computed (used later in formatting upper loop values */
%let lent=%length(&num_t);
%let lenc=%length(&num_c);
/* "." added to end of lengths (for formatting purposes) */
data _null_;
call symput('fort', &lent||'.');
call symput('forc', &lenc||'.');
run;
/* xij, nj put into macro variables and trimmed */
data _null_;
set tmp;
call symput ('x'||left(put(i, &fort))||left(put(j, &forc)), xij);
call symput ('n'||left(put(j, &forc)), nj);
run;
%do k=1 %to &num_c;
%let n&k=%eval(&&n&k);
%do l=1 %to &num_t;
%let x&l&k=%eval(&&x&l&k);
%end;
%end;
/* sums of xij and nj computed */
proc means data=tmp noprint;
by i;
var xij nj;
output out=a sum=sumx sumn;
run;
/* sum of njs put into macro variable (used later) */
data _null_;
set a;
call symput ('sumn', sumn);
run;
/* &sum=sum of p_hats. Will change with each iteration of loop. */
%let sum=0;
/* p_hat1, p_hat2 computed, put into macro variables */
%do k=1 %to &num_t;
data b&k;
set a;
if i=&k;
p_hat&k=sumx/sumn;
run;
data _null_;
set b&k;
tmp=&k;
call symput('p_hat'||left(put(tmp, 1.)), p_hat&k);
run;
%let sum=%sysevalf(&sum+&&p_hat&k);
%end;
/* p bar computed */
%let p_bar=%sysevalf (&sum/&num_t);
/* part1=j/(j-1) (Used in computing the matrix S) */
%let part1=%sysevalf (&num_c*(1/(&num_c-1)));
/* part3=(sum of njs)^2 (Used in computing the matrix S) */
%let part3=%eval (&sumn*&sumn);
/* Part 2 computed */
/* Each iteration of part 2 initialized to 0 */
%do l=1 %to &num_t;
%do m=1 %to &num_t;
%let tcmp&l&m=0;
%end;
%end;
/* l represents i, m represents i’ */
%do l=1 %to &num_t;
%do m=1 %to &num_t;
/* Since S is symmetric, tcmp&l&m is only calculated if tcmp&m&l hasn’t been calculated */
%if &l > &m %then %do;
%let tcmp&l&m=&&tcmp&m&l;
%end;
%else %do;
/* Each iteration of the loop represents an iteration of the summation from 1 to j */
%do k=1 %to &num_c;
%let comp&l&m&k=%sysevalf((&&x&l&k-(&&n&k*&p_bar))*(&&x&m&k-(&&n&k*&p_bar)));
%let tcmp&l&m=%sysevalf(&&tcmp&l&m+&&comp&l&m&k);
%end;
%end;
%end;
%end;
/* Sii’ calculated */
%do l=1 %to &num_t;
%do m=1 %to &num_t;
%let s&l&m=%sysevalf(&&tcmp&l&m*&part1/&part3);
%end;
%end;
/* Chi-square value calculated, put into data set variable */
%let phatcalc=%sysevalf (&p_hat1 - &p_hat2);
%let numer=%sysevalf (&phatcalc*&phatcalc);
%let denom1=%sysevalf (&s11+&s22);
%let denom2=%sysevalf (2*&s12);
%let denom=%sysevalf (&denom1-&denom2);
%let chisq=%sysevalf (&numer/&denom);
data final;
chi=&chisq;
run;
/* p-value calculated with i-1 degrees of freedom, put into macro variable */
data _null_;
set final;
pvalue=1-probchi(chi, %eval(&num_t-1));
call symput ('pvalue', pvalue);
run;
/* Degrees of freedom put into macro variable */
%let dof=%eval(&num_t-1);
/* Calculations output to output window */
data _null_;
file print;
%do l=1 %to &num_t;
put @5 "p_hat&l = &&p_hat&l";
%end;
put;
put @5 "chi-square statistic = &chisq";
put;
put @5 "degrees of freedom = &dof";
put;
put @5 "p-value = &pvalue";
put;
put;
put @5 "S";
put;
%do l=1 %to &num_t;
%do m=1 %to &num_t;
%let fmt=%eval( %sysevalf (14*&m)-9);
put " ";
put @&fmt " &&s&l&m " @;
%end;
put;
%end;
put;
put;
run;
%mend clustpro;
%clustpro(INFIL=exampleData, NUM_C=21);
... View more