L'optimisation du maximum de vraisemblance pour le cas d'incertitudes en x et y a été traitée par York (2004). Voici le code R pour sa fonction.
"YorkFit", écrit par Rick Wehr, 2011, traduit en R par Rachel Chang
Routine universelle pour trouver le meilleur ajustement en ligne droite aux données avec des erreurs corrélées variables, y compris l'erreur et la qualité des estimations de l'ajustement, suivant l'équation. (13) de York 2004, American Journal of Physics, qui était basé à son tour sur York 1969, Earth and Planetary Sciences Letters
Fonction YorkFit <- (X, Y, Xstd, Ystd, Ri = 0, b0 = 0, printCoefs = 0, makeLine = 0, eps = 1e-7)
X, Y, Xstd, Ystd: ondes contenant des points X, des points Y et leurs écarts-types
AVERTISSEMENT: Xstd et Ystd ne peuvent pas être nuls car cela fera que Xw ou Yw soit NaN. Utilisez plutôt une très petite valeur.
Ri: coefficients de corrélation pour les erreurs X et Y - longueur 1 ou longueur de X et Y
b0: estimation initiale approximative de la pente (peut être obtenue à partir d'un ajustement des moindres carrés standard sans erreurs)
printCoefs: mis égal à 1 pour afficher les résultats dans la fenêtre de commande
makeLine: mis égal à 1 pour générer une onde Y pour la ligne d'ajustement
Renvoie une matrice avec l'ordonnée à l'origine et la pente plus leurs incertitudes
Si aucune supposition initiale pour b0 n'est fournie, utilisez simplement OLS si (b0 == 0) {b0 = lm (Y ~ X) $ coefficients [2]}
tol = abs(b0)*eps #the fit will stop iterating when the slope converges to within this value
a, b: interception finale et pente a.err, b.err: incertitudes estimées en interception et en pente
# WAVE DEFINITIONS #
Xw = 1/(Xstd^2) #X weights
Yw = 1/(Ystd^2) #Y weights
# ITERATIVE CALCULATION OF SLOPE AND INTERCEPT #
b = b0
b.diff = tol + 1
while(b.diff>tol)
{
b.old = b
alpha.i = sqrt(Xw*Yw)
Wi = (Xw*Yw)/((b^2)*Yw + Xw - 2*b*Ri*alpha.i)
WiX = Wi*X
WiY = Wi*Y
sumWiX = sum(WiX, na.rm = TRUE)
sumWiY = sum(WiY, na.rm = TRUE)
sumWi = sum(Wi, na.rm = TRUE)
Xbar = sumWiX/sumWi
Ybar = sumWiY/sumWi
Ui = X - Xbar
Vi = Y - Ybar
Bi = Wi*((Ui/Yw) + (b*Vi/Xw) - (b*Ui+Vi)*Ri/alpha.i)
wTOPint = Bi*Wi*Vi
wBOTint = Bi*Wi*Ui
sumTOP = sum(wTOPint, na.rm=TRUE)
sumBOT = sum(wBOTint, na.rm=TRUE)
b = sumTOP/sumBOT
b.diff = abs(b-b.old)
}
a = Ybar - b*Xbar
wYorkFitCoefs = c(a,b)
# ERROR CALCULATION #
Xadj = Xbar + Bi
WiXadj = Wi*Xadj
sumWiXadj = sum(WiXadj, na.rm=TRUE)
Xadjbar = sumWiXadj/sumWi
Uadj = Xadj - Xadjbar
wErrorTerm = Wi*Uadj*Uadj
errorSum = sum(wErrorTerm, na.rm=TRUE)
b.err = sqrt(1/errorSum)
a.err = sqrt((1/sumWi) + (Xadjbar^2)*(b.err^2))
wYorkFitErrors = c(a.err,b.err)
# GOODNESS OF FIT CALCULATION #
lgth = length(X)
wSint = Wi*(Y - b*X - a)^2
sumSint = sum(wSint, na.rm=TRUE)
wYorkGOF = c(sumSint/(lgth-2),sqrt(2/(lgth-2))) #GOF (should equal 1 if assumptions are valid), #standard error in GOF
# OPTIONAL OUTPUTS #
if(printCoefs==1)
{
print(paste("intercept = ", a, " +/- ", a.err, sep=""))
print(paste("slope = ", b, " +/- ", b.err, sep=""))
}
if(makeLine==1)
{
wYorkFitLine = a + b*X
}
ans=rbind(c(a,a.err),c(b, b.err)); dimnames(ans)=list(c("Int","Slope"),c("Value","Sigma"))
return(ans)
}
lm