# Predicted lm() means of log-transformed and untransformed data not equal

Why is the back-transformation of the predicted values so different from the observed when the observed are log-transformed?

Sample data:

trt=c("a","a","a","a","a","a","a","b","b","b","b","b","b","b","c","c","c","c","c","c","c")
resp=c(1,2,3,1,2,3,1,10,20,30,10,20,30,10,100,200,300,100,200,300,100)
resp=(log(resp))
observed=cbind(by(resp,trt,mean))
colnames(observed)="obs"
data1=data.frame(trt,resp)


Models: log.transformed and untransformed

model.nolog=lm(resp~trt,data=data1)
model.log=lm(log(resp)~trt,data=data1)


Predicted means

library(predictmeans)
compare=cbind(observed,"est.nolog"=estimated.nolog,"est.log"=estimated.log)
options(digits=2)
> compare
obs est.nolog est.log
a 0.51      0.51     1.7
b 2.81      2.81    16.7
c 5.12      5.12   166.9

• I made a mistake. Need to remove "resp=(log(resp))" and run the code. The outcome at the bottom will then show the problem I am refering to.
– Cesar Gemeno
Dec 11, 2014 at 16:40
• You are modeling very different things in both cases. This seems like you generally aren't sure how simple linear regression works which might be a better question for Cross Validated. Right now, this does not appear to be a specific programming question, your confusion comes from not understanding the math of the regression.
– MrFlick
Dec 11, 2014 at 16:50
• I am very confused by the output you show because you have the statement resp=(log(resp)) before you make the data frame, but the results of your fitted models don't jibe with this, and seem to be reversed from what they should be. I suggest typing all the statements again and recomputing, because what you're showing cannot have been produced by the statements shown-- at least in the order shown. Dec 12, 2014 at 1:59
• If what you're trying to get at is the difference between these two columns: i=c(1,8,15); data.frame(orig=fitted(lm(resp~trt))[i], explog=exp(fitted(lm(log(resp)~trt))[i])) then you should make that explicit in your question. You need to fix your code and ask a clear question. Dec 12, 2014 at 3:06

My answer is you got mixed-up somewhere in the chain of calculations.

> trt = c("a","a","a","a","a","a","a",
"b","b","b","b","b","b","b",
"c","c","c","c","c","c","c")
> resp = c(1,2,3,1,2,3,1,
10,20,30,10,20,30,10,
100,200,300,100,200,300,100)

> model.nolog = lm(resp ~ trt)
> predict(model.nolog, newdata = data.frame(trt=c("a","b","c")))
1          2          3
1.857143  18.571429 185.714286

> model.log = lm(log(resp) ~ trt)
> exp(predict(model.log, newdata = data.frame(trt=c("a","b","c"))))
1         2         3
1.66851  16.68510 166.85104


The results differ because the transformation is nonlinear. But not by as much as you indicated.

• My appologies for sending a mistake in the code. rvl got it right though (thanks) so perhaps it is not necessary to resubmit the question. The predicted from model.nolog are identical to the observed. The predicted from model.log are off by 11%. This is a lot. I think Dec 12, 2014 at 11:55
• rvl: I think you are right about the nonlinear relation between log and exp: backtransforming a log does not have to be the same as the original. However this is a counterintuitive concept. If I do exp(log(x)) I get x, so I was expecting the same with the model. I suppose there will be a correcting factor somewhere, but for publication purposes I may as well use the log-transformed predicted and dnot backtransform it. Dec 12, 2014 at 12:47
• The discrepancy is due to the fact that there are several observations being averaged. And it is a well-known result, called Jensen's inequality, that the mean is greater than the back-transformed mean of the logs. The latter is commonly called the geometric mean. Dec 12, 2014 at 14:09