R: Translate a model having orthogonal polynomials to a function using qr decomposition

一世执手 提交于 2019-11-30 16:59:25

I'm ignoring "I want to use qr decomposition using Gram Schmidt algorithm in R" except to note that poly() uses qr() to calculate its orthogonal polynomials.

I read the question as wanting to take the model with coefficients in terms of orthogonal polynomials poly(QPB2_REF3, 2, raw = FALSE) and express it algebraically in powers of QPB2_REF3. That means expressing the orthogonal polynomials poly(QPB2_REF3, 2, raw = FALSE)1, poly(QPB2_REF3, 2, raw = FALSE)2 conventionally as coefficients of powers of QPB2_REF3 rather than as the "centering and normalization constants" in the attr(, "coefs") of the poly() object.

Over the years in the various R forums others have made similar requests to be told that one can: (a) calculate the polynomials using poly.predict(), so the conventional form coefficients aren't needed; (b) see the algorithm in the code and/or Kennedy & Gentle (1980, pp. 343–4).

(a) didn't meet my didactic needs. On (b) I could see how to calculate the polynomial values for given x but I just got lost in the algebra trying to deduce the conventional form coefficients :-{

Kennedy & Gentle refer to "solving for x in p(x)" which to my simple mind suggested lm and led to the truly horrible approach implemented in orth2raw() below. I fully accept that there must be a better, more direct, way to deduce the conventional form coefficients from the centering and normalisation constants but I can't work it out, and this approach seems to work.

orth2raw <- function(x){
# x <- poly(.., raw=FALSE) has a "coefs" attribute "which contains 
# the centering and normalization constants used in constructing 
# the orthogonal polynomials". orth2raw returns the coefficents of
# those polynomials in the conventional form
#    b0.x^0 + b1.x^1 + b2.x^2 + ...
# It handles the coefs list returned by my modifications of 
# poly and polym to handle multivariate predictions  
    o2r <- function(coefs){
       Xmean <- coefs$alpha[1]
       Xsd <- sqrt(coefs$norm2[3]/coefs$norm2[2])
       X <- seq(Xmean-3*Xsd, Xmean+3*Xsd, length.out=degree+1)
       Y <- poly(X, degree = degree, coefs=coefs)
       Rcoefs <- matrix(0,degree, degree+1)
       for (i in 1:degree) Rcoefs[i,1:(i+1)] <- coef(lm(Y[,i] ~ poly(X, i, raw=TRUE) ))
       dimnames(Rcoefs) <- list(paste0("poly(x)", 1:degree), paste0("x^",0:degree))
       Rcoefs
      }
   degree <- max(attr(x, "degree"))
   coefs <- attr(x, "coefs")
   if(is.list(coefs[[1]])) lapply(coefs, o2r) else o2r(coefs)
   }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!