<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: MACRO CLUSTPRO in New SAS User</title>
    <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725800#M28076</link>
    <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/15131"&gt;@ron_horne&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think the error is here:&lt;/P&gt;
&lt;PRE&gt;/* Sii’ calculated */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&lt;STRONG&gt;&lt;FONT color="#FF0000"&gt;&amp;amp;part1&amp;amp;part3&lt;/FONT&gt;&lt;/STRONG&gt;);
%end;
%end;&lt;/PRE&gt;
&lt;P&gt;With the example data, &lt;FONT face="courier new,courier"&gt;&amp;amp;part1=1.05&lt;/FONT&gt;,&amp;nbsp; &lt;FONT face="courier new,courier"&gt;&amp;amp;part3=2601&lt;/FONT&gt;, which are 21/20 and 51**2, respectively, computed from the integer constants 21 and 51 involved in the study data. Apparently an operator is missing between &lt;FONT face="courier new,courier"&gt;&amp;amp;part1&lt;/FONT&gt; and &lt;FONT face="courier new,courier"&gt;&amp;amp;part3&lt;/FONT&gt; in the calculation of &lt;FONT face="courier new,courier"&gt;s&amp;amp;l&amp;amp;m&lt;/FONT&gt;&amp;nbsp;because concatenation doesn't make sense. The fact that many computations in the macro are done with macro variables (none of which is declared as local ...) is a weakness of the code anyway.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It seems that the division operator (&lt;FONT face="courier new,courier"&gt;/&lt;/FONT&gt;) does a good job here (but without the &lt;A href="https://onlinelibrary.wiley.com/doi/10.1002/(SICI)1097-0258(19980715)17:13%3C1495::AID-SIM863%3E3.0.CO;2-I" target="_blank" rel="noopener"&gt;Obuchowski paper [behind a paywall]&lt;/A&gt; I'm only guessing).&lt;/P&gt;
&lt;PRE&gt;%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&amp;amp;part1&lt;FONT size="5" color="#008000"&gt;&lt;STRONG&gt;/&lt;/STRONG&gt;&lt;/FONT&gt;&amp;amp;part3);&lt;/PRE&gt;
&lt;P&gt;At least the results get &lt;EM&gt;much&lt;/EM&gt; closer to those in the article:&lt;/P&gt;
&lt;PRE&gt;    p_hat1 = 0.7843137255
    p_hat2 = 0.9019607843
    chi-square statistic = 2.85714285599953
    degrees of freedom = 1
    p-value =  0.090968948

    S
     0.00510488158443
                   0.00093340907387
     0.00093340907387
                   0.00160622722075&lt;/PRE&gt;
&lt;P&gt;The only significant difference occurs in value &lt;FONT face="courier new,courier"&gt;&amp;amp;s22&lt;/FONT&gt; where the paper has an additional zero after the decimal point: 0.00&lt;STRONG&gt;&lt;FONT color="#FF0000"&gt;0&lt;/FONT&gt;&lt;/STRONG&gt;16062272. But this must be a typo in the paper because otherwise the relationship&lt;/P&gt;
&lt;PRE&gt;chisq = (p_hat1 - p_hat2)**2 / (s11+s22-2*s12)&lt;/PRE&gt;
&lt;P&gt;would be violated and this equality holds also in the example found in the NESUG 2006 paper "&lt;A href="https://www.google.com/url?client=internal-element-cse&amp;amp;cx=011240857950991443104:hsqcj3nokh0&amp;amp;q=https://www.lexjansen.com/nesug/nesug06/an/da01.pdf&amp;amp;sa=U&amp;amp;ved=2ahUKEwjxydGm2arvAhUQQEEAHcSoAa0QFjAAegQIABAB&amp;amp;usg=AOvVaw3bscKL6o-AWDTuZcEqNj_X" target="_blank" rel="noopener"&gt;Statistical Analysis of Clustered Data using SAS® System&lt;/A&gt;" (see Fig. 10, p. 6).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note that matrix S is described in the Lieber/Ashley paper as&amp;nbsp;"the variance-covariance matrix for p&lt;SUB&gt;1&lt;/SUB&gt; and p&lt;SUB&gt;2&lt;/SUB&gt;", i.e., the&amp;nbsp;covariance matrix of two random variables with values between 0 and 1 (if I interpret this correctly). As such the diagonal entries s11 and s22 must be between 0 and 0.25 and the other two (equal) entries s12 must be between -0.25 and 0.25 (regardless of the input data). So, values like 13.31, 2.43 and 4.19 as obtained with the uncorrected code are definitely wrong.&lt;/P&gt;</description>
    <pubDate>Fri, 12 Mar 2021 15:13:19 GMT</pubDate>
    <dc:creator>FreelanceReinh</dc:creator>
    <dc:date>2021-03-12T15:13:19Z</dc:date>
    <item>
      <title>MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725536#M28066</link>
      <description>&lt;P&gt;dear members,&lt;/P&gt;
