Tutorials › Exam PA - Predictive Analytics › Writing Factor-By-Numeric Interactions in R

Exam PA · Categorical Encoding and Interactions · Tutorial 244 of 966

Writing Factor-By-Numeric Interactions in R

Use R formula syntax to fit a factor-by-numeric interaction, inspect its design columns, and calculate the fitted intercept and slope for each category.

Intermediate 13 min read

What You'll Learn

  • Write an R formula that includes a factor-by-numeric interaction.
  • Explain how treatment coding determines the generated model-matrix columns.
  • Identify the intercept, factor-indicator, numeric-predictor, and interaction columns.
  • Calculate category-specific intercepts and slopes from fitted coefficients.
  • Check a fitted value by substituting a category and numeric value into the model matrix.

From an R Formula to Category-Specific Lines

A factor-by-numeric interaction lets the fitted relationship between a numeric predictor and the response vary across categories. In a linear model, each category can have its own fitted intercept and slope. R writes this model compactly in a formula, but the coefficient table reports coefficients for the reference category and adjustments to it—not a separate intercept and slope for every category.

The task is to connect those pieces correctly: read the formula, identify the columns R constructs, and combine the coefficients for the category of interest. The calculations below use ordinary least squares with a quantitative response and an identity-scale linear mean. They assume treatment coding, an intercept, a numeric predictor entered in its stated units, and a full-rank model matrix. If different contrasts or a no-intercept formula are used, the coefficient meanings and columns can differ.

Definition: For a factor \(G\) with \(K\) categories and a numeric predictor \(x\), a factor-by-numeric interaction allows the fitted mean to have a different intercept and slope for each category. Under treatment coding with an intercept, one category is the reference. The model has an intercept, \(K-1\) factor-indicator columns, one numeric-predictor column, and \(K-1\) interaction columns.

In R, a formula such as response ~ group * x includes the main effects for group and x, as well as their interaction. With the default treatment contrasts, the first factor level is typically the reference level; the actual reference is determined by the factor’s levels and contrasts. For a factor with \(K\) levels, the treatment-coded factor and interaction each generate \(K-1\) columns.

The function model.matrix() returns one row per observation and columns for the model-matrix columns generated by the formula’s terms and contrasts, including the intercept when requested. The exact column names depend on the variable names and factor levels. Inspecting this matrix is a direct way to verify how R has encoded a model.

How to Read the Coefficients

Suppose the factor has reference category \(A\) and another category \(B\). Under treatment coding, the model can be written as:

$$ E[Y\mid x,G=A]=\beta_0+\beta_x x, \qquad E[Y\mid x,G=B]=(\beta_0+\beta_B)+(\beta_x+\beta_{Bx})x. $$

Here, \(\beta_0\) is the reference-category intercept, \(\beta_x\) is its slope, \(\beta_B\) is the adjustment to the intercept for category \(B\), and \(\beta_{Bx}\) is the adjustment to the slope for \(B\). For more than two categories, each non-reference category has its own indicator and interaction adjustment.

Key result: Under treatment coding with an intercept, the reference category’s intercept and slope are \(\beta_0\) and \(\beta_x\). For any non-reference category \(j\), they are \(\beta_0+\beta_j\) and \(\beta_x+\beta_{xj}\). The interaction coefficient is a slope adjustment, not that category’s entire slope.

Why the Coefficient Combinations Work

The combinations follow directly from substituting the model-matrix entries for each category. For the reference category, every treatment indicator is zero, so its interaction columns are also zero. For category \(j\), its indicator is one and its interaction column contains the observed value of \(x\). All other category indicators and interactions are zero.

$$ \begin{aligned} \widehat{Y}_{\text{reference}} &=1\cdot\hat{\beta}_0+0\cdot\hat{\beta}_j +x\cdot\hat{\beta}_x+0\cdot\hat{\beta}_{xj} =\hat{\beta}_0+\hat{\beta}_x x,\\ \widehat{Y}_{j} &=1\cdot\hat{\beta}_0+1\cdot\hat{\beta}_j +x\cdot\hat{\beta}_x+x\cdot\hat{\beta}_{xj}\\ &=(\hat{\beta}_0+\hat{\beta}_j) +(\hat{\beta}_x+\hat{\beta}_{xj})x. \end{aligned} $$

Thus, each non-reference category’s indicator adds to the intercept, and its interaction column adds a multiple of \(x\), changing the slope. This is a substitution into the fitted linear predictor; it does not require fitting a separate model for each category.

