*! Date : 08 May 2018 *! Version : 1.0 /* 08/05/18 v1.0 Initial version complete */ program define pval_fixed, rclass version 11.0 syntax, [n(integer 25) pi0(real 0.1) pi(numlist) method(string) /// SUMmary(integer 0) PLot *] local xopt `"`options'"' preserve if ("`method'" == "") { local method "all" } ///// Perform checks on input variables //////////////////////////////////////// if (`n' <= 0) { di "{error} n must be an integer in (0,Inf)." exit(198) } if ((`pi0' <= 0) | (`pi0' >= 1)) { di "{error} pi0 must be a real strictly between 0 and 1." exit(198) } if ("`pi'" ~= "") { local lenpi:list sizeof pi forvalues i = 1/`lenpi' { local pii:word `i' of `pi' if (`pii' > 1 | `pii' < 0) { di "{error} Elements in pi must belong to [0,1]." exit(198) } } } if ("`method'" ~= "all" & "`method'" ~= "exact" & "`method'" ~= "normal") { di "{error} method must be one of: all, exact, or normal." exit(198) } // Set up matrices to pass to mata if ("`pi'" ~= "") { local matapi "" foreach i of local pi{ if "`matapi'" == "" local matapi "`i'" else local matapi "`matapi',`i'" } mat pi = (`matapi') } else { mat pi = . } ///// Compute and Output /////////////////////////////////////////////////////// mata: PvalFixed(`n', `pi0', "`method'", `summary', "`plot'", `"`xopt'"') matrix colnames pval = s m Method "p(s,m)" return mat pval = pval matrix colnames perf = pi Method "E(p|pi)" "Var(p|pi)" return mat perf = perf return mat n = n return mat pi0 = pi0 return mat pi = pi return mat summary = summary restore end ///// Mata //////////////////////////////////////////////////////////////////// mata: void PvalFixed(n, pi0, method, summary, plot, xopt) { pi = st_matrix("pi") if (pi == .) { pi = 0.01*(0::100) } ///// Print Summary ////////////////////////////////////////////////////////// ///// Main Computations ////////////////////////////////////////////////////// if (method == "all") { int_method = (1 \ 2) } else if (method == "exact") { int_method = 1 } else { int_method = 2 } s = 0::n n = J(n + 1, 1, n) pval = (vec(J(length(int_method), 1, s')), vec(J(length(int_method), 1, n')), J(n[1] + 1, 1, int_method), J(length(int_method)*(n[1] + 1), 1, 0)) for (i = 1; i <= rows(pval); i++) { if (pval[i, 3] == 1) { pval[i, 4] = pval_fixed_exact(pval[i, 1], pval[i, 2], pi0) } else { pval[i, 4] = pval_fixed_normal(pval[i, 1], pval[i, 2], pi0) } if (summary == 1 & mod(i, 100) == 0) { printf("{txt}...{res}%g{txt} p-values determined...\n", i) } } dbinomial_pi = J(n[1] + 1, length(pi), 0) for (i = 1; i <= length(pi); i++) { dbinomial_pi[, i] = binomialp(n[1], 0::n[1], pi[i]) } perf = (J(length(int_method), 1, pi), vec(J(length(pi), 1, int_method')), J(length(pi)*length(int_method), 2, 0)) for (i = 1; i <= rows(perf); i++) { pval_i = select(pval, pval[, 3] :== perf[i, 2]) pi_index = mm_which(pi :== perf[i, 1]) perf[i, 3] = sum(dbinomial_pi[, pi_index]:*pval_i[, 4]) perf[i, 4] = sum(dbinomial_pi[, pi_index]:*(pval_i[, 4]:^2)) - perf[i, 3]^2 if (summary == 1 & mod(i, 100) == 0) { printf("{txt}...performance for {res}%g{txt} elements of pi evaluated...\n", i) } } if (plot ~= "") { if (method ~= "all") { st_matrix("perf", perf) stata("qui svmat perf") stata(`"twoway line perf3 perf1, xtitle({&pi}) ytitle(E({it:p}|{&pi}))"'+ xopt) } else { perf1 = select(perf, perf[, 2] :== 1) perf2 = select(perf, perf[, 2] :== 2) st_matrix("perf1", perf1) st_matrix("perf2", perf2) stata("qui svmat perf1") stata("qui svmat perf2") stata(`"twoway (line perf13 perf11, color(blue)) (line perf23 perf21, color(red)), xtitle({&pi}) ytitle(E({it:p}|{&pi})) legend(lab(1 "Exact") lab(2 "Normal"))"'+ xopt) } } ///// Return ///////////////////////////////////////////////////////////////// if (summary == 1) { printf("...outputting.") } st_matrix("pval", pval) st_matrix("perf", perf) st_matrix("n", n[1]) st_matrix("pi0", pi0) st_matrix("pi", pi') st_matrix("summary", summary) } // Function for finding p-value, using the exact method, in a fixed design real scalar pval_fixed_exact(real scalar s, real scalar m, real scalar pi0) { return(binomialtail(m, s, pi0)) } // Function for finding p-value, using the normal method, in a fixed design real scalar pval_fixed_normal(real scalar s, real scalar m, real scalar pi0) { return(1 - normal((s/m - pi0)/sqrt(pi0*(1 - pi0)/m))) } end