&lt;P&gt;i would like to use the macro %clustpro:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://support.sas.com/resources/papers/proceedings/proceedings/sugi23/Posters/p204.pdf" target="_blank"&gt;https://support.sas.com/resources/papers/proceedings/proceedings/sugi23/Posters/p204.pdf&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;I am having an issue extracting the script from the PDF. Apparently the formatting in the PDF file has messed up the text in a way that produces many errors when I try to run it.&lt;/P&gt;
&lt;P&gt;I would be very thankful if anyone can extract the script, and re-post it here in working order. perhaps as a text file.&lt;/P&gt;
&lt;P&gt;I did correct all quotation marks&amp;nbsp; that were not recognized and added some missing spaces. yet, this is not enough and I get different results than the example.&lt;/P&gt;
&lt;P&gt;many thanks!&lt;/P&gt;</description>
      <pubDate>Thu, 11 Mar 2021 17:43:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725536#M28066</guid>
      <dc:creator>ron_horne</dc:creator>
      <dc:date>2021-03-11T17:43:28Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725547#M28067</link>
      <description>If you post what you've extracted so far, maybe someone can help you debug it further?&lt;BR /&gt;I quick search (Google/Github) didn't show anything obvious to me.&lt;BR /&gt;&lt;BR /&gt;I would also check if that methodology hasn't been added to SAS/Stat functionality, SUGI23 was a long time ago...23 years in fact.</description>
      <pubDate>Thu, 11 Mar 2021 18:32:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725547#M28067</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2021-03-11T18:32:56Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725560#M28068</link>
      <description>&lt;P&gt;thank you &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13879"&gt;@Reeza&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;please see the code i have so far.&lt;/P&gt;
&lt;P&gt;i do not think it was added to the program.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* 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;
infile &amp;amp;infil;
input i j xij nj;
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(&amp;amp;num_t);
%let lenc=%length(&amp;amp;num_c);

/* "." added to end of lengths (for formatting purposes) */
data _null_;
call symput('fort', &amp;amp;lent||'.');
call symput('forc', &amp;amp;lenc||'.');
run;

/* xij, nj put into macro variables and trimmed */
data _null_;
set tmp;

call symput ('x'||left(put(i, &amp;amp;fort))||left(put(j, &amp;amp;forc)), xij);
call symput ('n'||left(put(j, &amp;amp;forc)), nj);
run;

