我有这个数据集:
x <- c(0, 40, 80, 120, 160, 200)
y <- c(6.52, 5.10, 4.43, 3.99, 3.75, 3.60)
我使用lm()
计算了一个线性模型:
model <- lm(y ~ x)
如果我有新的x
值,我想知道y
的预测值,例如ynew <- c(5.5, 4.5, 3.5)
,但如果我使用predict()
函数,则只会计算新的y
值。
如果我有新的x
值,如何预测新的y
值?
答案 0 :(得分:4)
我认为您只需使用代数将y=a+b*x
反转为x=(y-a)/b
:
cc <- coef(model)
(xnew <- (ynew-cc[1])/cc[2])
# [1] 31.43007 104.76689 178.10372
plot(x,y
abline(model)
points(xnew,ynew,col=2)
在这里查看您的“数据”,我认为非线性回归可能会更好......
答案 1 :(得分:4)
由于这是化学中的典型问题(预测校准值),因此包chemCal
提供inverse.predict
。但是,此函数仅限于“类别lm或rlm的单变量模型对象[s],模型公式为y~x或y~x-1。”
x <- c(0, 40, 80, 120, 160, 200)
y <- c(6.52, 5.10, 4.43, 3.99, 3.75, 3.60)
plot(x,y)
model <- lm(y ~ x)
abline(model)
require(chemCal)
ynew <- c(5.5, 4.5, 3.5)
xpred<-t(sapply(ynew,function(y) inverse.predict(model,y)[1:2]))
# Prediction Standard Error
#[1,] 31.43007 -38.97289
#[2,] 104.7669 -36.45131
#[3,] 178.1037 -39.69539
points(xpred[,1],ynew,col="red")
警告:如果您需要inverse.predict大量值,此函数非常慢且不适合。
如果我没记错的话,那就是。 SE发生是因为函数期望斜率始终为正。 SE的绝对值应该仍然是正确的。
答案 2 :(得分:2)
如果你的关系是非单调的,或者你有多个预测值,那么给定的y值可以有多个x值,你需要决定如何处理它。
一个可能很慢的选项(可能是所提到的其他包中使用的方法)是使用uniroot函数:
x <- runif(100, min=-1,max=2)
y <- exp(x) + rnorm(100,0,0.2)
fit <- lm( y ~ poly(x,3), x=TRUE )
(tmp <- uniroot( function(x) predict(fit, data.frame(x=x)) - 4, c(-1, 2) )$root)
library(TeachingDemos)
plot(x,y)
Predict.Plot(fit, 'x', data=data.frame(x=x), add=TRUE, ref.val=tmp)
您可以使用TkPredict
包中的TeachingDemos
功能来解决问题。
或者您可以通过生成大量预测点来获得相当快速的近似值,然后将它们提供给approxfun
或splinfun
函数以生成近似值:
tmpx <- seq(min(x), max(x), length.out=250)
tmpy <- predict(fit, data.frame(x=tmpx) )
tmpfun <- splinefun( tmpy, tmpx )
tmpfun(4)