knitr::opts_chunk$set(cache = TRUE, dev = c("png", "pdf"))
library(eucs)
vars <- c(
  "Relief" = "relief_1000m_radius", "TWI" = "topographic_wetness_index_3sec",
  "Moisture" = "mean_moisture_index_of_low_qtr", "Nitrogen" = "total_nitrogen",
  "Radiation" = "annual_mean_radiation",
  "Precipitation" = "annual_precipitation",
  "Temperature" = "annual_mean_temperature",
  "Phosphorus" = "total_phosphorus", "Sand" = "sand",
  "Soil Depth" = "depth_of_soil"
)
rgn_names <- sort(c("Greater Grampians", unique(southeast$ibra_subregion)))
pca_data <- na.omit(rbind(covariates_grampians, covariates_southeast))
pca_data <- subset(pca_data, ibra_subregion %in% rgn_names)
pca <- prcomp(pca_data[, vars], center = TRUE, scale. = TRUE)
rgns <- factor(pca_data$ibra_subregion)
n <- NROW(pca$x)
lam <- pca$sdev[1:2] * sqrt(n)
y <- t(t(pca$rotation[, 1:2]) * lam)
x <- t(t(pca$x[, 1:2]) / lam)
n <- nrow(x)
p <- nrow(y)
unsigned.range <-
  function(x) c(-abs(min(x, na.rm = TRUE)), abs(max(x, na.rm = TRUE)))
rangx1 <- unsigned.range(x[, 1])
rangx2 <- unsigned.range(x[, 2])
rangy1 <- unsigned.range(y[, 1])
rangy2 <- unsigned.range(y[, 2])
xlim <- ylim <- rangx1 <- rangx2 <- range(rangx1, rangx2)
ratio <- max(rangy1 / rangx1, rangy2 / rangx2) / .9

colors <- rainbow(nlevels(rgns), alpha = .5)
names(colors) <- levels(rgns)
colors[
  c(
    "Bateman", "Bondo", "East Gippsland Lowlands", "Ettrema", "Gippsland Plain",
    "Highlands-Northern Fall", "Highlands-Southern Fall", "Kybeyan-Gourock",
    "Monaro", "Murrumbateman", "South East Coastal Ranges", "Strzelecki Ranges",
    "Victorian Alps"
  )
] <- grey.colors(1, alpha = .1)
par(mar = c(5, 4, 8, 3))
plot(
  x, xlim = xlim, ylim = ylim, cex = .25,
  col = colors[rgns], pch = 19,
  panel.first = grid()
)
par(xpd = TRUE)
legend(
  "topleft", inset = c(0, -.21), legend = levels(rgns),
  fill = colors, ncol = 4, bty = "n", x.intersp = .8, cex = .7
)
par(new = TRUE)
dev.hold()
plot(
  y, axes = FALSE, type = "n", xlim = xlim * ratio, ylim = ylim * ratio,
  xlab = "", ylab = ""
)
box()
text(y, labels = names(vars), cex = .6)
arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, length = 0.1)