%do k=1 %to &amp;amp;num_c;
	%let n&amp;amp;k=%eval(&amp;amp;&amp;amp;n&amp;amp;k);

	%do l=1 %to &amp;amp;num_t;
		%let x&amp;amp;l&amp;amp;k=%eval(&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;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;

/* &amp;amp;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 &amp;amp;num_t;

data b&amp;amp;k;
set a;
if i=&amp;amp;k;
p_hat&amp;amp;k=sumx/sumn;
run;

data _null_;
set b&amp;amp;k;
tmp=&amp;amp;k;
call symput('p_hat'||left(put(tmp, 1.)), p_hat&amp;amp;k);
run;
%let sum=%sysevalf(&amp;amp;sum+&amp;amp;&amp;amp;p_hat&amp;amp;k);
%end;

/* p bar computed */
%let p_bar=%sysevalf (&amp;amp;sum/&amp;amp;num_t);

/* part1=j/(j-1) (Used in computing the matrix S) */
%let part1=%sysevalf (&amp;amp;num_c*(1/(&amp;amp;num_c-1)));

/* part3=(sum of njs)^2 (Used in computing the matrix S) */
%let part3=%eval (&amp;amp;sumn*&amp;amp;sumn);

/* Part 2 computed */
/* Each iteration of part 2 initialized to 0 */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let tcmp&amp;amp;l&amp;amp;m=0;
%end;
%end;

/* l represents i, m represents i’ */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;

/* Since S is symmetric, tcmp&amp;amp;l&amp;amp;m is only calculated if tcmp&amp;amp;m&amp;amp;l hasn’t been calculated */
%if &amp;amp;l &amp;gt; &amp;amp;m %then %do;
%let tcmp&amp;amp;l&amp;amp;m=&amp;amp;&amp;amp;tcmp&amp;amp;m&amp;amp;l;
%end;

%else %do;

/* Each iteration of the loop represents an iteration of the summation from 1 to j */
				%do k=1 %to &amp;amp;num_c;
					%let comp&amp;amp;l&amp;amp;m&amp;amp;k=%sysevalf((&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar))*(&amp;amp;&amp;amp;x&amp;amp;m&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar)));
					%let tcmp&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m+&amp;amp;&amp;amp;comp&amp;amp;l&amp;amp;m&amp;amp;k);
			%end;
		%end;
	%end;
%end;

/* Sii’ calculated */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&amp;amp;part1&amp;amp;part3);
%end;
%end;

/* Chi-square value calculated, put into data set variable */
%let phatcalc=%sysevalf (&amp;amp;p_hat1 - &amp;amp;p_hat2);
%let numer=%sysevalf (&amp;amp;phatcalc*&amp;amp;phatcalc);
%let denom1=%sysevalf (&amp;amp;s11+&amp;amp;s22);
%let denom2=%sysevalf (2*&amp;amp;s12);
%let denom=%sysevalf (&amp;amp;denom1-&amp;amp;denom2);
%let chisq=%sysevalf (&amp;amp;numer/&amp;amp;denom);
data final;
chi=&amp;amp;chisq;
run;

/* p-value calculated with i-1 degrees of freedom, put into macro variable */
data _null_;
set final;
pvalue=1-probchi(chi, %eval(&amp;amp;num_t-1));
call symput ('pvalue', pvalue);
run;

/* Degrees of freedom put into macro variable */
%let dof=%eval(&amp;amp;num_t-1);

/* Calculations output to output window */
data _null_;
file print;
%do l=1 %to &amp;amp;num_t;
put @5 "p_hat&amp;amp;l = &amp;amp;&amp;amp;p_hat&amp;amp;l";
%end;
put;
put @5 "chi-square statistic = &amp;amp;chisq";
put;
put @5 "degrees of freedom = &amp;amp;dof";
put;
put @5 "p-value = &amp;amp;pvalue";
put;
put;
put @5 "S";
put;
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let fmt=%eval( %sysevalf (14*&amp;amp;m)-9);
put @&amp;amp;fmt "&amp;amp;&amp;amp;s&amp;amp;l&amp;amp;m" @;
%end;
put;
%end;
put;
put;
run;
%mend clustpro;

%clustpro (INFIL='C:\Users\Smart\Documents\sample.dat', NUM_C=21);




