home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 142_01 / chis16.c < prev    next >
Text File  |  1985-03-10  |  7KB  |  277 lines

  1. /* Chi-square and other analyses for 2 x 2 table. Alan Coates, 15 Aug 1984
  2.     Written for Aztec CII compiler. This program is hereby placed in the 
  3.     public domain.  Please send suggestions for improvements or 
  4.     extensions to Alan Coates, 40 Cook Rd, Centennial Park 2021.
  5.  */
  6. #include "libc.h"    /* or your compiler header file, e.g. stdio.h */
  7. #include "math.h"    /* you will need sqrt() or recode for pow()   */
  8. #define ABS(x) (((x) < 0) ? -(x) : (x)) /* unless already in from header */
  9. #define VERS     1
  10. #define SUBV     62
  11. #define DATE     "15 Aug 1984"
  12. #define NO     0
  13. #define YES    1
  14. #define BEL    "\007"        /* ASCII bell */
  15.  
  16. /* HAZELTINE screen controls, octal. Insert your terminal codes as needed
  17.     only one set should be left uncommented
  18. #define INTODIM    "\176\031"
  19. #define OUTODIM    "\176\037"    
  20. #define CLS     "\176\034"    
  21.  */
  22.  
  23. /* Wyse 50 or 100 screen controls, octal */
  24. #define INTODIM    "\033\107\160"
  25. #define OUTODIM    "\033\107\060"    
  26. #define CLS     "\033\052"    
  27.  
  28.  
  29. static double a,b,c,d;        
  30.  
  31. main()
  32.     {
  33.  
  34.     printf("%s%s\n\tContingency Table Analysis v%d.%d  %s\n\t\t\t%s\n",
  35.         OUTODIM,CLS, VERS, SUBV, DATE,"Alan Coates");
  36.     entry();
  37.     exit(0);
  38. }    /* end of main */
  39.  
  40.  
  41. int  chisq(e,f,g,h,y)
  42.  
  43. /*    Uses formula (n)(|eh-fg|-n/2)**2    (omits "-n/2"if not Yates)
  44.              ---------------------
  45.              (e+g)(f+h)(e+f)(g+h)
  46.  */    
  47.     double e,f,g,h;
  48.     int y;
  49.  
  50.     {
  51.     double n;
  52.     double chis;
  53.     char corr[BUFSIZ];
  54.     
  55.     if (y)
  56.         strcpy(corr,"with Yates correction");
  57.     else
  58.         strcpy(corr,"(uncorrected)");
  59.  
  60.     n = (e+f+g+h);
  61.     chis=ABS((e*h)-(f*g));
  62.     if (y)
  63.         chis = ((chis-n/2)>0.1) ? (chis-n/2) : 0;/* Yates correction */
  64.     chis = chis*chis;
  65.     chis = chis*n;    
  66.     /* check for zero or negative row totals */
  67.     if (((e+g)<=0.1)||((f+h)<=0.1)||((e+f)<=0.1)||((g+h)<=0.1)){    
  68.         printf("\n** ERROR ** Row or col total .le. zero %s!\n\n",BEL);
  69.         entry();
  70.         }
  71.     chis = chis/(e+g);    
  72.     chis = chis/(f+h);
  73.     chis = chis/(e+f);
  74.     chis = chis/(g+h);
  75.  
  76.     printf("\n\nChi-squared %s  is %10.2f\n\n", corr, chis);
  77.  
  78.     signif(chis);
  79.  
  80.     if (n < 20){
  81.      printf("\nWARNING - small numbers - consider Fisher's exact test\n");
  82.      puts(BEL);
  83.      }    /* end of small number warning */
  84.     printf("\t\t-----------------------------------------\n");
  85.     return;
  86.     }
  87.  
  88. int  entry()
  89.     {
  90.        printf("%s\nThis program computes chisquared ", INTODIM);
  91.     printf("(with optional Yates correction)\n");
  92.     printf("and other analyses of a 2 x 2 table.\n\n");
  93.     printf("\t\t\ta   |   b\n");
  94.     printf("\t\t\t---------\n");
  95.     printf("\t\t\tc   |   d\n");
  96.     printf("%s\nEnter a b c d separated by space or cr\n: ", OUTODIM);
  97.     while(scanf("%lf %lf %lf %lf", &a, &b, &c, &d) == 4 )
  98.         doit();    /* got data, go select analysis option*/
  99.     printf("%s\ndata error - try again!\n",INTODIM);
  100.     return; /* if scanf error, crash gracefully(?) to system prompt */
  101.     }    /* end of entry module */
  102.  
  103. int doit()
  104.     
  105.     {
  106.     int menu();
  107.  
  108.     for(;;){         /* loops back to menu, can exit from there */
  109.         switch(menu())
  110.             {
  111.         case  1 :
  112.         chisq(a,b,c,d,YES);        /* i.e. WITH Yates */
  113.             break;
  114.         case  2 :
  115.             chisq(a,b,c,d,NO);    /*      or WITHOUT */
  116.             break;
  117.         case  4:
  118.             mcn(a,b);
  119.             break;
  120.         case  5:
  121.             odds(a,b,c,d);
  122.             break;
  123.         case  6:
  124.             risk(a,b,c,d);
  125.             break;
  126.         case  7:
  127.             display(a,b,c,d);
  128.             break;
  129.         case  8:
  130.             confid(a,b,c,d);
  131.             break;
  132.         case  9 :
  133.             printf("\n\tExit selected from menu - %s%s bye!\n",
  134.                 INTODIM,BEL);
  135.             exit(0);
  136.             break;
  137.         case  3:
  138.             entry(); 
  139.             break;
  140.         default:
  141.             display(a,b,c,d);
  142.             printf("Bad option - restart !\n");
  143.             exit(0);
  144.             break;
  145.             }    /* end of switch   */
  146.         }        /* end of for loop */
  147.     }            /* end of function */
  148.  
  149. int menu()
  150.     {
  151.     int choice;
  152.     printf("\n%sOptions are:\n", INTODIM);
  153.     printf("1\tChisquare - Yates correction\t5\tOdds Ratio\n");
  154.     printf("2\tChisquare without correction\t6\tRelative Risk\n");
  155.     printf("3\tEnter new data\t\t\t7\tRedisplay data\n");
  156.     printf("4\tMcNemar's (a,b)\t\t\t8\tConfidence Intervals\n");
  157.     printf("9\tExit\n");
  158.     printf("%s\t\t\tYour choice? : ", OUTODIM);
  159.     scanf("%d",&choice);
  160.     return(choice);
  161.     }
  162.  
  163. int odds(e,f,g,h)
  164.  
  165.     double e,f,g,h;
  166.     {
  167.     double o;
  168.  
  169.     o = (e*h)/(f*g);
  170.     printf("\nOdds Ratio ad/bc is %6.2f\n",o);
  171.     return;
  172.     }
  173.  
  174. int risk(e,f,g,h)
  175.  
  176.     double e,f,g,h;
  177.     {
  178.     double rr;
  179.     
  180.     rr = (e*(g+h));
  181.     rr = rr/(g*(e+f));
  182.     printf("\nRelative risk, i.e. (a/(a+b))/(c/(c+d)) is %6.2f\n", rr);
  183.     return;
  184.     }
  185.  
  186. int display(e,f,g,h)
  187.  
  188.     double e,f,g,h;
  189.  
  190.     {
  191.     printf("\n\t\t\t%4.0f  |  %4.0f\n", e, f);
  192.     printf("Data are\t\t-------------\n");
  193.     printf("\t\t\t%4.0f  |  %4.0f\n\n", g, h);
  194.     printf("\t------------------+-------------------\n");
  195.     return;
  196.     }
  197.  
  198. int confid(e,f,g,h)
  199.  
  200.     double e,f,g,h;
  201.  
  202.     {
  203.     double n;
  204.     double p1, p2, diff, var1, var2, varc, lcl, ucl;
  205.     double sqrt();
  206.     n = e + f + g + h;
  207.     if(((e+f) == 0) || ((g+h) == 0)){
  208.         printf("Row total zero ! %s\n", BEL);
  209.         return;
  210.     }
  211.     else if((((n*e)/(e+f)) < 10) || (((n*g)/(g+h)) < 10)){
  212.         printf("** WARNING ** at extremes, the ");
  213.         printf("normal assumptions are unreliable! %s\n\n", BEL);
  214.     }
  215.     p1 = e/(e+f);
  216.     p2 = g/(g+h);
  217.     diff = p2 - p1;
  218.     var1 = (p1*(1-p1))/(e+f);
  219.     var2 = (p2*(1-p2))/(g+h);
  220.     varc = var1 + var2;
  221.     lcl =  p1 - 1.96*(sqrt(var1));
  222.     ucl =  p1 + 1.96*(sqrt(var1));
  223.     printf("Response rates:\n");
  224.     printf("a/a+b is %4.2f  \t95 pct conf limits %4.2f to  %4.2f \n",
  225.         p1, lcl, ucl);
  226.     lcl =  p2 - 1.96*(sqrt(var2));
  227.     ucl =  p2 + 1.96*(sqrt(var2));
  228.     printf("c/c+d is %4.2f  \t95 pct conf limits %4.2f to  %4.2f \n",
  229.         p2, lcl, ucl);
  230.     lcl =  diff - 1.96*(sqrt(varc));
  231.     ucl =  diff + 1.96*(sqrt(varc));
  232.     printf("\nDifference is %4.2f \n", diff);
  233.     printf("The 95 percent confidence interval\nof this difference is ");
  234.     printf("\t%4.2f to %4.2f \n\n", ucl, lcl);
  235.     return;
  236.     }
  237.  
  238. int mcn(e,f)
  239.     double e,f;
  240.  
  241.     {
  242.     double m;
  243.  
  244.     if(e+f < 0.10){
  245.         printf("\nCannot calculate McNemar if both 0!\n");
  246.         return;
  247.         }
  248.     m = ABS(e - f);
  249.     m -= 1.0;
  250.     m = m*m;
  251.     m = m/(e+f);
  252.     printf("\nMcNemar's test of p(a) = p(b) = 0.5\n");
  253.     printf("gives Chisquared of %4.2f\n", m);
  254.     signif(m);
  255.     return;
  256.     }
  257.  
  258. int signif(x)
  259.     double x;
  260.  
  261.     {
  262.     double p;
  263.  
  264.     if (x > 10.828)    /* critical values of chi-quared with 1 d.f. */
  265.         p = 0.001;
  266.     else if (x > 6.635)
  267.         p = 0.01;
  268.     else 
  269.         p  = 0.05;
  270.  
  271.     if (x > 3.841)
  272.         printf("\twhich is significant: p < %6.3f\n",p);
  273.     else
  274.         printf("\twhich is not significant at the 5 percent level\n");
  275.     return;
  276.     }
  277.