dev.flush()
IycgLS0tCiMnIHRpdGxlOiAiUHJpbmNpcGFsIGNvbXBvbmVudHMgYW5hbHlzaXMgb2YgU291dGgtZWFzdCBBdXN0cmFsaWFuIGVudmlyb25tZW50IgojJyBhdXRob3I6ICJXaWxsaWFtIEsuIE1vcnJpcyIKIycgZGF0ZTogImByIFN5cy5EYXRlKClgIgojJyBvdXRwdXQ6CiMnICAgcm1hcmtkb3duOjpodG1sX25vdGVib29rOgojJyAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiMnIC0tLQoKIysgc2V0dXAsIG1lc3NhZ2U9RkFMU0UKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNhY2hlID0gVFJVRSwgZGV2ID0gYygicG5nIiwgInBkZiIpKQpsaWJyYXJ5KGV1Y3MpCgojKyBydW4tcGNhCnZhcnMgPC0gYygKICAiUmVsaWVmIiA9ICJyZWxpZWZfMTAwMG1fcmFkaXVzIiwgIlRXSSIgPSAidG9wb2dyYXBoaWNfd2V0bmVzc19pbmRleF8zc2VjIiwKICAiTW9pc3R1cmUiID0gIm1lYW5fbW9pc3R1cmVfaW5kZXhfb2ZfbG93X3F0ciIsICJOaXRyb2dlbiIgPSAidG90YWxfbml0cm9nZW4iLAogICJSYWRpYXRpb24iID0gImFubnVhbF9tZWFuX3JhZGlhdGlvbiIsCiAgIlByZWNpcGl0YXRpb24iID0gImFubnVhbF9wcmVjaXBpdGF0aW9uIiwKICAiVGVtcGVyYXR1cmUiID0gImFubnVhbF9tZWFuX3RlbXBlcmF0dXJlIiwKICAiUGhvc3Bob3J1cyIgPSAidG90YWxfcGhvc3Bob3J1cyIsICJTYW5kIiA9ICJzYW5kIiwKICAiU29pbCBEZXB0aCIgPSAiZGVwdGhfb2Zfc29pbCIKKQpyZ25fbmFtZXMgPC0gc29ydChjKCJHcmVhdGVyIEdyYW1waWFucyIsIHVuaXF1ZShzb3V0aGVhc3QkaWJyYV9zdWJyZWdpb24pKSkKcGNhX2RhdGEgPC0gbmEub21pdChyYmluZChjb3ZhcmlhdGVzX2dyYW1waWFucywgY292YXJpYXRlc19zb3V0aGVhc3QpKQpwY2FfZGF0YSA8LSBzdWJzZXQocGNhX2RhdGEsIGlicmFfc3VicmVnaW9uICVpbiUgcmduX25hbWVzKQpwY2EgPC0gcHJjb21wKHBjYV9kYXRhWywgdmFyc10sIGNlbnRlciA9IFRSVUUsIHNjYWxlLiA9IFRSVUUpCgojKyBwbG90LXBjYSwgcmVzdWx0cyA9ICJoaWRlIiwgZmlnLmhlaWdodCA9IDguMiwgZmlnLndpZHRoID0gNy41CnJnbnMgPC0gZmFjdG9yKHBjYV9kYXRhJGlicmFfc3VicmVnaW9uKQpuIDwtIE5ST1cocGNhJHgpCmxhbSA8LSBwY2Ekc2RldlsxOjJdICogc3FydChuKQp5IDwtIHQodChwY2Ekcm90YXRpb25bLCAxOjJdKSAqIGxhbSkKeCA8LSB0KHQocGNhJHhbLCAxOjJdKSAvIGxhbSkKbiA8LSBucm93KHgpCnAgPC0gbnJvdyh5KQp1bnNpZ25lZC5yYW5nZSA8LQogIGZ1bmN0aW9uKHgpIGMoLWFicyhtaW4oeCwgbmEucm0gPSBUUlVFKSksIGFicyhtYXgoeCwgbmEucm0gPSBUUlVFKSkpCnJhbmd4MSA8LSB1bnNpZ25lZC5yYW5nZSh4WywgMV0pCnJhbmd4MiA8LSB1bnNpZ25lZC5yYW5nZSh4WywgMl0pCnJhbmd5MSA8LSB1bnNpZ25lZC5yYW5nZSh5WywgMV0pCnJhbmd5MiA8LSB1bnNpZ25lZC5yYW5nZSh5WywgMl0pCnhsaW0gPC0geWxpbSA8LSByYW5neDEgPC0gcmFuZ3gyIDwtIHJhbmdlKHJhbmd4MSwgcmFuZ3gyKQpyYXRpbyA8LSBtYXgocmFuZ3kxIC8gcmFuZ3gxLCByYW5neTIgLyByYW5neDIpIC8gLjkKCmNvbG9ycyA8LSByYWluYm93KG5sZXZlbHMocmducyksIGFscGhhID0gLjUpCm5hbWVzKGNvbG9ycykgPC0gbGV2ZWxzKHJnbnMpCmNvbG9yc1sKICBjKAogICAgIkJhdGVtYW4iLCAiQm9uZG8iLCAiRWFzdCBHaXBwc2xhbmQgTG93bGFuZHMiLCAiRXR0cmVtYSIsICJHaXBwc2xhbmQgUGxhaW4iLAogICAgIkhpZ2hsYW5kcy1Ob3J0aGVybiBGYWxsIiwgIkhpZ2hsYW5kcy1Tb3V0aGVybiBGYWxsIiwgIkt5YmV5YW4tR291cm9jayIsCiAgICAiTW9uYXJvIiwgIk11cnJ1bWJhdGVtYW4iLCAiU291dGggRWFzdCBDb2FzdGFsIFJhbmdlcyIsICJTdHJ6ZWxlY2tpIFJhbmdlcyIsCiAgICAiVmljdG9yaWFuIEFscHMiCiAgKQpdIDwtIGdyZXkuY29sb3JzKDEsIGFscGhhID0gLjEpCnBhcihtYXIgPSBjKDUsIDQsIDgsIDMpKQpwbG90KAogIHgsIHhsaW0gPSB4bGltLCB5bGltID0geWxpbSwgY2V4ID0gLjI1LAogIGNvbCA9IGNvbG9yc1tyZ25zXSwgcGNoID0gMTksCiAgcGFuZWwuZmlyc3QgPSBncmlkKCkKKQpwYXIoeHBkID0gVFJVRSkKbGVnZW5kKAogICJ0b3BsZWZ0IiwgaW5zZXQgPSBjKDAsIC0uMjEpLCBsZWdlbmQgPSBsZXZlbHMocmducyksCiAgZmlsbCA9IGNvbG9ycywgbmNvbCA9IDQsIGJ0eSA9ICJuIiwgeC5pbnRlcnNwID0gLjgsIGNleCA9IC43CikKcGFyKG5ldyA9IFRSVUUpCmRldi5ob2xkKCkKcGxvdCgKICB5LCBheGVzID0gRkFMU0UsIHR5cGUgPSAibiIsIHhsaW0gPSB4bGltICogcmF0aW8sIHlsaW0gPSB5bGltICogcmF0aW8sCiAgeGxhYiA9ICIiLCB5bGFiID0gIiIKKQpib3goKQp0ZXh0KHksIGxhYmVscyA9IG5hbWVzKHZhcnMpLCBjZXggPSAuNikKYXJyb3dzKDAsIDAsIHlbLCAxTF0gKiAwLjgsIHlbLCAyTF0gKiAwLjgsIGxlbmd0aCA9IDAuMSkKZGV2LmZsdXNoKCkK