&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 11 Mar 2021 19:11:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725560#M28068</guid>
      <dc:creator>ron_horne</dc:creator>
      <dc:date>2021-03-11T19:11:09Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725595#M28069</link>
      <description>&lt;P&gt;This runs for me and generates the following:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;  p_hat1 = 0.7843137255                                                                                                           
    p_hat2 = 0.9019607843                                                                                                           
   &lt;FONT size="4" color="#FF6600"&gt;&lt;STRONG&gt; chi-square statistic = 0.00109576424212 &lt;/STRONG&gt; &lt;/FONT&gt;                                                                                       
    degrees of freedom = 1                                                                                                          
    &lt;FONT size="4" color="#FF6600"&gt;&lt;STRONG&gt;p-value = 0.9735929848 &lt;/STRONG&gt; &lt;/FONT&gt;                                                                                                        
    S                                                                                                                               
 &lt;FONT size="4" color="#FF6600"&gt;   &lt;STRONG&gt; 13.3106880011136                                                                                                               
                   2.43381100114915                                                                                                 
     2.43381100114915                                                                                                               
                   4.18814600118416  &lt;/STRONG&gt; &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;The values in Orange do not match the values in the paper using the sample data they provided.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I would personally find another example to verify my numbers as this is a user written paper - you have no certainty that this code is correct or accurate. Either the code is wrong or the data is wrong, but unless you exactly understand the process that would be very hard to know.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Full code to reproduce numbers, &lt;FONT color="#FF0000"&gt;&lt;STRONG&gt;note&lt;/STRONG&gt;&lt;/FONT&gt; that I modified the macro slightly to take an input data set instead of reading the data from a text file.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;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 &amp;amp;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(&amp;amp;num_t);
%let lenc=%length(&amp;amp;num_c);

/* "." added to end of lengths (for formatting purposes) */
data _null_;
call symput('fort', &amp;amp;lent||'.');
call symput('forc', &amp;amp;lenc||'.');
run;

/* xij, nj put into macro variables and trimmed */
data _null_;
set tmp;

call symput ('x'||left(put(i, &amp;amp;fort))||left(put(j, &amp;amp;forc)), xij);
call symput ('n'||left(put(j, &amp;amp;forc)), nj);
run;

%do k=1 %to &amp;amp;num_c;
	%let n&amp;amp;k=%eval(&amp;amp;&amp;amp;n&amp;amp;k);

	%do l=1 %to &amp;amp;num_t;
		%let x&amp;amp;l&amp;amp;k=%eval(&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;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;

/* &amp;amp;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 &amp;amp;num_t;

data b&amp;amp;k;
set a;
if i=&amp;amp;k;
p_hat&amp;amp;k=sumx/sumn;
run;

data _null_;
set b&amp;amp;k;
tmp=&amp;amp;k;
call symput('p_hat'||left(put(tmp, 1.)), p_hat&amp;amp;k);
run;
%let sum=%sysevalf(&amp;amp;sum+&amp;amp;&amp;amp;p_hat&amp;amp;k);
%end;

/* p bar computed */
%let p_bar=%sysevalf (&amp;amp;sum/&amp;amp;num_t);

/* part1=j/(j-1) (Used in computing the matrix S) */
%let part1=%sysevalf (&amp;amp;num_c*(1/(&amp;amp;num_c-1)));

/* part3=(sum of njs)^2 (Used in computing the matrix S) */
%let part3=%eval (&amp;amp;sumn*&amp;amp;sumn);

/* Part 2 computed */
/* Each iteration of part 2 initialized to 0 */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let tcmp&amp;amp;l&amp;amp;m=0;
%end;
%end;

/* l represents i, m represents i’ */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;

/* Since S is symmetric, tcmp&amp;amp;l&amp;amp;m is only calculated if tcmp&amp;amp;m&amp;amp;l hasn’t been calculated */
%if &amp;amp;l &amp;gt; &amp;amp;m %then %do;
%let tcmp&amp;amp;l&amp;amp;m=&amp;amp;&amp;amp;tcmp&amp;amp;m&amp;amp;l;
%end;

%else %do;

/* Each iteration of the loop represents an iteration of the summation from 1 to j */
				%do k=1 %to &amp;amp;num_c;
					%let comp&amp;amp;l&amp;amp;m&amp;amp;k=%sysevalf((&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar))*(&amp;amp;&amp;amp;x&amp;amp;m&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar)));
					%let tcmp&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m+&amp;amp;&amp;amp;comp&amp;amp;l&amp;amp;m&amp;amp;k);
			%end;
		%end;
	%end;
