Chapter 14 t-tests: Comparing means
We will cover the following:
- One-sample t-test
- Paired t-test
- Two-sample t-test (“Welch’s t-test”)
14.1 Some theory
In this theory section I focus on the one-sample t-test, but the concepts apply to the other types of t-test.
The one-sample t-test is used to compare the mean of a sample to some fixed value. For example, we might want to compare the concentration of an air pollutant (e.g. in µg/m3) in a sample to some acceptable threshold value to help us decide whether we need to take action to prevent or clean up pollution.
One of the assumptions of t-tests (and many other tests/models) is that the residuals (the deviations of each observation from its group mean) come from a normal distribution. For a t-test, in practice, this means that the measured values for each group should be approximately normally distributed (for a paired t-test, it is the differences within pairs that should be approximately normal). Another key assumption is that the observations (or, for a paired test, the pairs) are independent of each other.
If these assumptions hold, you can use the data to estimate two things: the mean, and the standard error of the mean.
We will talk more about model assumptions later.
The mean gives an estimate of location, and the standard error of the mean (calculated as \(s/ \sqrt{n}\), where s = standard deviation and n = sample size) gives an estimate of precision (i.e. how certain we are that the mean value is really where we think it is). Note the difference between these two measures of spread: the standard deviation (SD) describes how variable the individual measurements are, whereas the standard error (SE) describes how uncertain our estimate of the mean is. Collecting more independent measurements does not change the SD much, but it makes the SE smaller. Because a t-test asks a question about a mean, it uses the SE.
The t-test then works by comparing the estimated mean (and its uncertainty) with some fixed value. Sometimes you are asking “is my mean different from the value?”, other times you are asking “is my mean less than/greater than the value?”. This depends on the hypothesis. The default that R uses is that it tests whether the mean of your distribution is different to the fixed value, but in many cases you should be framing a directional hypothesis.
It is helpful to visualise this, so some examples of the pollution threshold test are shown in the figure below (Figure 14.1 ). The curves illustrate the uncertainty in our estimate of the mean pollution level from some data (e.g. each curve might represent samples from different locations): each is centred on an estimated mean, and its width reflects the standard error. We are interested in whether the mean values (the vertical dashed lines) are significantly greater than the threshold of 100 µg/m3 (solid vertical black line) (this gives us a directional hypothesis).
Formally we do this by establishing two hypotheses about the population mean, \(\mu\): a null hypothesis and an alternative hypothesis. In this case, the null hypothesis (H0) is that the population mean is less than or equal to the threshold value (\(\mu \le 100\)). The alternative hypothesis (H1) is that the population mean is greater than this threshold value (\(\mu > 100\)). Note that hypotheses are statements about the population, not about the sample, and that the word “significant” does not belong in a hypothesis: significance is a property of the result of the test.
The degree of confidence that we can have that the mean pollution values are different from the threshold value depends on (A) the position of the distribution relative to the threshold value and (B) the spread of the distribution (the standard error).
Based on Figure 14.1, which of these four different samples shows a mean value significantly greater than 100? (you should be looking at the amount of the normal distribution curve that is overlapping the threshold value.)
Figure 14.1: Visualisation of a t-test.
This should look familiar – it is the same concept as we used in the class on randomisation tests. If you find it confusing, please go back and review the randomisation test materials!
Another useful way to think about t-tests is that it is a way of distinguishing between signal and noise: the signal is the difference between the estimated mean and the value specified by the null hypothesis, and the noise is the uncertainty in that estimate. This uncertainty could be due to measurement error and/or natural variation. In fact, the t-value that the t-test relies on is a ratio between the signal (difference between mean (\(\bar{x}\)) and threshold (\(\mu_{0}\))) and noise (variability, standard error of the mean (\(s/ \sqrt{n}\))): \[t = \frac{\bar{x}-\mu_{0}} {s/ \sqrt{n}}\]
The larger the signal is compared to the noise, the larger (in absolute value) the t-value will be. e.g. a t-value of 2 means that the estimated mean is 2 standard errors away from the null value. A t-value of zero, or close to zero, means that the signal is “drowned out” by the noise. Therefore, large t-values give you stronger evidence against the null hypothesis.
To know if the t-value means that the difference is significant, the t-value is compared to a known theoretical distribution (the t-distribution), which describes the values of t we would expect if the null hypothesis were true. The area under the curve of the distribution is 1, but its shape depends on the degrees of freedom (for a one-sample t-test, the sample size - 1). The plot below (Figure 14.2) shows three t-distributions of different degrees of freedom (d.f.).
What R is doing when it figures out the p-value is calculating the area under the curve beyond the t-statistic. For a two-sided test this is the area in both tails (beyond +t and -t); for a one-sided test it is the area in the one tail specified by the alternative hypothesis. If t is small, then this area (the p-value) is large. If t is large then the area (and the p-value) is small. Remember that the p-value is the probability of getting a result at least this extreme if the null hypothesis were true; it is not the probability that the null hypothesis is true. In the olden-days (>15 years ago) you would have looked these values up in printed tables, but now R does that for us.
Figure 14.2: The t-distribution
14.2 One sample t-test
Enough theory. Here’s how you would apply such a test in R.
In this chapter we use these packages (and, as always, work inside your course RStudio project so that the relative data paths work):
Firstly, let’s load some data: 20 measurements of the concentration of an air pollutant, in µg/m3. Because this is a very small example, you can simply cut and paste the data in rather than loading it from a CSV file.
pollution <- data.frame(ugm3 = c(
105, 196, 226, 81, 156, 201, 142, 149, 191, 192,
178, 185, 231, 76, 207, 138, 146, 175, 114, 155
))First I plot the data (Figure 14.3). One reason for doing this is to check that the data look approximately normally distributed. These data are slightly left-skewed but they are close enough.
Figure 14.3: Histogram of the pollution data.
Now we can run a t-test in R like this. The command is simple - the arguments are the data (x), the fixed value you are comparing the data to (mu), and the alternative hypothesis (alternative). This can take values of “two.sided”, “less” or “greater” (the default is two.sided). In this example, the alternative hypothesis is that the mean of our sample is greater than the threshold of 100.
##
## One Sample t-test
##
## data: pollution$ugm3
## t = 6.2824, df = 19, p-value = 2.478e-06
## alternative hypothesis: true mean is greater than 100
## 95 percent confidence interval:
## 145.0803 Inf
## sample estimates:
## mean of x
## 162.2
The output of the model tells us (1) what type of t-test is being fitted (“One Sample t-test”). Then it gives some values for the t-statistic, the degrees of freedom and the p-value. The model output also tells us that the alternative hypothesis “true mean is greater than 100”. Because the p-value is very small (p<0.05) we can reject the null hypothesis: the data provide strong evidence that the population mean is greater than 100. Finally, the output gives you the estimate of the mean and a 95% confidence interval for it. A confidence interval is a range of plausible values for the population mean: if we repeated the sampling many times, 95% of intervals calculated this way would contain the true mean. Because we asked a one-sided question (“greater than”), R gives a one-sided interval: the lower bound is 145.08 and the upper bound is Inf (infinity), meaning that the procedure gives no finite upper limit. The whole interval lies above 100, which agrees with the small p-value. If you want a conventional two-sided interval to report alongside the estimate, run the test without the alternative argument: t.test(pollution$ugm3, mu = 100)$conf.int gives 141.5 to 182.9 µg/m3. Its lower limit is a little lower than 145.08 because the 5% is now split between the two tails (2.5% each) rather than all placed in the lower tail.
We could report these results like this: “the mean value of the sample was 162.2 µg/m3 (one-sided 95% lower confidence bound: 145.1 µg/m3), which is significantly greater than the threshold of 100 µg/m3 (one-sample t-test: t = 6.28, df = 19, p = 2.5 x 10-6)”.
14.3 Doing it “by hand” - where does the t-statistic come from?
At this point, to ensure that you understand where the t-statistic comes from we will calculate the t-statistic using the equation from above. The purpose of this is to illustrate that this is not brain surgery - it all hinges on a straightforward comparison between signal (the difference between mean and threshold in this case) and noise (the variation, or standard error of the mean).
To do this we first need to know the mean value and the threshold (the signal: \(\bar{x} - \mu_{0}\)). We can then divide that by the standard error of the mean (the noise: \(s/ \sqrt{n}\))
Here goes… I first create a vector (x) of the values to save typing. Then I show how to calculate mean and standard error, before dividing the “signal” by the “noise”.
## [1] 162.2
## [1] 9.900718
## [1] 6.282373
This matches exactly with the t-statistic above!
One can obtain a p-value from a given t-statistic and degrees of freedom like this for a t-test like the one fitted above (the d.f. is the sample size minus one for a one-sample t-test):
## [1] 2.477945e-06
Again, this matches the value from the t.test function above. (lower.tail = FALSE asks for the area in the upper tail, which is what we need for the “greater than” alternative hypothesis. It is equivalent to 1 - pt(6.282373, 19) but more accurate when the p-value is very small.)
14.4 Paired t-test
It’s actually quite hard to find examples of one-sample t-tests in biology. Most one-sample t-tests you will encounter are really paired t-tests. A paired t-test is a special case of the one-sample test where, rather than using the actual values measured, we use the difference between the two measurements in each pair, and compare the mean difference with zero (Figure 14.4).
Figure 14.4: Visualising a paired t-test.
Here’s a simple example. Anthropologists studied tool use in women from the indigenous Machiguenga of Peru9. They measured how many kilograms of sweet manioc (cassava) a woman dug up per hour spent digging, using either a traditional wooden tool (a broken palm-wood bow) or a metal machete. In each of 5 trials, a woman dug up the roots of two manioc plants at the same location, one with each tool, so that differences in patch quality and individual skill were controlled for. (Their Table 1 gives the data used here; it misprints the first difference as 60 instead of 80.)
Each trial used both tools, so each trial provides a pair of measurements, and the five pairs (not the ten measurements) are the independent units. The anthropologists expected the metal tool to be more efficient, and analysed their data with one-tailed paired t-tests. Here, to illustrate the default two-sided test, we will ask the more general question of whether harvesting efficiency differed between the tools. The null hypothesis is that the mean difference in harvest rate between the two tools (machete - bow) is zero, i.e. that on average a woman was equally efficient at foraging using either tool. The alternative hypothesis is that the mean difference is not zero. (NOTE - as the original authors did, this could also be formulated as a directional hypothesis, with the expectation that the machete is more efficient than the bow. If so, that decision should be made before looking at the data.)
First let’s import and look at the data. Make sure you understand it. For a paired t-test, the normality assumption applies to the differences within pairs. With only five pairs, a plot will tell us very little about whether these differences are normally distributed, so we will have to assume that they are. t-tests are fairly robust to moderate departures from normality, especially with larger samples, but with very small samples like this one, the assumption matters more and is hard to check.
## subjectID tool amount
## 1 1 machete 119
## 2 1 bow 39
## 3 2 machete 216
## 4 2 bow 114
## 5 3 machete 240
## 6 3 bow 150
## 7 4 machete 129
## 8 4 bow 51
## 9 5 machete 137
## 10 5 bow 60
We should now plot our data (Figure 14.5). A nice way of doing this for paired data is to plot points with lines joining the pairs. This way, the slope of the lines is a striking visual indication of the effect.
ggplot(toolUse, aes(x = tool, y = amount, group = subjectID)) +
geom_line() +
geom_point() +
xlab("Tool used") +
ylab("Cassava harvested (kg/hr)")
Figure 14.5: An interaction plot for the tool use data
We can also look at the mean values and standard deviations:
## # A tibble: 2 × 3
## tool meanAmount sdAmount
## <chr> <dbl> <dbl>
## 1 bow 82.8 47.3
## 2 machete 168. 55.6
Now let’s do a paired t-test to compare the means using the two tools. The best way to do this is to provide the two samples separately in the t.test command. To do this you will need to create two vectors containing the data from the two groups like this, using the dplyr command pull to extract the variable along with filter to subset the data.
IMPORTANT: it is very important that the pairs are arranged in the data frame so that the pairs match up when you filter the data to each group. It is therefore advisable to use arrange to sort the data by first the pairing variable (in this case, subjectID), and then the explanatory variable (the variable that defines the group - in this case, tool). R pairs the values by their position in the two vectors, not by subjectID, so if the rows are in a different order for the two tools, the test will pair the wrong measurements without any warning.
toolUse <- toolUse %>%
arrange(subjectID, tool)
A <- toolUse %>%
filter(tool == "machete") %>%
pull(amount)
B <- toolUse %>%
filter(tool == "bow") %>%
pull(amount)
t.test(A, B, paired = TRUE)##
## Paired t-test
##
## data: A and B
## t = 17.98, df = 4, p-value = 5.625e-05
## alternative hypothesis: true mean difference is not equal to 0
## 95 percent confidence interval:
## 72.21262 98.58738
## sample estimates:
## mean difference
## 85.4
You would report these results something like this: “Women dug up cassava more efficiently with a machete (168.2 kg/hr) than with a wooden tool (82.8 kg/hr). The mean difference of 85.4 kg/hr (95% CI 72.2-98.6 kg/hr) was statistically significant (paired t-test: t = 17.98, df = 4, p = 5.6 x 10-5).”
NOTE: you could add the argument alternative = "less" or alternative = "greater" to these t-tests to turn them into directional (one-tailed) tests. The direction refers to the first group minus the second: here, alternative = "greater" tests whether machete - bow is greater than zero. When the observed difference is in the predicted direction, the one-tailed p-value is half the two-tailed p-value. When it is in the opposite direction, the one-tailed p-value is close to 1 (it is 1 minus half the two-tailed p-value). So you can only halve the two-tailed p-value if you chose the direction before seeing the data and the result is in that direction.
14.5 A paired t-test is a one-sample test
A paired t-test is the same as a one-sample t-test really. Here’s proof.
First we need to calculate the difference between the two measures
Then we can fit the one-sample t-test from above, with the mu set as 0 (because the null hypothesis is that there is no difference between the groups). Compare this result with the paired t-test above.
##
## One Sample t-test
##
## data: difference
## t = 17.98, df = 4, p-value = 5.625e-05
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 72.21262 98.58738
## sample estimates:
## mean of x
## 85.4
14.6 Two sample t-test
The two-sample t-test is used for comparing the means of two independent samples.
You can visualise this by picturing the uncertainty in each of the two estimated means (Figure 14.6) and thinking about their overlap. If they overlap a lot the difference between means is unlikely to be significant. If they don’t overlap very much then the difference between means is more likely to be significant. This is only a rough guide: the formal test is based on the standard error of the difference between the means (see below).
The underlying mathematical machinery for the two-sample t-test is similar to the one-sample and paired t-tests. Again, the important value is the t-statistic, which can be thought of as a measure of signal:noise ratio (see above). It is harder to detect a signal (the true difference between means) if there is a lot of noise (the variability, or spread of the distributions), or if the signal is small (the difference between means is small).
Figure 14.6: A two-sample t-test.
The mathematics involved with calculating the t-statistic is very similar to the one-sample t-test, except the numerator in the fraction is the difference between two means rather than between a mean and a fixed value. The denominator is the standard error of the difference between the two means, which combines the variability of both groups:
\[t = \frac{\bar{x}_1-\bar{x}_2} {\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}}\]
This is the same signal/noise idea as before. The signal is the difference between the two sample means (minus zero, the difference specified by the null hypothesis). The noise is the standard error of that difference, which combines the uncertainty in both means. This version of the formula, which allows the two groups to have different variances, is used by Welch’s t-test (see below).
So far so good… let’s push on and use R to do some statistics.
In this example, we can revisit the class data (a set of measurements such as height, hand width and reaction time, collected from students in previous years of this course) and ask the question, Is the reaction time of males different from that of females? The null hypothesis for this question is that there is no difference in mean reaction times between the two groups. The alternative hypothesis is that there is a difference in the mean reaction time between the two groups. Each student belongs to only one group, so the two groups are independent. Note that these are observational data from a convenience sample (one class), so we should be careful not to generalise too far, or to interpret any difference as being caused by sex.
Import the data in the usual way, and subset it to the right year (in the example below I am using 2019 data).
x <- read.csv("CourseData/classData.csv") %>%
filter(Year == 2019) %>%
filter(Gender %in% c("Male", "Female"))Then look at the data. Here I do this using a box plot with jittered points (a nice way of plotting data with small sample sizes) (Figure 14.7). From this figure, it looks like males have a faster reaction time than females, but there is a lot of variation. We need to apply the t-test in a similar way to above.
ggplot(x, aes(x = Gender, y = Reaction)) +
geom_boxplot() +
geom_jitter(col = "grey60", width = 0.2)
Figure 14.7: Reaction time of both sexes
##
## Welch Two Sample t-test
##
## data: Reaction by Gender
## t = 1.9655, df = 30.528, p-value = 0.05851
## alternative hypothesis: true difference in means between group Female and group Male is not equal to 0
## 95 percent confidence interval:
## -0.001716093 0.091311649
## sample estimates:
## mean in group Female mean in group Male
## 0.3483778 0.3035800
This output first tells us that we are using something called a “Welch Two Sample t-test”. This is a form of the two-sample t-test that relaxes the assumption that the variance in the two groups is the same. This is a good thing. Although it is possible to fit a t-test with equal variances, I recommend that you stick with the default Welch’s test and not make this limiting assumption.
Then we are told the t-statistic (1.965), the degrees of freedom (30.528) and the p-value (0.059). Because p > 0.05, we fail to reject the null hypothesis: there is no detectable difference between the two groups. We have not shown that males are faster than females. Equally, we have not shown that the two groups have the same mean: a non-significant result is not evidence of no difference.
The confidence interval helps here. The estimated difference (female - male) is 44.8 milliseconds, and the 95% confidence interval runs from -1.7 to 91.3 milliseconds. The interval includes zero (which is why the test is not significant), but it also includes differences of almost 0.1 seconds. The data are compatible with no difference, and also with a fairly large one. We could report this something like this:
“Females had a slightly slower mean reaction time than males (0.348 seconds compared to 0.304 seconds; difference = 44.8 ms, 95% CI -1.7 to 91.3 ms), but this difference was not statistically significant (Welch’s t-test: t = 1.965, d.f. = 30.528, p = 0.059).”
Note: With a t-test that did assume equal variances in the two groups, the d.f. is calculated as the total sample size (both groups combined) minus 2 (the number of groups). You can do this by adding the argument “var.equal = TRUE” to the t-test command. With the Welch test, the appropriate degrees of freedom are estimated by looking at the sample sizes and variances in the two groups. The details of this are beyond the scope of this course.
14.7 t-tests are linear models
It is also possible to formulate t-tests as linear models (using the lm function). To do this with the paired t-test you would specify a model that estimates an intercept. In R you can do this by writing the formula as x ~ 1. So, for the tool use example you can write the code like this:
##
## Call:
## lm(formula = difference ~ 1)
##
## Residuals:
## 1 2 3 4 5
## -5.4 16.6 4.6 -7.4 -8.4
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 85.40 4.75 17.98 5.62e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 10.62 on 4 degrees of freedom
If you look at the summary you will notice that the estimate of the intercept (the mean difference within pairs), the degrees of freedom, the t-value and the p-value are all the same as the values reported when using t.test.
In fact, all of the t-tests, and ANOVA (in a later chapter), are kinds of linear models and can be also fitted with lm.
Here is the two-sample t-test investigating gender differences in reaction time, fitted as a linear model. There is one important difference: an ordinary linear model assumes that the variance is the same in both groups. It is therefore equivalent to the equal-variance t-test (var.equal = TRUE), not to the Welch test we used above. You can see that the t-value and p-value for the GenderMale coefficient match the equal-variance t-test exactly (the sign of t is reversed because lm estimates male - female, while t.test estimates female - male), but they differ slightly from the Welch test.
## Analysis of Variance Table
##
## Response: Reaction
## Df Sum Sq Mean Sq F value Pr(>F)
## Gender 1 0.01642 0.0164196 3.6482 0.06542 .
## Residuals 31 0.13952 0.0045008
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call:
## lm(formula = Reaction ~ Gender, data = x)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.08938 -0.04558 -0.01258 0.03662 0.22542
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.34838 0.01581 22.03 <2e-16 ***
## GenderMale -0.04480 0.02345 -1.91 0.0654 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.06709 on 31 degrees of freedom
## Multiple R-squared: 0.1053, Adjusted R-squared: 0.07643
## F-statistic: 3.648 on 1 and 31 DF, p-value: 0.06542
##
## Two Sample t-test
##
## data: Reaction by Gender
## t = 1.91, df = 31, p-value = 0.06542
## alternative hypothesis: true difference in means between group Female and group Male is not equal to 0
## 95 percent confidence interval:
## -0.003037248 0.092632804
## sample estimates:
## mean in group Female mean in group Male
## 0.3483778 0.3035800
Try it: Randomisation Test Lab: same question, three tests (open the lab)
Use the “Same question, three tests” panel at the bottom of the lab.
- Compare the t-test and
lm()rows. Which numbers are identical, and why? - Give the two groups very different SDs and a small sample. When does the randomisation test start to disagree with the t-test?
- Switch to paired data: how does the paired t-test relate to
lm(change ~ 1)?
14.8 Exercise: Sex differences in fine motor skills
Some people have suggested that there might be sex differences in fine motor skills in humans. Use the data collected from students in previous years to address this topic using t-tests. The relevant data set is called classData.csv, and the columns of interest are Gender and Precision. The data contain several years, and a small number of students chose a Gender other than Female or Male; filter the data so that you are comparing two groups (and decide whether to use one year or all years).
Carry out a two-sample (Welch) t-test.
Plot the data (e.g. with a box plot, or histogram)
Formulate null and alternative hypotheses.
Use the
t.testfunction to do the test.Write a sentence or two describing the results.
14.9 Exercise: Therapy for anorexia
A study was carried out looking at the effect of cognitive behavioural therapy on weight of people with anorexia. Weight was measured in week 1 and again in week 8. Use a paired t-test to assess whether weight changed between week 1 and week 8 during the treatment. (Think about this: the study has no control group, so can a change in weight on its own tell you that the treatment caused it?)
The data are called anorexiaCBT.csv
The data are in “wide format”. You may wish to convert it to “long format” depending on how you use the data. You can do that with the pivot_longer function, which rearranges the data:
anorexiaCBT_long <- anorexiaCBT %>%
pivot_longer(
cols = starts_with("Week"), names_to = "time",
values_to = "weight"
)Plot the data (e.g. with an interaction plot).
Formulate a null and alternative hypothesis.
Use
t.testto conduct a paired t-test.Write a couple of sentences to report your result.
14.10 Exercise: Compare t-tests with randomisation tests (optional)
-
Try re-analysing some of the tests in this chapter as randomisation tests (or analyse the randomisation test data using
t.test). Do they give the same results? -
Try answering the question - “are people who prefer dogs taller than those who prefer cats?” using the
classData.csv. Can you think of any problems with this analysis?
A.M. Hurtado, K. Hill (1989). “Experimental Studies of Tool Efficiency Among Machiguenga Women and Implications for Root-Digging Foragers”, Journal of Anthropological Research, Vol.45,2,pp207-217.↩︎