Selection differentials and gradients in R

evolutionary ecology
quantitative genetics
natural selection
R
ecology tutorial
Measure natural selection on correlated traits in R: the differential captures total selection, the gradient isolates direct selection by regression.
Author

Tidy Ecology

Published

2026-08-04

A field biologist who measures survival or reproduction against a trait faces a quiet problem: traits travel in groups. Body size correlates with growth rate, which correlates with timing, which correlates with condition. If bigger animals leave more offspring, is size itself the target, or is size just a passenger on some other trait that selection actually favours? The answer separates two quantities that beginners often blur together: the selection differential and the selection gradient.

This post builds both from a simulated population, all in base R, and shows the matrix identity that connects them. It is the measurement half of evolutionary quantitative genetics; the breeder’s equation is the prediction half.

Total selection: the differential

The selection differential S for a trait is the covariance between the trait and relative fitness (absolute fitness divided by its mean). Equivalently, it is the change in the trait mean within a generation, before reproduction copies it forward. It counts all the selection a trait experiences, direct plus whatever it inherits through correlations with other selected traits.

Here is a population of 3000 individuals with two standardised traits, z1 and z2, correlated at 0.6. Fitness, the number of offspring, depends on z2 alone. Trait z1 has no causal effect on fitness whatsoever.

set.seed(431)
n   <- 3000
rho <- 0.6
z2 <- rnorm(n)
z1 <- rho * z2 + sqrt(1 - rho^2) * rnorm(n)   # cor(z1, z2) = 0.6, both ~ N(0, 1)
W  <- rpois(n, exp(0.30 + 0.35 * z2))          # offspring: driven by z2 only
w  <- W / mean(W)                              # relative fitness

S1 <- cov(z1, w)
S2 <- cov(z2, w)
cat(sprintf("S1 = %.3f   S2 = %.3f   S1/S2 = %.3f\n", S1, S2, S1 / S2))
S1 = 0.211   S2 = 0.352   S1/S2 = 0.599

Trait z2 has a differential of 0.352, as expected. But z1 also shows a positive differential, 0.211, even though it does nothing. The ratio of the two differentials, 0.599, is almost exactly the trait correlation of 0.6. That is the signature of indirect selection: z1 looks selected only because it rides along with z2. A differential, on its own, cannot tell a target apart from a passenger.

Direct selection: the gradient

The selection gradient beta fixes this. It is the vector of partial regression coefficients from regressing relative fitness on all the traits at once. Because multiple regression holds the other traits constant, each gradient measures the selection acting directly on its trait, with indirect paths removed.

m    <- lm(w ~ z1 + z2)
beta <- coef(m)[c("z1", "z2")]
round(summary(m)$coefficients, 3)
            Estimate Std. Error t value Pr(>|t|)
(Intercept)    1.000      0.015  64.958    0.000
z1             0.001      0.019   0.058    0.954
z2             0.350      0.019  18.304    0.000

The gradient for z2 is 0.350, matching its differential because z2 is the real target. The gradient for z1 is 0.001 with a p-value of 0.954: once z2 is in the model, z1 explains nothing. The regression has stripped away the borrowed selection and left the truth. This is the core move of Lande and Arnold (1983): the differential describes what happened to each trait, the gradient describes why.

An honest limit

Both quantities are phenotypic and descriptive. The gradient isolates direct selection only among the traits you actually measured. If some unmeasured trait causes fitness and correlates with z1, it re-enters the gradient as if z1 were the cause, exactly the omitted-variable problem of any regression (see collinearity and VIF for the standard-error side of this). A selection gradient is the best linear description of who dies and who breeds; turning it into a statement about adaptation still needs the trait to be heritable and the analysis to be honest about what was left out. That heritability step is where the breeder’s equation comes in, and the checking post walks through the assumptions that can quietly break a gradient analysis.

References

Lande R, Arnold SJ 1983. Evolution 37(6):1210-1226 (10.1111/j.1558-5646.1983.tb00236.x)

Mitchell-Olds T, Shaw RG 1987. Evolution 41(6):1149-1161 (10.1111/j.1558-5646.1987.tb02457.x)

Falconer DS, Mackay TFC 1996. Introduction to Quantitative Genetics, 4th ed. Longman. ISBN 978-0582243026

Newsletter

Get new tutorials by email

New R and QGIS tutorials for ecologists, straight to your inbox. No spam; unsubscribe anytime.

By subscribing you agree to receive these emails and confirm your address once. See the privacy policy.