%end;

/* Sii’ calculated */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&amp;amp;part1&amp;amp;part3);
%end;
%end;

/* Chi-square value calculated, put into data set variable */
%let phatcalc=%sysevalf (&amp;amp;p_hat1 - &amp;amp;p_hat2);
%let numer=%sysevalf (&amp;amp;phatcalc*&amp;amp;phatcalc);
%let denom1=%sysevalf (&amp;amp;s11+&amp;amp;s22);
%let denom2=%sysevalf (2*&amp;amp;s12);
%let denom=%sysevalf (&amp;amp;denom1-&amp;amp;denom2);
%let chisq=%sysevalf (&amp;amp;numer/&amp;amp;denom);
data final;
chi=&amp;amp;chisq;
run;

/* p-value calculated with i-1 degrees of freedom, put into macro variable */
data _null_;
set final;
pvalue=1-probchi(chi, %eval(&amp;amp;num_t-1));
call symput ('pvalue', pvalue);
run;

/* Degrees of freedom put into macro variable */
%let dof=%eval(&amp;amp;num_t-1);

/* Calculations output to output window */
data _null_;
file print;
%do l=1 %to &amp;amp;num_t;
put @5 "p_hat&amp;amp;l = &amp;amp;&amp;amp;p_hat&amp;amp;l";
%end;
put;
put @5 "chi-square statistic = &amp;amp;chisq";
put;
put @5 "degrees of freedom = &amp;amp;dof";
put;
put @5 "p-value = &amp;amp;pvalue";
put;
put;
put @5 "S";
put;
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let fmt=%eval( %sysevalf (14*&amp;amp;m)-9);
put " ";
put @&amp;amp;fmt " &amp;amp;&amp;amp;s&amp;amp;l&amp;amp;m " @;
%end;
put;
%end;
put;
put;
run;
%mend clustpro;

%clustpro(INFIL=exampleData, NUM_C=21);


&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 11 Mar 2021 20:15:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725595#M28069</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2021-03-11T20:15:19Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725613#M28070</link>
      <description>&lt;P&gt;thank you &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13879"&gt;@Reeza&lt;/a&gt; ,&lt;/P&gt;
&lt;P&gt;this is what i get, but in the paper the results are as follows.&lt;/P&gt;
&lt;P&gt;there is no error message in the log so i do not know how to fix it.&lt;/P&gt;
&lt;P&gt;p_hat1 = 0.7843137255&lt;BR /&gt;p_hat2 = 0.9019607843&lt;BR /&gt;chi-square statistic = 2.8571429014&lt;BR /&gt;degrees of freedom = 1&lt;BR /&gt;p-value = 0.0909689455&lt;BR /&gt;S&lt;BR /&gt;0.0051048816 0.0009334091&lt;BR /&gt;0.0009334091 0.00016062272&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 11 Mar 2021 20:39:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725613#M28070</guid>
      <dc:creator>ron_horne</dc:creator>
      <dc:date>2021-03-11T20:39:06Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725800#M28076</link>
      <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/15131"&gt;@ron_horne&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think the error is here:&lt;/P&gt;
