home *** CD-ROM | disk | FTP | other *** search
- (* Multivariate Analysis Package - N-Way Crosstabulation Module
- A copyrighted program by Douglas L. Anderton 1985. This
- program may be freely circulated so long as it is not sold for
- profit and any charge does not exceed costs of reproduction *)
-
- {$A-}
- Program Crosstab(Input,Output);
- (* Up to eight variables and up to 25 unique codes for each, so
- long as the total number of cells is less than 3500. You
- should use a variable with less than 8 unique codes for the
- column variable for the most attractive printout on a 80col.
- printer. *)
- Type
- TB = Array [1..3500] Of Integer;
- IX = Array [1..8,1..25] Of Real;
- I8 = Array [1..8] Of Integer;
- R8 = Array [1..8] Of Real;
- S8 = Array [1..8] Of String[8];
- R25 = Array [1..25] Of Real;
- M25 = Array [1..25,1..25] Of Real;
- Var
- dfile, ofile : Text;
- sel, m, c : I8;
- vars : R8;
- varn : S8;
- indx : IX;
- tabl : TB;
- i, j, k, nv, dv, ot : Integer;
- nc : Real;
-
- Procedure openfiles(Var dfile, ofile:Text; Var nv, dv, ot:Integer);
- Var
- dfl, ofl:String[12];
- Begin
- ClrScr; Writeln(' *** CROSSTAB: N-WAY TABLES AND ASSOCIATION TESTS ***');
- Writeln; Write('Name of the data file? ');
- Readln(dfl); Assign(dfile,dfl); Reset(dfile);
- Write('Name of the output file? ');
- Readln(ofl); Assign(ofile,ofl); Rewrite(ofile);
- ot:= 0;
- If (ofl='CON:') Or (ofl='con:') Then ot:=1;
- If (ofl='LST:') Or (ofl='lst:') Then ot:=2;
- If (ot=2) Then
- Begin
- Writeln(ofile,'Multivariate Analysis Package (1.2) - ',
- 'Program: CROSSTAB, Datafile: ',dfl); Writeln(ofile);
- End;
- Write('How many variables in data file? ');
- Readln(nv);
- Write('Number of variables to use in CROSSTAB? ');
- Readln(dv);
- End; (* Of openfiles *)
-
- Procedure selectvar(Var sel, m:I8; Var varn:S8; dv:Integer);
- Var
- i:Integer;
- Begin
- Writeln; Write('Column number for COLUMN variable? ');
- Read(sel[1]); Write(' Name? '); Readln(varn[1]);
- Write(' Max. No. Categories? '); Readln(m[1]);
- Write('Column number for ROW variable? ');
- Read(sel[2]); Write(' Name? '); Readln(varn[2]);
- Write(' Max. No. Categories? '); Readln(m[2]);
- For i := 3 To dv Do
- Begin
- Write('Column number for BREAKDOWN variable ',i-2,'? ');
- Read(sel[i]); Write(' Name? '); Readln(varn[i]);
- Write(' Max. No. Categories? '); Readln(m[i]);
- End;
- End; (* Of selectvar *)
-
- Procedure getcase(Var vars:R8; sel:I8; nv, dv:Integer; Var dfile:Text);
- Var
- i, j:Integer;
- x:Real;
- Begin
- For i := 1 To nv Do
- Begin
- Read(dfile,x);
- For j := 1 To dv Do
- Begin
- If (sel[j]=i) Then vars[j] := x;
- End;
- End;
- End; (* Of getcase *)
-
- Procedure tables(vars:R8; dv:Integer; Var varn:S8; Var m, c:I8;
- Var indx:IX; Var tabl:TB);
- Var
- i,j,k: Integer;
- cell: I8;
- Begin
- (* for each var search c[] codes stored in indx[] for match *)
- For i:= 1 To dv Do
- Begin
- j := c[i]; cell[i]:=0;
- While j > 0 Do
- Begin
- If (vars[i] = indx[i,j]) Then cell[i] := j;
- j := j - 1;
- End;
- (* no match found set up new code and identify cell *)
- If cell[i] = 0 Then
- Begin
- c[i] := c[i] + 1;
- If c[i] > m[i] Then
- Begin
- ClrScr; gotoXY(5,10);
- Writeln('** Error: Over',m[i]:3,' values for ',varn[i],' **');
- Delay(2000); Bdos(0);
- End;
- indx[i,c[i]] := vars[i]; cell[i] := c[i];
- End;
- End;
- (* add to table *)
- j:=cell[1]; k:=1;
- For i:=2 To dv Do
- Begin
- k:=k*m[i-1];
- j :=j+cell[i]*k;
- End;
- tabl[j] := tabl[j] + 1;
- End; (* Of tables *)
-
- Procedure tabstats(gt:Real; snr, snc:Integer; srtot, sctot:R25;
- save:M25; ot:Integer; Var ofile:Text);
- Var
- i, j, k, l: Integer;
- sr, sc, ar, ac, ex, chi, temp: Real;
- Begin
- (* association statistics *)
- chi:=0.; temp:=0.; k:=0; l:=0;
- For i:=1 To snr Do
- Begin
- If srtot[i] > 0 Then k:=k+1;
- For j:=1 To snc Do
- Begin
- If srtot[i] > 0 Then l:=l+1;
- ex := srtot[i]*sctot[j]/gt;
- If ex > 0. Then
- Begin
- chi := chi+Sqr(save[i,j]-ex)/ex;
- temp := temp+Sqr(Abs(save[i,j]-ex)-0.5)/ex;
- End;
- End;
- End;
- Writeln(ofile); i:=(k-1)*(l-1);
- Writeln(ofile,'Chi-Square:',chi:10:4,' Degrees of freedom:',i:4);
- If i=1 Then Writeln(ofile,'Yale''s correction for continuity:',temp:9:4);
- temp := Sqrt(chi/(chi+gt));
- Writeln(ofile,'Contingency Coefficient:',temp:9:4);
- temp := k; If k<l Then temp:=l;
- chi := sqrt(chi/(gt*(temp-1)));
- Writeln(ofile,'Cramer''s V:',chi:7:4);
- sc:=0.;
- For i:= 1 to snc Do
- Begin
- ar:=0.;
- For j:= 1 to snr Do
- If save[i,j] > ar Then ar:=save[i,j];
- sc:=sc+ar;
- End;
- ar:=0;
- For i:=1 to snr Do
- If srtot[i] > ar Then ar:=srtot[i];
- sr:=0.;
- For i:= 1 to snr Do
- Begin
- ac:=0.;
- For j:= 1 to snc Do
- If save[i,j] > ac Then ac:=save[i,j];
- sr:=sr+ac;
- End;
- ac:=0;
- For i:=1 to snc Do
- If sctot[i] > ac Then ac:=sctot[i];
- If (gt-ar) > 0 Then
- Begin
- temp:=(sc-ar)/(gt-ar);
- Writeln(ofile,'Asymmetric Lambda with Row Dependent:',temp:9:4);
- End;
- If (gt-ac) > 0 Then
- Begin
- temp:=(sr-ac)/(gt-ac);
- Writeln(ofile,'Asymmetric Lambda with Column Dependent:',temp:9:4);
- End;
- If ((2*gt)-ar-ac) > 0 Then
- Begin
- temp:=(sr+sc-ac-ar)/((2*gt)-ar-ac);
- Writeln(ofile,'Symmetric Lambda:',temp:9:4);
- End;
- Writeln(ofile);
- If ot=1 Then
- Begin
- Write('- Press any key to continue -'); While Not KeyPressed Do;
- ClrScr;
- End;
- End; (* Of tabstats *)
-
- Procedure tabout(dv:Integer; m, c:I8; Var varn:S8;
- Var indx:IX; Var tabl:TB; Var ofile:Text; ot:Integer);
- Var
- i,j,k:Integer;
- save: M25;
- srtot, sctot: R25;
- snr, snc: Integer;
- gt: Real;
- Begin
- (* save 2-way dimensions *)
- snr:=c[2]; snc:=c[1];
- If dv=2 Then c[3]:=1;
- While c[3] > 0 Do
- Begin
- (* write header *)
- If dv > 2 Then
- Writeln(ofile,'Breakdown ',varn[3],' = ',indx[3,c[3]]:8:2);
- Writeln(ofile,'Table rows:',varn[2],' by columns:',varn[1]);
- Writeln(ofile); Write(ofile,' ');
- For i:=1 To snc Do
- Begin
- Write(ofile,indx[1,snc-i+1]:8:2);
- sctot[i]:=0.0;
- End;
- Writeln(ofile);
- For i:=1 To snr Do srtot[i]:=0.0;
- c[2]:=snr;
- While c[2] > 0 Do
- Begin (* loop over rows *)
- Write(ofile,indx[2,c[2]]:8:2,' ');
- c[1]:=snc;
- While c[1] > 0 Do
- Begin (* loop over cols *)
- j:=c[1]; k:=1;
- For i:=2 To dv Do
- Begin
- k:=k*m[i-1];
- j :=j+c[i]*k;
- End;
- Write(ofile,tabl[j]:8);
- (* save 2-way table *)
- save[c[2],c[1]]:=tabl[j];
- srtot[c[2]]:=srtot[c[2]]+tabl[j];
- sctot[c[1]]:=sctot[c[1]]+tabl[j];
- c[1] := c[1] - 1;
- End;
- Writeln(ofile,srtot[c[2]]:8:0);
- c[2] := c[2] - 1;
- End;
- (* write col totals and grand *)
- Write(ofile,' ');
- For i:=1 To snc Do
- Begin
- Write(ofile,sctot[snc-i+1]:8:0);
- gt:=gt+sctot[i];
- End;
- Writeln(ofile,gt:8:0); Writeln(ofile);
- If ot=1 Then
- Begin
- Write('- Press any key to continue -'); While Not KeyPressed Do;
- ClrScr;
- End;
- tabstats(gt, snr, snc, srtot, sctot, save, ot, ofile);
- c[3] := c[3] - 1;
- End;
- End; (* Of tabout *)
-
- Procedure tablop(dv,k:Integer;Var m, c:I8; Var varn:S8;
- Var indx:IX; Var tabl:TB; Var ofile:Text; ot:integer);
- Var
- l: Integer;
- Begin
- k := k - 1; l:=c[k];
- If k < 4 Then l := 1;
- While (l > 0) And (k > 1) Do
- Begin
- (* recursive loop to final 3 levels then write *)
- If k > 3 Then
- Begin
- Writeln(ofile,'Breakdown ',varn[k],' = ',indx[k,c[k]]:8:2);
- tablop(dv,k,m,c,varn,indx,tabl,ofile,ot);
- c[k] := c[k] - 1;
- End;
- If k < 4 Then tabout(dv,m,c,varn,indx,tabl,ofile,ot);
- l := l - 1;
- End;
- k := k + 1;
- End; (* Of tablop *)
-
- Begin (* main *)
- openfiles(dfile,ofile,nv,dv,ot);
- (* intialize *)
- nc := 0.;
- For i:=1 To 3000 Do tabl[i] := 0;
- For i:=1 To 8 Do
- Begin
- c[i] := 0; m[i] := 0;
- End;
- selectvar(sel,m,varn,dv);
- (* accumulate tables, c=#codes in indx for var *)
- Writeln;
- k:=0;
- While Not EOF(dfile) Do
- Begin
- k:=k+1;
- getcase(vars, sel, nv, dv, dfile);
- If Frac(k/10)=0.0 Then Write('+');
- If Not EOF(dfile) Then
- Begin
- nc := nc + 1;
- tables(vars,dv,varn,m,c,indx,tabl);
- End;
- End;
- (* compute for 2-ways And Output *)
- k := dv + 1;
- ClrScr;
- tablop(dv,k,m,c,varn,indx,tabl,ofile,ot);
- Close(dfile); Close(ofile);
- End.
- ┼╒σ!î█⌡┼╒σσ≡ !Y φ░╤:jO:lé╒═╙╤:kO:mâ═╙!≡ ═Ñ*n═ß╤┴±╔!≡ δ!i45(╔!+/û0ⁿå⌡y■0(±φ╔
- d!9├-!I├-