Here is the source code of R
poly
function (boundary checking are removed). Why we can use QR to build polynomial expansion, which is very different from orthogonal polynomial tutorials like this one. Could anyone help me to understand the connection between these two?
xbar <- mean(x)
x <- x - xbar
X <- outer(x, 0L:degree, "^")
QR <- qr(X)
z <- QR$qr
z <- z * (row(z) == col(z))
Z <- qr.qy(QR, z)
norm2 <- colSums(Z^2)
alpha <- (colSums(x * Z^2)/norm2 + xbar)[1L:degree]
norm2 <- c(1, norm2)
Z <- Z/rep(sqrt(norm2[-1L]), each = length(x))
colnames(Z) <- 0L:degree
Z <- Z[, -1, drop = FALSE]