&lt;PRE&gt;/* Sii’ calculated */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&lt;STRONG&gt;&lt;FONT color="#FF0000"&gt;&amp;amp;part1&amp;amp;part3&lt;/FONT&gt;&lt;/STRONG&gt;);
%end;
%end;&lt;/PRE&gt;
&lt;P&gt;With the example data, &lt;FONT face="courier new,courier"&gt;&amp;amp;part1=1.05&lt;/FONT&gt;,&amp;nbsp; &lt;FONT face="courier new,courier"&gt;&amp;amp;part3=2601&lt;/FONT&gt;, which are 21/20 and 51**2, respectively, computed from the integer constants 21 and 51 involved in the study data. Apparently an operator is missing between &lt;FONT face="courier new,courier"&gt;&amp;amp;part1&lt;/FONT&gt; and &lt;FONT face="courier new,courier"&gt;&amp;amp;part3&lt;/FONT&gt; in the calculation of &lt;FONT face="courier new,courier"&gt;s&amp;amp;l&amp;amp;m&lt;/FONT&gt;&amp;nbsp;because concatenation doesn't make sense. The fact that many computations in the macro are done with macro variables (none of which is declared as local ...) is a weakness of the code anyway.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It seems that the division operator (&lt;FONT face="courier new,courier"&gt;/&lt;/FONT&gt;) does a good job here (but without the &lt;A href="https://onlinelibrary.wiley.com/doi/10.1002/(SICI)1097-0258(19980715)17:13%3C1495::AID-SIM863%3E3.0.CO;2-I" target="_blank" rel="noopener"&gt;Obuchowski paper [behind a paywall]&lt;/A&gt; I'm only guessing).&lt;/P&gt;
&lt;PRE&gt;%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&amp;amp;part1&lt;FONT size="5" color="#008000"&gt;&lt;STRONG&gt;/&lt;/STRONG&gt;&lt;/FONT&gt;&amp;amp;part3);&lt;/PRE&gt;
&lt;P&gt;At least the results get &lt;EM&gt;much&lt;/EM&gt; closer to those in the article:&lt;/P&gt;
&lt;PRE&gt;    p_hat1 = 0.7843137255
    p_hat2 = 0.9019607843
    chi-square statistic = 2.85714285599953
    degrees of freedom = 1
    p-value =  0.090968948

    S
     0.00510488158443
                   0.00093340907387
     0.00093340907387
                   0.00160622722075&lt;/PRE&gt;
&lt;P&gt;The only significant difference occurs in value &lt;FONT face="courier new,courier"&gt;&amp;amp;s22&lt;/FONT&gt; where the paper has an additional zero after the decimal point: 0.00&lt;STRONG&gt;&lt;FONT color="#FF0000"&gt;0&lt;/FONT&gt;&lt;/STRONG&gt;16062272. But this must be a typo in the paper because otherwise the relationship&lt;/P&gt;
&lt;PRE&gt;chisq = (p_hat1 - p_hat2)**2 / (s11+s22-2*s12)&lt;/PRE&gt;
&lt;P&gt;would be violated and this equality holds also in the example found in the NESUG 2006 paper "&lt;A href="https://www.google.com/url?client=internal-element-cse&amp;amp;cx=011240857950991443104:hsqcj3nokh0&amp;amp;q=https://www.lexjansen.com/nesug/nesug06/an/da01.pdf&amp;amp;sa=U&amp;amp;ved=2ahUKEwjxydGm2arvAhUQQEEAHcSoAa0QFjAAegQIABAB&amp;amp;usg=AOvVaw3bscKL6o-AWDTuZcEqNj_X" target="_blank" rel="noopener"&gt;Statistical Analysis of Clustered Data using SAS® System&lt;/A&gt;" (see Fig. 10, p. 6).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note that matrix S is described in the Lieber/Ashley paper as&amp;nbsp;"the variance-covariance matrix for p&lt;SUB&gt;1&lt;/SUB&gt; and p&lt;SUB&gt;2&lt;/SUB&gt;", i.e., the&amp;nbsp;covariance matrix of two random variables with values between 0 and 1 (if I interpret this correctly). As such the diagonal entries s11 and s22 must be between 0 and 0.25 and the other two (equal) entries s12 must be between -0.25 and 0.25 (regardless of the input data). So, values like 13.31, 2.43 and 4.19 as obtained with the uncorrected code are definitely wrong.&lt;/P&gt;</description>
      <pubDate>Fri, 12 Mar 2021 15:13:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/725800#M28076</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2021-03-12T15:13:19Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/728791#M28295</link>
      <description>&lt;P&gt;Dear &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;THANK YOU! you must be correct.&lt;/P&gt;
