Skip to content

Instantly share code, notes, and snippets.

@conjugateprior
Created August 16, 2021 09:53
Show Gist options
  • Save conjugateprior/f1deb578a271c736a67a0ba0cb017cd4 to your computer and use it in GitHub Desktop.
Save conjugateprior/f1deb578a271c736a67a0ba0cb017cd4 to your computer and use it in GitHub Desktop.
ols-tls
library(ggplot2)
# the data
dd <- data.frame(x = c(0,3,6,9,10,14),
y = c(7,2,8,6,12,7))
# OLS model
mod <- lm(y ~ x, dd)
# TLS 'coefficients'
# from https://stats.stackexchange.com/questions/13152/how-to-perform-orthogonal-regression-total-least-squares-via-pca
v <- prcomp(cbind(dd$x,dd$y))$rotation
betax_tls <- v[2,1]/v[1,1]
beta0_tls <- mean(dd$y) - beta*mean(dd$x)
# add fitted values and some other stuff to a tidy version of dd
both <- rbind(dd, dd) |>
transform(model = rep(c("ols", "tls"), each = nrow(dd)),
fit = c(fitted(mod),
beta0_tls + dd$x * betax_tls),
res = c(dd$y - fitted(mod),
dd$y - (beta0_tls + dd$x * betax_tls))
)
ggplot(both, aes(x, y)) +
geom_point(size = 3, color = "darkgrey") +
geom_line(aes(x, fit, color = model)) +
annotate("text", x = both$x, y = both$y-0.5,
label = paste0("(", both$x, ",", both$y, ")"),
hjust = "inward", alpha = 0.5) +
lims(x = c(0, 15), y = c(0, 14)) +
scale_x_continuous(breaks = 0:16, minor_breaks = NULL) +
scale_y_continuous(breaks = 0:16, minor_breaks = NULL) +
theme_minimal()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment