One can test this by hand-coding it in R and comparing to the package. First, I'll use the iris
data by fitting a model with lmer
and plotting with the effects
package. For simplicity I just include two fixed effects and a random intercept for species.
#### Load Library ####
library(lmerTest)
library(effects)
#### Fit Model ####
fit <- lmer(
Sepal.Length
~ Sepal.Width
+ Petal.Width
+ (1|Species),
data=iris
)
#### Quick Plot ####
est <- predictorEffect("Sepal.Width", fit)
plot(est)
This gives the following plot:
We could just plot the model using the fixed intercept and slope directly from the saved summary(fit)
:
#### Get Fixed Intercept and Slope ####
s <- summary(fit)
a <- s$coefficients[1]
b <- s$coefficients[2]
se <- s$coefficients[2,2]
#### Plot Main Effect ####
plot(iris$Sepal.Width, # predictor
iris$Sepal.Length, # response
main="Sepal Dimensions",
xlab="Width",
ylab="Length") # labels
#### Add Rug ####
rug(jitter(iris$Sepal.Width))
#### Plot Regression Line with SE ####
abline(
a,b, # intercept/slope
col="red", # color of line
lwd=3 # size of line
)
But this doesn't look close at all to the plot we just looked at, as the intercept is at a much lower location:
Instead, we can just code the predictions ourselves, setting the predictor of interest to an arbitrary range of values between its minimum and maximum, then set the other predictor to its mean, and then get predictions from this data. Note that unless you specify re.form = NA
, the predict
function will force you to also include the random effects, which is only useful if you want by-species predictions:
#### Get Prediction Data ####
newdata <- data.frame(
Sepal.Width = seq(
min(iris$Sepal.Width),
max(iris$Sepal.Width),
length.out=200
),
Petal.Width = mean(iris$Petal.Width)
)
pred <- predict(
fit,
newdata=newdata,
re.form=NA,
se.fit=T
)
From there we plot again and now use the lines from the predictions we created:
#### Plot Again ####
plot(iris$Sepal.Width, # predictor
iris$Sepal.Length, # response
main="Sepal Dimensions",
xlab="Width",
ylab="Length") # labels
#### Add Rug Again ####
rug(jitter(iris$Sepal.Width))
#### Add Predictions ####
lines(newdata$Sepal.Width,
pred,
lwd=3,
col="darkred")
Now our plot matches that from the effects
package, as the intercept is now above 5:
So in short to answer your questions:
- It appears that the plot from the
effects
package indeed sets the other predictors to their mean values by default, then generates a line based off that fitting.
- It does this by "toggling off" the random effects, otherwise it would draw a line for each random intercept.
- The correlation between $X$ and $Y$ here is not captured by this relationship, so I'm not sure where you got the $r = -.40$ from. The coefficient isn't the correlation and is a partial effect (the effect after controlling for the other predictors).