&lt;P&gt;sorry for the late response, the message went to my spam box.&lt;/P&gt;
&lt;P&gt;your solution is correct and produces the right chiSqr as well as Pvalue.&lt;/P&gt;
&lt;P&gt;this data is used in the following R package called: clust.bin.pair - &lt;A href="https://cran.r-project.org/web/packages/clust.bin.pair/index.html" target="_blank"&gt;https://cran.r-project.org/web/packages/clust.bin.pair/index.html&lt;/A&gt; also described here: &lt;A href="https://cran.r-project.org/package=clust.bin.pair/clust.bin.pair.pdf" target="_blank"&gt;https://cran.r-project.org/package=clust.bin.pair/clust.bin.pair.pdf&lt;/A&gt; &lt;BR /&gt;I must admit, this was not an easy task but you have hit the nail on the head.&lt;/P&gt;
&lt;P&gt;All the best!&lt;/P&gt;
&lt;P&gt;Ron&lt;/P&gt;</description>
      <pubDate>Wed, 24 Mar 2021 15:53:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/728791#M28295</guid>
      <dc:creator>ron_horne</dc:creator>
      <dc:date>2021-03-24T15:53:14Z</dc:date>
    </item>
    <item>
      <title>Re: MACRO CLUSTPRO</title>
      <link>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/728803#M28298</link>
      <description>&lt;P&gt;Just to conclude, thanks to &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp; ,&lt;/P&gt;
&lt;P&gt;this is a working version from a to z:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;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 &amp;amp;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(&amp;amp;num_t);
%let lenc=%length(&amp;amp;num_c);

/* "." added to end of lengths (for formatting purposes) */
data _null_;
call symput('fort', &amp;amp;lent||'.');
call symput('forc', &amp;amp;lenc||'.');
run;

/* xij, nj put into macro variables and trimmed */
data _null_;
set tmp;

call symput ('x'||left(put(i, &amp;amp;fort))||left(put(j, &amp;amp;forc)), xij);
call symput ('n'||left(put(j, &amp;amp;forc)), nj);
run;

