How to unscale the coefficients from an lmer()-model fitted with a scaled response
Asked Answered
B

1

10

I fitted a model in R with the lmer()-function from the lme4 package. I scaled the dependent variable:

    mod <- lmer(scale(Y)
                ~ X
                + (X | Z),
                data = df,
                REML = FALSE)

I look at the fixed-effect coefficients with fixef(mod):

    > fixef(mod)
    (Intercept)      X1          X2         X3           X4 
     0.08577525 -0.16450047 -0.15040043 -0.25380073  0.02350007

It is quite easy to calculate the means by hand from the fixed-effects coefficients. However, I want them to be unscaled and I am unsure how to do this exactly. I am aware that scaling means substracting the mean from every Y and deviding by the standard deviation. But both, mean and standard deviation, were calculated from the original data. Can I simply reverse this process after I fitted an lmer()-model by using the mean and standard deviation of the original data?

Thanks for any help!


Update: The way I presented the model above seems to imply that the dependent variable is scaled by taking the mean over all responses and dividing by the standard deviation of all the responses. Usually, it is done differently. Rather than taking the overall mean and standard deviation the responses are standardized per subject by using the mean and standard deviation of the responses of that subject. (This is odd in an lmer() I think as the random intercept should take care of that... Not to mention the fact that we are talking about calculating means on an ordinal scale...) The problem however stays the same: Once I fitted such a model, is there a clean way to rescale the coefficients of the fitted model?

Bradytelic answered 13/5, 2014 at 21:43 Comment(2)
I'm not sure there is a simple way to "un-scale" the latter procedure (i.e. scaling each subject separately) -- this really feels like a different model to me ... I'm also not entirely sure why you would want to ...Expostulation
I suspected this. No matter how I wrote the model down I didn’t come up with a reasonable way to rescale. I quite agree with this procedure being odd. But it can be found in some papers. I don’t get why you would combinde standardizing the response per subject and allowing random intercepts. That seems like two things solving the same problem; maybe even underestimating proper individual differences. But thanks so much for trying to come up with an answer!Bradytelic
E
12

Updated: generalized to allow for scaling of the response as well as the predictors.

Here's a fairly crude implementation.

If our original (unscaled) regression is

Y = b0 + b1*x1 + b2*x2 ... 

Then our scaled regression is

(Y0-mu0)/s0 = b0' + (b1'*(1/s1*(x1-mu1))) + b2'*(1/s2*(x2-mu2))+ ...

This is equivalent to

Y0 = mu0 + s0((b0'-b1'/s1*mu1-b2'/s2*mu2 + ...) + b1'/s1*x1 + b2'/s2*x2 + ...)

So bi = s0*bi'/si for i>0 and

b0 = s0*b0'+mu0-sum(bi*mui)

Implement this:

 rescale.coefs <- function(beta,mu,sigma) {
    beta2 <- beta ## inherit names etc.
    beta2[-1] <- sigma[1]*beta[-1]/sigma[-1]
    beta2[1]  <- sigma[1]*beta[1]+mu[1]-sum(beta2[-1]*mu[-1])
    beta2
 }

Try it out for a linear model:

m1 <- lm(Illiteracy~.,as.data.frame(state.x77))
b1 <- coef(m1)

Make a scaled version of the data:

ss <- scale(state.x77)

Scaled coefficients:

m1S <- update(m1,data=as.data.frame(ss))
b1S <- coef(m1S)

Now try out rescaling:

icol <- which(colnames(state.x77)=="Illiteracy")
p.order <- c(icol,(1:ncol(state.x77))[-icol])
m <- colMeans(state.x77)[p.order]
s <- apply(state.x77,2,sd)[p.order]
all.equal(b1,rescale.coefs(b1S,m,s))  ## TRUE

This assumes that both the response and the predictors are scaled.

  • If you scale only the response and not the predictors, then you should submit (c(mean(response),rep(0,...)) for m and c(sd(response),rep(1,...)) for s (i.e., m and s are the values by which the variables were shifted and scaled).
  • If you scale only the predictors and not the response, then submit c(0,mean(predictors)) for m and c(1,sd(predictors)) for s.
Expostulation answered 14/5, 2014 at 0:25 Comment(4)
You seem to have scaled the independent variables icol <- which(colnames(state.x77)=="Illiteracy"), ss <- state.x77, ss[,-icol] <- scale(ss[,-icol]). But I scaled the dependent variable in the design. So what I have done using the state.x77 data is: m1Sy <- lm(scale(Illiteracy)~.,as.data.frame(state.x77)). Now I get z-transformed coefficients in the model output and I want to reverse this to plot the means on the original scale. But maybe I am misinterpreting your solution.Bradytelic
And in case some background is helpful: There seems to be a strong tendency to scale ordinal responses and fit an lmer() on it in certain disciplines. Not just that I doubt that this is justified (ordinal variable) but I find myself asking how they get back the original scale, e.g. when plotting the mean (rating) and error bars. Strongly related: lmer() vs clmm() with ordinal responseBradytelic
oops, answered the wrong question -- will come back to this.Expostulation
Thank you so much! I really appreciate this. I’ve just recognized an imprecision on my end: Of course I mean scaling the response variable by VP. So, imagine that I have a rating scale 1 to 5 and I expect that some VPs have a strong tendency to just use extreme values and I want to correct for that. Then I could take the mean response (I know, horrible for an ordinal scale...!) and the standard deviation per subject and standardize the responses per subject. Which seems to be pointless in an lmer() given the random intercepts.(?) I should update my question to reflect that.Bradytelic

© 2022 - 2024 — McMap. All rights reserved.