Running z-tests with R

If you are sure about it or at least have very good reasons to assume that you are right about the population's variance, you should use a z-test. Some would say that you could go strictly to a z-test if you have a big enough sample even if you're estimating your population's variance through sample—which is not assumed by z-tests.

There are mainly two reasons for that. First, as your sample gets bigger—given some conditions such as limited mean—your sample's estimations converge to the true values, and the true parameters; so, with a big enough sample, you have more reasons to believe that you really know the real parameters.

The other reason can be seen in Figure 2.1. With greater samples come greater degrees of freedom (these were actually Uncle Ben's last words to Peter Parker). The more degrees of freedom you have, the more your test distribution will look like a normal distribution. That is actually a consequence of reason number one, and you can visualize this by trying the following code:

x <- seq(-4,4,.1)
par(lwd = 2)
plot(x, dnorm(x), type = 'l', ylab = 'density',
main = 'prob. density distributions')
lines(x, dt(x, 500), col = '#e66101')

Try to find the black line and fail! The black line is hiding behind the orange line. Both lines are matching. But, of course, if you could zoom in enough you would see there's still a small difference between these two lines; hence, I and some other people would argue that it's best to use the t-test no matter the sample's size (size doesn't matter—that's what she said). Practically, the difference you get from using one or another comes to be very small as your sample grows—it's up to you which one to use.

So, now that we discussed why/when we should use one instead of the other, we can go ahead and see how to practically run a z-test with R. There's no function like t.test() sitting there waiting for you to run a z-test right away—maybe R developers agree with me, t-tests are usually better. But you can easily wrap a function to calculate the test and drop the statistics for you.

Do you remember the formula for the t-test statistic? The only difference between the t-test statistic and z-test one is that, instead of trusting the estimator, S, for the standard deviation, you use the value that we assume you know and trust a standard normal distribution to make your decision. That's it, you are assuming that you know the true standard deviation and hence that your test statistic follows a standard normal distribution (that is, a normal distribution with mean zero and variance one). The formula gets to be this:

The sigma in the equation is now accounting for the true value of the standard deviation that the test assumes you know (a very uncommon situation). Sigma is usually estimated in the exact same way that the t-test does, a very good reason to stick with t-test. Anyway, to walk through this test is also a good way to get to know the t-test better, given that everything remains the same and the only change is the distribution used to compare the statistic.

Usually, to use a z-test means you're comparing your test statistic with a standardized normal distribution and not that you actually know the standard deviation, sigma, for sure. Yet, if your sample is big enough, you're safe using a z-test.

A good way to start is to make a checklist of everything we might need to get this test done. We need:

  1. mu, sigma, and sample to work as inputs
  2. Calculate the test statistic
  3. Define an alternative hypothesis
  4. Calculate the p-value
  5. Estimate a confidence interval

Let's start with steps one and two:

z.test <- function(sample, mu, sigma){
n <- length(sample)
xbar <- mean(sample, na.rm =T)
z <- (xbar - mu)/(sigma/sqrt(n))
cat('z = ', z,' ')
}

Now we have a function that will output the test statistic if we input a sample, a hypothetical mean, and a standard deviation. We could elaborate on this function in order to output the p-value; this way we could put our decision rule to good use. The way the alternative hypothesis is set does affect how the p-value should be calculated; hence, the code is chaining some if...else statements to work things out. The code becomes lengthy but do not be afraid, read it calmly and I'm positive that you are getting it right: 

z.test <- function(sample, mu, sigma, alternative = 'two.sided'){
n <- length(sample)
xbar <- mean(sample, na.rm =T)
z <- (xbar - mu)/(sigma/sqrt(n))

if(alternative == 'two.sided'){
p.value <- 2*pnorm(-abs(z))
}
else if(alternative == 'greater'){
p.value <- pnorm(z, lower.tail = F)
}
else if(alternative == 'less'){
p.value <- pnorm(z)
}
else{stop('alternative is missepecified, accepted values are
'two.sided','greater' or 'less' ')}

cat('z = ', z, ' obs. = ', n, ' p-value = ', p.value, ' ')
cat('mean of x ', xbar, ' ')
}

The preceding code is pretty lengthy but it's only due to the various unfoldings that might come from different ways of setting the alternative hypothesis. It's modular, though. The previous code can be split into three modules: a first module stores the mean, number of observations, and calculates test statistic (z); the second one calculates the p-value based on the alternative hypothesis chosen; and the last module prints a little summary.

Let's navigate through the if statements from the second module. By looking at one if statement at a time, we can get a better understanding of how p-values should be calculated with respect to the alternative hypothesis. The first if statement is the following:

  if(alternative == 'two.sided'){
p.value <- 2*pnorm(-abs(z))'
}

Two-sided tests (Ha: mu ≠ mu0) consider both tails from the test's distribution as rejecting areas—areas for which you might reject the null hypothesis. These tests are trying to figure out how likely it would be to see a test statistic of z or even more extreme values if those samples were coming from a normally distributed variable with true mean equal (μ) and standard deviation equal σ.

The last chunk is looking for the negative version (left-hand version) of the test statistic (-abs(z)) and asking how likely it would be to find values equal or lower to this one within a standard normal distribution (the same distribution that our test statistic is assumed to follow). The pnorm() function is taking care of calculating this probability. Since the exact same probability may be found on the other extreme (the right-hand tail), our p-value is simply two times that probability; hence, p-value (p.value) is given by 2*pnorm(-abs(z)).

A one-sided test could be selected by setting the alternative argument of z.test() either to 'greater' or 'less'. In case the former is selected, the following the else if statement will be called to use:

  else if(alternative == 'greater'){
p.value <- pnorm(z, lower.tail = F)
}

Declaring alternative = 'greater' is useful when the true mean being greater than some value is critical to the decision-making process. For example, if you're testing the concentration of a toxin in the bloodstream, you don't care if the level of toxin is too low, the important thing is to make sure that it's not too high.

For these cases, you will only reject your null hypothesis if you find extreme values on the right-hand side of the distribution, also known as the upper tail. The p-value is then the probability of finding the estimated test statistic (z) or even greater values if our assumptions were true. Such a probability is easily calculated by pnorm(z, lower.tail = F). The lower.tail = F argument makes sure that we are looking for the probability of getting values equal or higher than z instead of the other way round.

You can also specify mean and standard deviation from the normal distribution you're looking for with pnorm(). Name and set values for the mean and sd arguments. Default values for those are respectively zero and one, which leads to a standardized normal distribution—the distribution that our test statistic is assumed to follow.

On the other hand, if the only thing that is critical to your decision-making process is whether the true mean is lower than some value, set alternative = 'less' when calling z.test(). The rejection area will now be sitting on the lower tail (left-hand side) of the test's distribution and is calculated by the following if statement (inside the z.test() function):

  else if(alternative == 'less'){
p.value <- pnorm(z)
}

This time, the p-value is showing the probability of getting a value equal or lower to z within the test distribution. Notice that we skipped the lower.tail = F argument so that pnorm() will only seek the probability of getting values equal or lower than z. After the p-value is properly computed, z.test() will output the test statistic (z), the number of observations, the p-value (which is useful to the previously described decision rule), and the estimated sample mean.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.67.235