%do k=1 %to &amp;amp;num_c;
	%let n&amp;amp;k=%eval(&amp;amp;&amp;amp;n&amp;amp;k);

	%do l=1 %to &amp;amp;num_t;
		%let x&amp;amp;l&amp;amp;k=%eval(&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;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;

/* &amp;amp;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 &amp;amp;num_t;

data b&amp;amp;k;
set a;
if i=&amp;amp;k;
p_hat&amp;amp;k=sumx/sumn;
run;

data _null_;
set b&amp;amp;k;
tmp=&amp;amp;k;
call symput('p_hat'||left(put(tmp, 1.)), p_hat&amp;amp;k);
run;
%let sum=%sysevalf(&amp;amp;sum+&amp;amp;&amp;amp;p_hat&amp;amp;k);
%end;

/* p bar computed */
%let p_bar=%sysevalf (&amp;amp;sum/&amp;amp;num_t);

/* part1=j/(j-1) (Used in computing the matrix S) */
%let part1=%sysevalf (&amp;amp;num_c*(1/(&amp;amp;num_c-1)));

/* part3=(sum of njs)^2 (Used in computing the matrix S) */
%let part3=%eval (&amp;amp;sumn*&amp;amp;sumn);

/* Part 2 computed */
/* Each iteration of part 2 initialized to 0 */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let tcmp&amp;amp;l&amp;amp;m=0;
%end;
%end;

/* l represents i, m represents i’ */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;

/* Since S is symmetric, tcmp&amp;amp;l&amp;amp;m is only calculated if tcmp&amp;amp;m&amp;amp;l hasn’t been calculated */
%if &amp;amp;l &amp;gt; &amp;amp;m %then %do;
%let tcmp&amp;amp;l&amp;amp;m=&amp;amp;&amp;amp;tcmp&amp;amp;m&amp;amp;l;
%end;

%else %do;

/* Each iteration of the loop represents an iteration of the summation from 1 to j */
				%do k=1 %to &amp;amp;num_c;
					%let comp&amp;amp;l&amp;amp;m&amp;amp;k=%sysevalf((&amp;amp;&amp;amp;x&amp;amp;l&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar))*(&amp;amp;&amp;amp;x&amp;amp;m&amp;amp;k-(&amp;amp;&amp;amp;n&amp;amp;k*&amp;amp;p_bar)));
					%let tcmp&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m+&amp;amp;&amp;amp;comp&amp;amp;l&amp;amp;m&amp;amp;k);
			%end;
		%end;
	%end;
%end;

/* Sii’ calculated */
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let s&amp;amp;l&amp;amp;m=%sysevalf(&amp;amp;&amp;amp;tcmp&amp;amp;l&amp;amp;m*&amp;amp;part1/&amp;amp;part3);
%end;
%end;

/* Chi-square value calculated, put into data set variable */
%let phatcalc=%sysevalf (&amp;amp;p_hat1 - &amp;amp;p_hat2);
%let numer=%sysevalf (&amp;amp;phatcalc*&amp;amp;phatcalc);
%let denom1=%sysevalf (&amp;amp;s11+&amp;amp;s22);
%let denom2=%sysevalf (2*&amp;amp;s12);
%let denom=%sysevalf (&amp;amp;denom1-&amp;amp;denom2);
%let chisq=%sysevalf (&amp;amp;numer/&amp;amp;denom);
data final;
chi=&amp;amp;chisq;
run;

/* p-value calculated with i-1 degrees of freedom, put into macro variable */
data _null_;
set final;
pvalue=1-probchi(chi, %eval(&amp;amp;num_t-1));
call symput ('pvalue', pvalue);
run;

/* Degrees of freedom put into macro variable */
%let dof=%eval(&amp;amp;num_t-1);

/* Calculations output to output window */
data _null_;
file print;
%do l=1 %to &amp;amp;num_t;
put @5 "p_hat&amp;amp;l = &amp;amp;&amp;amp;p_hat&amp;amp;l";
%end;
put;
put @5 "chi-square statistic = &amp;amp;chisq";
put;
put @5 "degrees of freedom = &amp;amp;dof";
put;
put @5 "p-value = &amp;amp;pvalue";
put;
put;
put @5 "S";
put;
%do l=1 %to &amp;amp;num_t;
%do m=1 %to &amp;amp;num_t;
%let fmt=%eval( %sysevalf (14*&amp;amp;m)-9);
put " ";
put @&amp;amp;fmt " &amp;amp;&amp;amp;s&amp;amp;l&amp;amp;m " @;
%end;
put;
%end;
put;
put;
run;
%mend clustpro;

%clustpro(INFIL=exampleData, NUM_C=21);


&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 24 Mar 2021 16:10:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/New-SAS-User/MACRO-CLUSTPRO/m-p/728803#M28298</guid>
      <dc:creator>ron_horne</dc:creator>
      <dc:date>2021-03-24T16:10:03Z</dc:date>
    </item>
  </channel>
</rss>

