/* Umbrella tests for a one-way layout Test whether treatment groups increase to a particular treatment group then decrease afterwards Two versions: Known peak and unknown peak */ #include #include #include /* Prototypes for all functions in statlib.c */ #include "statlib.h" /* Compile with e.g. */ /* gcc -Wall -o Umbrella Umbrella.c statlib.c */ /* with both statlib.h and statlib.c in the same directory as Umbrella.c */ /* Number of permutation simulations to estimate P-values */ /* and the starting random-number seed. */ int nsims=10000; unsigned long wseed=123456; #define MAXK 10 /* Upper bound for number of treatment groups */ #define MAXN 50 /* Upper bound for number of observations per group */ #define MAXTOT (MAXK*MAXN) /* Upper bound for total number of observations */ /* Two data sets */ /* Dataset I: */ /* Title and source */ const char *title_one="Five treatment groups with 10 observations each"; const char *source_one="(Simulated data)"; /* Descriptive names for treatment groups */ const char *treatnames_one[MAXK] = { "#1", "#2", "#3", "#4", "#5", "#6" }; /* Number of treatment groups and treatment-group sample sizes */ const int kk_one=5; const int nn_one[MAXK] = { 10, 10, 10, 10, 10 }; /* Data with treatment groups as rows */ /* See comments in OneWayLayout.c for syntax of double arrays */ /* and how to initialize them. */ const double xx_one[MAXK][MAXN] = { { 308, 308, 12, 206, 368, 264, 88, 240, 118, 264 }, { 126, 252, 262, 258, 136, 204, 170, 276, 314, 308 }, { 218, 364, 300, 322, 46, 180, 278, 454, 70, 188 }, { 358, 366, 394, 252, 430, 274, 216, 284, 350, 290 }, { 332, 358, 356, 178, 262, 158, 176, 278, 240, 304 } }; /* How to display the data in a printf() statement */ const char *dataformat_one="%3g"; /* Dataset II: */ /* Title and source */ const char *title_two="Fasting metabolic rates in deer by months"; const char *source_two="Hollander & Wolfe Table 6.8, p215"; const char *treatnames_two[MAXK] = { "Jan-Feb", "Mar-Apr", "May-Jun", "Jul-Aug", "Sep-Oct", "Nov-Dec" }; /* Number of treatment groups and treatment-group sample sizes */ const int kk_two=6; const int nn_two[MAXK] = { 7, 3, 5, 4, 4, 3 }; /* Data with treatment groups as rows */ const double xx_two[MAXK][MAXN] = { { 36.0, 33.6, 26.9, 35.8, 30.1, 31.2, 35.3 }, { 39.9, 29.1, 43.4 }, { 44.6, 54.4, 48.2, 55.7, 50.0 }, { 53.8, 53.9, 62.5, 46.6 }, { 44.3, 34.1, 35.7, 35.6 }, { 31.7, 22.1, 30.7 } }; /* How to display the data in a printf() statement */ const char *dataformat_two="%4.1f"; /* Carry out umbrella tests for one dataset */ void do_umbrella_tests (const char *title, const char *source, const char *treatnames[MAXK], const double xx[MAXK][MAXN], const int nn[MAXK], const int kk, const int pp, const char *dataformat); int main(int argc, char **argv) { printf ( "\nUMBRELLA TESTS for a one-way layout\n" "Test whether treatment groups increase to a particular treatment group\n" " then decrease afterwards\n" "Two versions: Known peak and unknown peak\n"); /* Helpful messages on segmentation faults and some other fatal errors */ /* This function is in statlib.c */ set_newsignals(); /* Seed random-number seed */ /* Enter `ProgramName ' to set starting RN seed= */ if (argc>=2) wseed=atol(argv[1]); wseed=setrand(wseed); /* If wseed=0, replace by true starting seed */ printf ("\nStarting random-number seed: %lu\n",wseed); printf ("(Enter a number on the command line " "to specify a different seed.)\n"); /* First dataset */ printf ("\nFIRST DATA SET:\n"); do_umbrella_tests(title_one, source_one, treatnames_one, xx_one, nn_one, kk_one, 4, dataformat_one); printf ("\n--------------------------------------------\n"); printf ("--------------------------------------------\n"); /* Second dataset */ printf ("\nSECOND DATA SET:\n"); /* Switch to 100,000 simulations for the second dataset */ nsims=100000; do_umbrella_tests(title_two, source_two, treatnames_two, xx_two, nn_two, kk_two, 4, dataformat_two); /* Show total random numbers used */ show_randnums_used(); return 0; } /* Functions to carry out known-p and unknown-p umbrella tests */ void do_one_umbrella(int pp, const double ww[MAXTOT], const int nfirst[MAXK], const int nn[MAXK], int kk); void do_max_umbrella(const double ww[MAXTOT], const int nfirst[MAXK], const int nn[MAXK], int kk); void do_umbrella_tests (const char *title, const char *source, const char *treatnames[MAXK], const double xx[MAXK][MAXN], const int nn[MAXK], const int kk, const int pp, const char *dataformat) { int i,j,r, ntot; /* nfirst[i] is the offset in wwdat[] of the first value in row #i */ int nfirst[MAXK]; /* Variables for midranks: */ double wwdat[MAXTOT]; /* All observations */ double mrank[MAXTOT]; /* The corresponding midranks */ /* Show dataset description and source */ printf ("%s\n%s\n", title,source); /* Count the total number of observations */ for (ntot=i=0; i0) /* This allows for empty treatment groups */ { for (j=nf; j=obs_aap) nbig++; } /* Display the estimated P-value and a CI for the P-value */ show_pval(nbig,nsims); } /* Subroutines for do_umbrella() and do_max_umbrella() */ /* For data for kk treatment groups stored in a single linear */ /* array ww[], with the i-th treatment group starting at nfirst[i] */ /* of length nn[i], put the corresponding Mann-Whitney differences */ /* in the array uu[][]. */ void make_mannwhitney_diffs(double uu[MAXK][MAXK], const double ww[MAXTOT], const int nfirst[MAXK], const int nn[MAXK], int kk) { int i,j, a,b; for (i=0; ipp; i--) for (j=i-1; j>=pp; j--) { printf ("%sU(%d,%d)",sgn,i,j); sgn="+"; } printf("\n ="); sgn=""; for (i=1; ipp; i--) for (j=i-1; j>=pp; j--) { double u=uu[i-1][j-1]; printf(" %s %g",sgn,u); ap+=u; sgn="+"; } printf(" = %g\n",ap); } /* Return the umbrella statistic Ap using Mann-Whitney differences */ /* stored in uu[][] */ /* Note p=1,2,...,kk while i,j offsets are 0,1,..,kk-1 */ double get_aap (int pp, double uu[MAXK][MAXK], int kk) { int i,j; double aap=0.0; for (i=0; iobs_max_astar) { obs_max_astar=zz; pmax=p; }} printf ("MAX ASTAR=%.3f at p=%d\n", obs_max_astar, pmax); printf ("\nSimulating the P-value of MaxAstar=%.3f " "using %s permutations:\n", obs_max_astar, commnum(nsims)); /* Copy the data in ww[] to wtemp[] for permutations */ for (ntot=i=0; imstar) mstar=zz; } /* Allow for a small amount of roundoff error */ if (mstar>=obs_max_astar-(1e-12)) nbig++; } printf ("The multiple-comparison-corrected P-value " "for MaxAstar=%.3f is:\n", obs_max_astar); /* Display the estimated P-value and a CI for the P-value */ show_pval(nbig,nsims); }