1
Check the variables.
Confirm the categorical predictor is a factor, the other predictor is numeric, and the numeric variable uses the units intended for interpretation.
2
Fit and inspect.
Fit the model with the factor-by-numeric interaction. Check the factor reference level and, if the column structure is unclear, inspect model.matrix().
3
Combine coefficients by category.
For the reference category, use the intercept and numeric coefficient. For each other category, add its factor coefficient to the intercept and its interaction coefficient to the numeric coefficient.
4
Verify with a row.
Construct the model-matrix row for a category and a chosen value of \(x\), then multiply its entries by the fitted coefficients and add the results.

Worked Examples

Worked Example: A Two-Level Factor and Operating Hours

A hypothetical repair team models service cost, measured in hundreds of dollars, using operating hours and machine type. The factor machine has levels Standard and Heavy, with Standard as the treatment reference. The numeric predictor hours is measured in hours. The analyst fits lm(cost ~ machine * hours, data = dat). Suppose the fitted coefficients are: intercept \(18\), machineHeavy \(5\), hours \(0.6\), and machineHeavy:hours \(-0.2\). Identify the generated columns, find each category’s intercept and slope, and calculate the fitted cost for a Heavy machine operated for 15 hours.

Method and assumptions. This is an ordinary least-squares model with treatment coding and an intercept. The formula includes the machine effect, the hours effect, and their interaction. With two factor levels, the columns are the intercept, machineHeavy, hours, and machineHeavy:hours.

Standard machines. The reference indicator and interaction are zero. The fitted intercept is \(18\) hundreds of dollars and the slope is \(0.6\) hundreds of dollars per hour.

Heavy machines. Add the machineHeavy coefficient to the intercept: \(18+5=23\) hundreds of dollars. Add the interaction coefficient to the hours coefficient: \(0.6+(-0.2)=0.4\) hundreds of dollars per hour.

Prediction at 15 hours. A Heavy machine has model-matrix row \((1,1,15,15)\), in the column order given above. The fitted value is \(18+5+(0.6)(15)+(-0.2)(15)=18+5+9-3=29\) hundreds of dollars, or \(\$2{,}900\).

Check. Using the Heavy-specific line gives \(23+(0.4)(15)=23+6=29\) hundreds of dollars, matching the model-matrix calculation. The common mistake avoided here is treating \(-0.2\) as the Heavy slope; it is the change from the Standard slope, so the Heavy slope is \(0.6-0.2=0.4\).

Worked Example: Three Delivery Routes

A hypothetical courier service models delivery time in minutes using distance in kilometres and a three-level factor route, whose levels are Local, Regional, and Express. Local is the treatment reference. The model is lm(minutes ~ route * distance, data = dat). Suppose the coefficient table gives an intercept of \(6.2\), routeRegional \(-1.1\), routeExpress \(2.0\), distance \(0.45\), routeRegional:distance \(0.08\), and routeExpress:distance \(-0.15\). Identify the columns, then find all category-specific intercepts and slopes and the fitted time for an Express delivery at 12 kilometres.

Method and columns. A three-level factor under treatment coding generates two indicator columns, one for Regional and one for Express. The model matrix also has an intercept, distance, and two interaction columns. In order, these columns are (Intercept), routeRegional, routeExpress, distance, routeRegional:distance, and routeExpress:distance.

Local. Local is the reference, so its intercept is \(6.2\) minutes and its slope is \(0.45\) minutes per kilometre.

Regional. Its intercept is \(6.2+(-1.1)=5.1\) minutes. Its slope is \(0.45+0.08=0.53\) minutes per kilometre.

Express. Its intercept is \(6.2+2.0=8.2\) minutes. Its slope is \(0.45+(-0.15)=0.30\) minutes per kilometre.

Express prediction at 12 kilometres. The model-matrix row is \((1,0,1,12,0,12)\). Substitution gives \(6.2+0+2.0+(0.45)(12)+0+(-0.15)(12)=8.2+5.4-1.8=11.8\) minutes.

Check. The Express-specific line gives \(8.2+(0.30)(12)=8.2+3.6=11.8\) minutes, as required. A common error is to use the Express indicator adjustment \(2.0\) as its full intercept or \(-0.15\) as its full slope; each is only an adjustment to the corresponding Local coefficient.

Worked Example: Confirming the Factor and Numeric Columns in R

A hypothetical equipment analyst models maintenance expense in hundreds of dollars. The factor grade has levels Basic and Reinforced, with Basic as the reference; load is numeric and measured in hundreds of kilograms. The fitted formula is lm(expense ~ grade * load, data = dat), with coefficient estimates: intercept \(42\), gradeReinforced \(-6\), load \(3.5\), and gradeReinforced:load \(1.2\). Calculate the fitted line for each grade and the prediction for a Reinforced unit carrying a load of 8 hundreds of kilograms.

