I am comparing different traits within the plant populations and looking for sex differences across ages. A trivial example is outlined below. Male plants are in blue, female plants in red. x-axis has age in days and y-axis has height of the plants. If I want to test for significant height difference across age between the two sexes can I just use a t-test to do so? And will this still be valid if the height change with age is exponential and the ages in my dataset are not particularly normal? And is there a good way to do this with python?

enter image description here


1 Answer 1



For the “no”, the usual t-test would just test if mean height or mean age differs between the two groups. This is not what you want.

For the “yes”…

I would analyze this using a regression. The outcome ($y$) would be the height, and the features ($X$) would be age, the group corresponding to the colors, and the interaction between them. The interaction tells you the difference in slope between the two groups: that is, the difference in how age affects height, which sound like the exact information you want.

$$ y=\beta_0+\beta_1x_{age} +\beta_2x_{group}+\beta_3x_{age}x_{group}+\epsilon $$

You would use categorical encoding for the $x_{group}$ variable, where you code one group as $0$ and the other group as $1$.

A common way to test this would be to fit a linear regression using ordinary least squares and test if the coefficient on the interaction feature is nonzero. This would be a t-test, with a more general definition of the t-test.

A good test of this in Python comes from the summary of a linear model in the statsmodels package, where you will get the p-value of each coefficient, including the interaction term of interest.

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
N = 50
x_age = np.random.uniform(0, 100, N)
x_group = np.random.binomial(1, 0.5, N)
e = np.random.normal(0, 1, N) # epsilon error term
y = x_age + x_group + 0.2*x_age*x_group + e
d = pd.DataFrame()
d["age"] = x_age
d["group"] = x_group
d["height"] = y
smf.ols("height ~ age + group + age*group", data = d).fit().summary()

I get a tiny p-value on the interaction term, and a plot is consistent with the notion of different slopes for the two groups.

import matplotlib.pyplot as plt
plt.scatter(x_age[x_group == 1], y[x_group == 1])
plt.scatter(x_age[x_group != 1], y[x_group != 1])

enter image description here

  • $\begingroup$ This is an excellent explanation! Just to clarify one piece, the small p-value you reference is the Prob(F)? And because OLS is run on all the data, the low Prob(F) tells us that there is a small probability that all of the data follows the regression. Is that correct? $\endgroup$ Commented Jan 12, 2023 at 16:34
  • $\begingroup$ @TheNightman That is for a test for the whole regression, so if the age variable has a major effect on the height (makes sense to me), such a p-value could be quite low no matter how the interaction term influences the height. For testing just the interaction, you want the P>|t| value for the age:group interaction. Some statsmodels documentation somewhere should explain what everything in the summary means. $\endgroup$
    – Dave
    Commented Jan 12, 2023 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.