rinterceptcontrastemmeans

Failed to contrast intercepts through emmeans in R


I would like to test the simetry in the response of an observer to a contrast stimuli with different polarity, positive (white) and negative (black). I took the reaction time (RT) as dependent variable, along four different contrasts. It is known that the response time follows a Pieron curve whose asymptotas are placed (1) at observer threshold (Inf) and (2) at a base RT placed somewere between 250 and 450 msec. The knowledge allows us to linearize the relationship transforming the independent variable (effective contrast EC) as 1/EC^2 (tEC), so the equation linking RT to EC becomes:

RT = m * tEC + RT0

To test the symmetry I established the criteria: same slope and same intercept in the two polarities implies symmetry. To obtain the coefficients I made a linear model with interaction (coding trough a dummy variable for Polarity: Positive or Negative). The output of lm is clear to me, but some colegues prefer somthing more similar to an ANOVA output. So I decided to use emmeans to make the contrasts. With the slope is all right, but when computing the interceps starts the problem. The intercepts computed by lm are very different from the output of emmeans, and the conclusions are also different. In what follows I reproduce the example. The question is two fold: It is possible to use emmeans to solve my problem? If not, it is possible to make the contrasts through other packages (which one)?

Data

RT1000 EC tEC Polarity
596.3564 -25 0.001600 Negative
648.2471 -20 0.002500 Negative
770.7602 -17 0.003460 Negative
831.2971 -15 0.004444 Negative
1311.3331 15 0.004444 Positive
1173.8942 17 0.003460 Positive
1113.7240 20 0.002500 Positive
869.3635 25 0.001600 Positive

Code

# Model
model <- lm(RT1000 ~ tEC * Polarity, data = Data)

# emmeans
library(emmeans)
# Slopes
m.slopes <- lstrends(model, "Polarity", var="tEC")
# Intercepts
m.intercept <- lsmeans(model, "Polarity")

# Contrasts
pairs(m.slopes)
pairs(m.intercept)

Outputs

Modelo
term estimate std.error statistic p.value
(Intercept) 449.948 66.829 6.733 0.003
tEC 87205.179 20992.976 4.154 0.014
PolarityPositive 230.946 94.511 2.444 0.071
tEC:PolarityPositive 58133.172 29688.551 1.958 0.122
Slopes (it is all right)
Polarity tEC.trend SE df lower.CL upper.CL
Negative 87205.18 20992.98 4 28919.33 145491.0
Positive 145338.35 20992.98 4 87052.51 203624.2
contrast estimate SE df t.ratio p.value
Negative - Positive -58133.17 29688.55 4 -1.958101 0.12182
Intercepts (problem)
Polarity lsmean SE df lower.CL upper.CL
Negative 711.6652 22.2867 4 649.7874 773.543
Positive 1117.0787 22.2867 4 1055.2009 1178.957
contrast estimate SE df t.ratio p.value
Negative - Positive -405.4135 31.51816 4 -12.86285 0.000211

Computed intercepts through emmeans differs from the ones computed by lm. I think the problem is that the model is not defined for EC = 0. But I'm not sure.


Solution

  • What you are calling the intercepts are not; they are the model predictions at the mean value of tEC. If you want the intercepts, use instead:

    m.intercept <- lsmeans(model, "Polarity", at = list(tEC = 0))
    

    You can tell what reference levels are being used via

    ref_grid(model)     # or   str(m.intercept)
    

    Please note that the model fitted here consists of two lines with different slopes; hence the difference between the predictions changes depending on the value of tEC. Thus, I would strongly recommend against testing the comparison of the intercepts; those are predictions at a tEC value that, as you say, can't even occur. Instead, try to be less of a mathematician and do the comparisons at a few representative values of tEC, e.g.,

    LSMs <- lsmeans(model, "Polarity", at = list(tEC = c(0.001, 0.003, 0.005)))
    pairs(LSMs, by = tEC)
    

    You can also easily visualize the fitted lines:

    emmip(model, Polarity ~ tEC, cov.reduce = range)