Method and model-matrix check. First verify that grade is a factor and load is numeric; otherwise R may construct a different design. With treatment coding, the generated columns are (Intercept), gradeReinforced, load, and gradeReinforced:load. For a Reinforced unit at load 8, the row is \((1,1,8,8)\).

Basic line. Basic is the reference, so its intercept is \(42\) hundreds of dollars and its slope is \(3.5\) hundreds of dollars per 100 kilograms.

Reinforced line. Its intercept is \(42+(-6)=36\) hundreds of dollars. Its slope is \(3.5+1.2=4.7\) hundreds of dollars per 100 kilograms.

Prediction at load 8. The model-matrix calculation is \(42+(-6)+(3.5)(8)+(1.2)(8)=36+28+9.6=73.6\) hundreds of dollars, or \(\$7{,}360\).

Check. The Reinforced-specific line gives \(36+(4.7)(8)=36+37.6=73.6\) hundreds of dollars. Keeping the stated load unit matters: load 8 means 800 kilograms, not 8 kilograms.

Common Formula and Interpretation Traps

The R formula is compact, so it is easy to overlook the structure it requests. Before using a coefficient table, check that the formula includes the interaction and that the coefficient names correspond to the factor levels you expect. When column names are uncertain, inspect the factor levels and the model matrix rather than inferring the encoding from memory.

  • Omitting the interaction. A formula with only the factor and numeric main effects gives categories different intercepts but a shared numeric slope. It does not fit a separate slope by category.
  • Calling an interaction coefficient the category’s slope. With treatment coding, it is a slope adjustment. Add it to the numeric main-effect coefficient to obtain that category’s slope.
  • Using the wrong reference category. The intercept and numeric main-effect coefficient describe the reference level. Check the factor levels and contrasts before assigning meaning to coefficients.
  • Using the wrong units. A slope is expressed per unit of the numeric variable as entered in the data. If distance is recorded in kilometres, the slope is per kilometre.
  • Assuming every contrast has treatment-coded meanings. Different contrasts or a model without an intercept can produce different columns and coefficient interpretations. The combinations in this tutorial require the stated treatment-coding setup.

The point of translating the formula into columns is practical: it makes the coefficient table auditable. The reference-category row has zeroes in all factor and interaction columns. A non-reference category has a one in its indicator column and the observed numeric value in its corresponding interaction column. If those entries do not match the intended category and predictor value, the resulting fitted value will not represent the requested case.

Check Your Understanding

For each question, use treatment coding with an intercept unless stated otherwise. Identify the relevant columns before combining coefficients.

  1. A model uses lm(score ~ class * practice, data = dat), where class has levels Day and Evening, with Day as the reference. The estimates are intercept \(10\), classEvening \(3\), practice \(2\), and classEvening:practice \(-0.5\). Give each class’s intercept and slope, then calculate the Evening fitted score at practice \(4\). (Answer: Day intercept \(10\), slope \(2\); Evening intercept \(13\), slope \(1.5\); fitted score \(19\).)
  2. A factor zone has levels North, Central, and South, with North as reference. What factor and interaction columns are generated in a model with a numeric predictor age and an intercept? (Answer: zoneCentral, zoneSouth, age, zoneCentral:age, and zoneSouth:age, in addition to the intercept.)
  3. For the zone model in question 2, suppose the intercept is \(20\), zoneCentral is \(-4\), zoneSouth is \(3\), age is \(0.8\), zoneCentral:age is \(0.2\), and zoneSouth:age is \(-0.3\). Find the South intercept and slope, then its fitted response at age \(10\). (Answer: intercept \(23\), slope \(0.5\), fitted response \(28\).)
  4. A hypothetical model predicts repair cost in thousands of dollars from load in 50-kilogram units and a factor with Reference and Special levels. The fitted coefficients are intercept \(7\), Special \(-1\), load \(0.4\), and Special:load \(0.1\). Give the Special-specific intercept and slope, then predict at load \(6\). (Answer: intercept \(6\) thousand dollars, slope \(0.5\) thousand dollars per 50-kilogram unit, prediction \(9\) thousand dollars.)
  5. A two-level factor has Reference and Alternate levels. In the treatment-coded model, the numeric coefficient is \(1.2\) and the Alternate:numeric interaction coefficient is \(-0.4\). The Alternate indicator coefficient is \(2\). What is the Alternate slope, and what is its fitted value at numeric predictor \(5\) if the intercept is \(9\)? (Answer: slope \(0.8\); fitted value \(9+2+(1.2)(5)+(-0.4)(5)=15\).)
Clinical Biostats