What?

See http://emilkirkegaard.dk/en/?p=5796

Start

library(pacman)
p_load(kirkegaard)

Calculate

The ranges of the possible correlation between \(r_{xz}\) given \(r_{rxy}\) and \(r_{yz}\) is given by Jensen (1980, p. 302) as:

\[range~r_{xz} = r_{xy} r_{yz} \pm \sqrt(r_{xy}^2 r_{yz}^2 - r_{xy}^2 - r_{yz}^2 + 1)\] We can re-calculate a matrix like the one given by Jensen using the following code.

#function
range_r = function(rxy, ryz) {
  c(rxy * ryz + sqrt(rxy^2 * ryz^2 - rxy^2 - ryz^2 + 1),
    rxy * ryz - sqrt(rxy^2 * ryz^2 - rxy^2 - ryz^2 + 1))
}

#tests
range_r(1, 1)
## [1] 1 1
range_r(.70, .70)
## [1]  1.00 -0.02
range_r(.30, .30)
## [1]  1.00 -0.82
#make a matrix like Jensen's
mat_input = expand.grid(rxy = seq(.10, 1, by = .05),
                        ryz = seq(.10, .90, by = .10))

mat_input = cbind(mat_input,
                  mat_input %>% rowwise() %>% do({
    range. = range_r(.$rxy, .$ryz)
    data_frame(
      upper = range.[1],
      lower = range.[2]
      )
  })
  ) %>% 
  mutate(shortform = sprintf("%.2f\n%.2f", upper, lower))

#plot as matrix
mat_input %>% ggplot(aes(rxy, ryz, label = shortform)) +
  #make text size smaller
  geom_text(size = 3) +
  #add axis text and use the desired breaks
  scale_x_continuous(expression(r[xy]), breaks = unique(mat_input$rxy)) +
  scale_y_continuous(expression(r[yz]), breaks = unique(mat_input$ryz)) +
  #cleaner presentation
  theme_bw() +
  #fix borders
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_line(color = "black")) +
  ggtitle("The transitiviity of correlations",
          subtitle = expression(The~range~of~possible~correlations~between~r[xz]~given~r[xy]~and~r[yz]))

GG_save("figs/matrix.png")