# Significant differences among fit lines - ANCOVA not enough?

I often am in the situation of having data sets consisting of an independent variable, a dependent variable, and a factor with multiple levels - for instance, calibration curves for an instrument measured on different days. I would like to know whether the data are best described by a single fit line or by a different fit line for each factor level; i.e., whether the data are best described by a single calibration curve based on all of the data, or whether there are significant differences in the individual curves for each day.

From what I understand, ANCOVA will tell me separately whether the factor interacts with the slope and then whether it interacts with the intercept. What I want to know is whether the factor has a significant effect on the slope and the intercept of the line.

An example in R:

require(reshape)  # for melt()
#Set up some data
set.seed(0)
x <- seq(from=0, to=2, length.out=50)
y1 <- x + rnorm(length(x)) + 0.3
y2 <- 1.2*x + rnorm(length(x))

d <- data.frame(x=x, day1=y1, day2=y2)#, day3=y3, day4=y4)

dm <- melt(d, id.vars="x")

ggplot(dm, aes(x=x, y=value, colour=variable)) + geom_point() + geom_smooth(method="lm", se=T)


m <- lm(value ~ x*variable, data=dm)
summary(m)


Here, the effect of the factor and the interaction of the factor with the independent variable are each marginally significant - at alpha = 0.05 we would fail to reject the hypothesis that the factor has an effect on slope or intercept. However, taken together, perhaps they matter. Is there a good way to assess this?

-
Thank you, thank you, THANK YOU for including reproducible code! –  Stephan Kolassa Jan 17 '13 at 16:17

What you need is model simplification. You can use stepwise deletion method, which removes term by term, starting from the interactions of highest order. Or you can compare AIC of all possible models and select the model with lowest AIC. This is the easiest approach in this case.

m1 <- lm(value ~ x*variable, data=dm)    # your original model
m2 <- lm(value ~ 0 + variable + x:variable, data=dm) # the same model, parametrized
# in more sane way - shows the coefficients you used for computation

m3 <- lm(value ~ 0 + variable + x, data=dm) # simplification - global slope
m4 <- lm(value ~ x, data=dm)   # further simplification - global intercept
m5 <- lm(value ~ variable, data=dm) # another variant - no slope, only categories


Let's compare AIC:

> AIC(m1)
[1] 265.857
> AIC(m2)
[1] 265.857
> AIC(m3)
[1] 267.6916
> AIC(m4)
[1] 266.0254
> AIC(m5)
[1] 313.5748


This shows that the first model is the best one - so you actually cannot use global slope and global intercept, you should use per-category slope and intercept.

-
+1 for choosing models using AIC (an extremely good background monograph on AIC is this: springer.com/statistics/statistical+theory+and+methods/book/…). However, beware of stepwise procedures. They are fine if your end goal is prediction for new data, but they cannot be used if the end goal is inference (since they filter for p values, the p values for the final model will be too small, since the filtering invalidates the assumptions on calculating those p values). –  Stephan Kolassa Jan 18 '13 at 8:28
@StephanKolassa, thanks for your comment, but I don't get the note about stepwise procedures. What do you mean with filtering? "... p values for the final model will be too small" - you mean too big? Because by simplification the p-values (of parameters and whole regression) will usualy grow, as the model will fit less.. –  Curious Jan 18 '13 at 9:43
Stepwise procedures usually remove "insignificant" predictors or add "significant" predictors by checking p-values; this is what I meant by "filtering". So if you determine your model by removing everything where the p value is large, you will artificially bias the p values of the remaining terms downward. See stata.com/support/faqs/statistics/stepwise-regression-problems as well as onlinelibrary.wiley.com/doi/10.1111/j.1365-2656.2006.01141.x/… –  Stephan Kolassa Jan 18 '13 at 9:50
@StephanKolassa, "biasing p-values" is a new concept to me. Biasing compared to what? There is no "true p-value" as far as I know, or is it? We usualy want to see most parsimonious model and look what's significant, that's all. –  Curious Jan 18 '13 at 9:56
The distributional assumptions underlying the calculation of p-values include "no model selection based on the data". Therefore, only the original model really fulfills those assumptions. (However, it may not fulfill normality requirements, which in turn we only can assess by looking at the data... which is part of why NHST is problematic.) –  Stephan Kolassa Jan 18 '13 at 11:32

It may depend on what "matters" means to you. However, we can say that a model containing the factor and its interaction with the covariate explains significantly more variation than a model containing the covariate alone:

anova(update(m,.~variable),m)

Analysis of Variance Table

Model 1: value ~ variable
Model 2: value ~ x * variable
Res.Df     RSS Df Sum of Sq     F    Pr(>F)
1     98 126.854
2     96  75.631  2    51.224 32.51 1.655e-11 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1


So, taken together, the factor and the covariate indeed seem to make a difference.

-
So should my general approach be to compare the model with the factor to the model without the factor, to see whether the former explains significantly more variance than the latter? (Also: is there an name for this process of comparing two models?) –  Drew Steen Jan 17 '13 at 16:17
It may make sense to just throw the variable out and compare the model with the factor only to the model without anything. It makes little sense to, e.g., compare the model with the interaction to a model with the interaction but without the main effect from the factor. As I wrote, it depends on what "matters" means to you. You may want to look at AIC or cross-validation to compare models (which I would simply call "comparing models" ;-). –  Stephan Kolassa Jan 17 '13 at 16:23
@DrewSteen Maybe I misunderstand your question but I would try Stephan's approache with Model 1: value ~ x instead of Model 1: value ~ variable –  Stéphane Laurent Jan 17 '13 at 21:32