Here's what you need to do in general
Hypothesis testing functions in R
create and output a list object of class h.test
. This type of object has a specific set of required components set out in its documentation, and it also has a special method of printing under the print.htest
setting in the global environment. That printing method draws out information from the list, but prints it in the user-friendly way you see in the output in the question. The list should contain the components set out below, including naming several of the objects with a names
attribute. (You are some other optional components shown in the linked documentation.)
Textual description of test
method
: A character string giving the name of the hypothesis test. This will appear as the first sentence of the print output.
data.name
: A character string giving a description of the data, which usually includes reference to the names of the data vectors used in the test. For this part it is useful to use the substitute
and deparse
functions to extract the names of the user inputs to the function as the appropriate names (example shown below).
Specification of hypotheses
null.value
: A numeric variable giving the value of the parameter under the null hypothesis (with a names
attribute).
alternative
: A character string set to greater
, less
or two-sided
, to specify the direction of the alternative hypothesis relative to the null value.
Test statistic and p-value
estimate
: The estimated value of the parameter (with a names
attribute). This value will be a function of the data inputs for the testing function.
statistic
: The value of the test statistic (with a names
attribute). This value will either be a direct function of the data inputs for the testing function, or a function of the parameter estimate.
p.value
: The p-value for the test (which should be a number between zero and one). This value will be a function of the test statistic.
Confidence interval (optional)
conf.int
: A confidence interval represented by a vector with two elements, where the first is the lower bound and the second is the upper bound (with a conf.level
attribute giving the confidence level). If you are using this component, it is desirable to require the function to take a significance level as an input, in order to specify the desired confidence level.
In order to create a custom hypothesis-testing function, you will need to create a function that produces a list containing the required components shown above, customised to your particular test. For the substantive parts of the test (i.e., the estimate, test statistic, p-value, and confidence interval), you will need to use the appropriate formulae for your particular test. Note that you can put these elements in any order in your list, so long as all the required elements are there.
You can also add other components to the list if you wish. It is good practice to add an initial part of your function to check the inputs to the function, to ensure that they are of the correct form, and to stop the function and give error messages if the input is defective in some way. Once your list is created, you set the class of the object to h.test
and output the object at the end of the function.
Here's an example of implementation for a particular test
In a related question I gave an example of code for a hypothesis test taken from Tarone (1979). Below is a slightly modified version of that code that serves as an example for how you can program a function for a custom hypothesis test.
Observe that the code first checks the inputs, and then builds up each of the required components of the test, using the appropriate names and formulae for that specific test. Once these components have been computed, we create a list object called TEST
, composed of these elements, and we set its class to h.test
. We output this object at the end of the function. (It is also worth observing the code for data.name
, which extracts the variable names that are input by the user.)
Tarone.test <- function(N, M) {
#Check validity of inputs
if(!(all(N == as.integer(N)))) { stop("Error: Number of trials should be integers"); }
if(min(N) < 1) { stop("Error: Number of trials should be positive"); }
if(!(all(M == as.integer(M)))) { stop("Error: Count values should be integers"); }
if(min(M) < 0) { stop("Error: Count values cannot be negative"); }
if(any(M > N)) { stop("Error: Observed count value exceeds number of trials"); }
#Set description of test and data
method <- "Tarone's Z test";
data.name <- paste0(deparse(substitute(M)), " successes from ",
deparse(substitute(N)), " trials");
#Set null and alternative hypotheses
null.value <- 0;
attr(null.value, "names") <- "dispersion parameter";
alternative <- "greater";
#Calculate test statistics
estimate <- sum(M)/sum(N);
attr(estimate, "names") <- "proportion parameter";
S <- ifelse(estimate == 1, sum(N),
sum((M - N*estimate)^2/(estimate*(1 - estimate))));
statistic <- (S - sum(N))/sqrt(2*sum(N*(N-1)));
attr(statistic, "names") <- "z";
#Calculate p-value
p.value <- 2*pnorm(-abs(statistic), 0, 1);
attr(p.value, "names") <- NULL;
#Create htest object
TEST <- list(method = method, data.name = data.name,
null.value = null.value, alternative = alternative,
estimate = estimate, statistic = statistic, p.value = p.value);
class(TEST) <- "htest";
TEST; }
Below we create some count data to implement this test and see what the output looks like. As you can see, the output is the same user-friendly output you get for other hypothesis tests in R
, where the components of the test have been pulled out of the list and presented in a nice simple manner. The output shows the name of the test and describes the data, and then it gives the test statistic and p-value for the test. It also describes the alternative hypothesis and gives the sample estimate of the parameter.
#Generate example data
TRIALS <- c(30, 32, 40, 28, 29, 35, 30, 34, 31, 39);
COUNTS <- c( 9, 10, 22, 15, 8, 19, 16, 19, 15, 10);
#Apply Tarone's test to the example data
TEST <- Tarone.test(TRIALS, COUNTS);
TEST;
Tarone's Z test
data: COUNTS successes from TRIALS trials
z = 2.5988, p-value = 0.009355
alternative hypothesis: true dispersion parameter is greater than 0
sample estimates:
proportion parameter
0.4359756