2012-08-22 35 views
7

ho questo insieme di dati:Come per prevedere i valori di x da un modello lineare (lm)

x <- c(0, 40, 80, 120, 160, 200) 
y <- c(6.52, 5.10, 4.43, 3.99, 3.75, 3.60) 

ho calcolato un modello lineare usando lm():

model <- lm(y ~ x) 

Voglio conoscere i valori previsti di x se ho nuovi valori , ad es. ynew <- c(5.5, 4.5, 3.5), ma se utilizzo la funzione predict(), calcola solo i nuovi valori .

Come posso prevedere nuovi valori x se ho nuovi valori ?

risposta

3

Poiché questo è un problema tipico in chimica (prevedere i valori da una calibrazione), il pacchetto chemCal fornisce inverse.predict. Tuttavia, questa funzione è limitata a "oggetti modello univariati di classe lm o rlm con formula del modello y ~ x o 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") 

Attenzione: Questa funzione è piuttosto lento e non adatto, se avete bisogno di inverse.predict un gran numero di valori.

Se ricordo male, il neg. Le SE avvengono perché la funzione si aspetta che la pendenza sia sempre positiva. I valori assoluti di SE dovrebbero essere ancora corretti.

+1

per quello che vale, 'library (sos); findFn ("{inverse prediction}") 'trova questa funzione, così come una funzione simile nel pacchetto' quantchem' (che sembra fare anche inversione non lineare ...) –

4

Credo che bisogna solo usare l'algebra per invertire 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) 

Guardando il tuo 'dati' qui, credo una regressione lineare potrebbe essere migliore ...

enter image description here

+0

so che posso risolvere il problema con l'algebra ma ho pensato che fare con alcune funzioni R. Lo faresti con una regressione non lineare? Grazie. – alexmulo

2

Se la tua relazione non è monotona o se hai più valori di predittore, allora ci possono essere più valori x per un dato valore y e devi decidere come gestirlo.

Una possibilità che potrebbe essere lento (e può essere il metodo utilizzato negli altri pacchetti menzionati) è quello di utilizzare la funzione 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) 

è possibile utilizzare la funzione TkPredict dal pacchetto TeachingDemos a bulbo oculare un soluzione.

Oppure si potrebbe ottenere un abbastanza veloce approssimazione generando un sacco di punti previsti, quindi nutrirli ai approxfun o splinfun funzioni per produrre le approssimazioni:

tmpx <- seq(min(x), max(x), length.out=250) 
tmpy <- predict(fit, data.frame(x=tmpx)) 
tmpfun <- splinefun(tmpy, tmpx) 
tmpfun(4)