When none of the predictors are standardized and 0 is not a meaningful value on a predictor, interpretation of the regression coefficients can become awkward. For instance, in the model with none of the predictors standardized, the coefficient for female – .348 – states that women score .348 points higher in terms of happiness than men among those who are 0 years old. The coefficient for age – -.004 – indicates that with every additional year, men's happiness decreases by .004 points. The coefficient for the interaction term – -.008 – denotes that women's happiness decrease more than men's with each additional year of age. The intercept is the average happiness of men who are 0 years old.
A first step towards giving the coefficients from an interaction model an easier interpretation is to standardize continuous variables. For the second model shown in the Table, age was standardized by subtracting its mean and dividing it by its standard deviation. Thus, for the standardized variable, the value of 0 refers to the average age, and a change of 1 refers to a change of one standard deviation. The age coefficient (-.07) now indicates that for every additional standard deviation of age, men's happiness decreases by .07. For men and women of average age, the happiness differential is .02. Women's happiness decreases by .15 per standard deviation of age stronger than men's. The intercept shows the average happiness of average-age men.
While it is a rather controversial technique, it is in principle also possible to standardize the dummy variable indicating the difference between men and women. Then, the intercept is the overall mean of happiness. However, an increase of 1 in the gender coefficient becomes difficult to interpret, as there is no such thing as a one-standard deviation increase in gender. When the dummy variable is approximately evenly distributed, then the coefficient reflects half of the difference in the outcome between the two groups.
Gelman and Hill (2007, p. 56) suggest to standardize variables by two rather than one standard deviation to keep binary and continuous variables on a roughly common scale. An increase of one in age then refers to the difference between one standard deviation below the mean and one standard deviation above the mean; an increase of one in age reflects roughly the difference between men and women.
As the plot above shows, none of these different scaling decisions affect the form of the interaction.
Reference
Gelman, Andrew, and Jennifer Hill. 2007. Data Analysis Using Regression and Multilevel/Hierarchical Models. Cambridge University Press.use agea gndr happy using ESS1e06.3_F1.dta, clear
// Set up variables
rename agea age
recode gndr (1 = 0) (2 = 1) (.a = .), gen(female)
label var female "Female sex (ref. male)"
label var age "Age"
label var happy "Happiness"
// Listwise deletion
drop if missing(female, age, happy)
// Standardize variables
qui sum female
gen female_1z = (female - r(mean)) / r(sd)
gen female_2z = (female - r(mean)) / (2*r(sd))
qui sum age
gen age_1z = (age - r(mean)) / r(sd)
gen age_2z = (age - r(mean)) / (2*r(sd))
// Fit models
reg happy c.age##female
estimates store unstandardized
reg happy c.age_1z##female
estimates store cont_standardized
reg happy c.age_1z##c.female_1z
estimates store standardized_1z
reg happy c.age_2z##c.female_2z
estimates store standardized_2z
// Create table
esttab unstandardized cont_standardized standardized_1z standardized_2z, ///
rename(age_1z age ///
age_2z age ///
female_1z 1.female ///
female_2z 1.female ///
c.age_1z#c.female_1z 1.female#c.age ///
c.age_2z#c.female_2z 1.female#c.age ///
1.female#c.age_1z 1.female#c.age) ///
drop(0b.female 0b.female#co.age 0b.female#co.age_1z) ///
coeflabel(age "Age" ///
1.female "Female (ref. male)" ///
1.female#c.age "Age X Female" ///
_cons "Intercept") ///
mtitles("Unstandardized" "Age standardized (1 SD)" ///
"Standardized (1 SD)" "Standardized (2 SD)") ///
nonumbers varwidth(18) modelwidth(24) ///
se r2 obslast
// Plot models
estimates restore unstandardized
qui sum age
local age_minsd = r(mean) - r(sd)
local age_mean = r(mean)
local age_plusd = r(mean) + r(sd)
qui margins, at(c.age = (`age_minsd' `age_mean' `age_plusd') ///
female = (0 1)) vsquish
qui marginsplot, recastci(rarea) ciopts(color(gs12)) ///
xlabel(`age_minsd' "-1 SD" `age_mean' "Average age" `age_plusd' "+1 SD") ///
title("Unstandardized variables", size(*.9)) ///
ytitle("Predicted happiness") ///
xtitle("") ///
plotopts(msymbol(none)) /// // Turn off markers
plot1opts(lpattern(dash)) /// // Define line types here
plot2opts(lpattern(solid)) ///
legend(subtitle(Gender, size(*.8)) ///
order(3 "Males" 4 "Females") ring(0) pos(7) ///
size(*.8) symysize(*.7) symxsize(*.7)) ///
name(unstandardized, replace)
estimates restore cont_standardized
qui margins, at(c.age_1z = (-1 0 1) ///
female = (0 1)) vsquish
qui marginsplot, recastci(rarea) ciopts(color(gs12)) ///
xlabel(-1 "-1 SD" 0 "Average age" 1 "+1 SD") ///
title("Age standardized at 1 SD", size(*.9)) ///
ytitle("Predicted happiness") ///
xtitle("") ///
plotopts(msymbol(none)) /// // Turn off markers
plot1opts(lpattern(dash)) /// // Define line types here
plot2opts(lpattern(solid)) ///
legend(subtitle(Gender, size(*.8)) ///
order(3 "Males" 4 "Females") ring(0) pos(7) ///
size(*.8) symysize(*.7) symxsize(*.7)) ///
name(cont_standardized, replace)
estimates restore standardized_1z
qui sum female
local fem_hi = (1 - r(mean)) / r(sd)
local fem_lo = (0 - r(mean)) / r(sd)
qui margins, at(c.age_1z = (-1 0 1) ///
c.female_1z = (`fem_lo' `fem_hi')) vsquish
qui marginsplot, recastci(rarea) ciopts(color(gs12)) ///
xlabel(-1 "-1 SD" 0 "Average age" 1 "+1 SD") ///
title("All variables standardized at 1 SD", size(*.9)) ///
ytitle("Predicted happiness") ///
xtitle("") ///
plotopts(msymbol(none)) /// // Turn off markers
plot1opts(lpattern(dash)) /// // Define line types here
plot2opts(lpattern(solid)) ///
legend(subtitle(Gender, size(*.8)) ///
order(3 "Males" 4 "Females") ring(0) pos(7) ///
size(*.8) symysize(*.7) symxsize(*.7)) ///
name(standardized_1z, replace)
estimates restore standardized_2z
qui sum female
local fem_hi = (1 - r(mean)) / (2*r(sd))
local fem_lo = (0 - r(mean)) / (2*r(sd))
qui margins, at(c.age_2z = (-.5 0 .5) ///
c.female_2z = (`fem_lo' `fem_hi')) vsquish
qui marginsplot, recastci(rarea) ciopts(color(gs12)) ///
xlabel(-.5 "-1 SD" 0 "Average age" .5 "+1 SD") ///
title("All variables standardized at 2 SD", size(*.9)) ///
ytitle("Predicted happiness") ///
xtitle("") ///
plotopts(msymbol(none)) /// // Turn off markers
plot1opts(lpattern(dash)) /// // Define line types here
plot2opts(lpattern(solid)) ///
legend(subtitle(Gender, size(*.8)) ///
order(3 "Males" 4 "Females") ring(0) pos(7) ///
size(*.8) symysize(*.7) symxsize(*.7)) ///
name(standardized_2z, replace)
graph combine unstandardized cont_standardized standardized_1z standardized_2z, ///
row(2) col(2) ysize(7) name(combined, replace)

