BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sherineeltoukhy
Fluorite | Level 6

It ran, it ran!!! Thank you @Reeza

Tom
Super User Tom
Super User

Below is a copy of the macro you posted.  I modified it to use parameters instead of hard coding information into the macro defintion. I also modified it work with an existing SAS dataset. 

 

To use it you need to know the name of your data set (the same name you would use in a PROC PRINT or other SAS code) and the list of variables you want to run the test on.

 

For example you might call it like this:

%mcartest
(indata=  work.eatingrisk         /* Input DATASET name */
,testvars=  abuse bds1 bds2 bds3 bds4 bds5 bds6 bds7       /* SPECIFY VARIABLE SET FOR THE MCAR TEST */
,misscode=-99      /* SPECIFY THE MISSING VALUE CODE */
);

Here is the SAS code to define the macro. There should be no need to change it (other than fix any errors I introduced) to use it. Just run it once to define the macro and then call it with parameter options like in example above.

%macro mcartest
(indata=           /* Input DATASET name */
,testvars=         /* SPECIFY VARIABLE SET FOR THE MCAR TEST */
,misscode=-99      /* SPECIFY THE MISSING VALUE CODE */
);
/******************************************************************************************************************
* This SAS macro implements the chi-square test for a missing completely at random (MCAR) mechanism, as *
* outlined in Little's (1998) JASA article. Note that the macro requires SAS version 8.2 (or higher) because *
* PROC MI is used to obtain ML estimates of the covariance matrix and mean vector. * *
******************************************************************************************************************/

%local numvars ;
%let numvars = %sysfunc(countw(&testvars));

data one;
  set &indata (keep=&testvars);
  array m[&numvars] &testvars ;
  array r[&numvars] r1 - r&numvars ;

  do i = 1 to &numvars;
    if m[i] = &misscode then m[i] = .;
    r[i] = not missing(m[i]);
  end;
  drop i;
run;

proc sort;
  by r1-r&numvars;
run;

proc mi data = one nimpute = 0 noprint;
  var &testvars;
  em outem = emcov;
run;

proc iml;

use one;
read all var {&testvars} into y;
read all var {%do i = 1 %to &numvars; r&i %end;} into r;
use emcov;
read all var {&testvars} into em;

mu = em[1,];
sigma = em[2:nrow(em),];

/* ASSIGN AN INDEX VARIABLE DENOTING EACH CASE'S PATTERN */

jcol = j(nrow(y), 1 , 1);

do i = 2 to nrow(y);
  rdiff = r[i,] - r[i - 1,];
  if max(rdiff) = 0 & min(rdiff) = 0 then jcol[i,] = jcol[i - 1,];
  else jcol[i,] = jcol[i - 1,] + 1;
end;

/* NUMBER OF DISTINCT MISSING DATA PATTERNS */

j = max(jcol);

/* PUT THE NUMBER OF CASES IN EACH PATTERN IN A COL VECTOR M */
/* PUT THE MISSING DATA INDICATORS FOR EACH PATTERN IN A MATRIX RJ */

m = j(j, 1, 0);
rj = j(j, ncol(r), 0);

do i = 1 to j;
  count = 0;
  do k = 1 to nrow(y);
    if jcol[k,] = i then do;
      count = count + 1;
    end;
    if jcol[k,] = i & count = 1 then rj[i,] = r[k,];
    m[i,] = count;
  end;
end;

/* COMPUTE D^2 STATISTIC FOR EACH J PATTERN */

d2j = j(j, 1, 0);

do i = 1 to j;

/* OBSERVED VALUES FOR PATTERN J */
  yj = y[loc(jcol = i),loc(rj[i,] = 1)];

/* VARIABLE MEANS FOR PATTERN J */
  ybarobsj = yj[+,]/nrow(yj);

/* D = P X Pj MATRIX OF INDICATORS (SEE P. 1199) */
  Dj = j(ncol(y), rj[i,+], 0);

  count = 1;
  do k = 1 to ncol(rj);
    if rj[i,k] = 1 then do;
      Dj[k, count] = 1;
      count = count + 1;
    end;
  end;

/* REDUCE EM ESTIMATES TO CONTAIN OBSERVED ELEMENTS */
  muobsj = mu * Dj;
  sigmaobsj = t(Dj) * sigma * Dj;

/* THE CONTRIBUTION TO THE D^2 STATISTIC FOR EACH OF THE J PATTERNS */
  d2j[i,] = m[i,] * (ybarobsj - muobsj) * inv(sigmaobsj) * t(ybarobsj - muobsj);

end;

/* THE D^2 STATISTIC */
d2 = d2j[+,];

/* DF FOR D^2 */
df = rj[+,+] - ncol(rj);
p = 1 - probchi(d2,df);

/* PRINT ANALYSIS RESULTS */
file print;
put "Number of Observed Variables = " (ncol(rj)) 3.0;
put "Number of Missing Data Patterns = " (j) 3.0; put;
put "Summary of Missing Data Patterns (0 = Missing, 1 = Observed)"; put;
put "Frequency | Pattern | d2j"; put;
do i = 1 to nrow(rj);
  put (m[i,]) 6.0 " | " @;
  do j = 1 to ncol(rj);
    put (rj[i,j]) 2.0 @;
  end;
  put " | " (d2j[i,]) 8.6;
end;
put;
put "Sum of the Number of Observed Variables Across Patterns (Sigma psubj) = " (rj[+,+]) 5.0; put;
put "Little's (1988) Chi-Square Test of MCAR"; put;
put "Chi-Square (d2) = " (d2) 10.3;
put "df (Sigma psubj - p) = " (df) 7.0;
put "p-value = " (p) 10.3;

quit;
%mend mcartest;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 16 replies
  • 4264 views
  • 6 likes
  • 5 in conversation