There are many ideas.
Maybe leverage in the corresponding linear regression? Problem: There are two possible regressions, $y=\alpha + \beta x +\epsilon$ or $x=\alpha+\beta y + \epsilon$. Turns out that there is no relationship between the leverages in these two models (exercise). Maybe some leverage formula could be made for correlations also? But from this an idea: Leverage has connections with Mahalanobis distance, so
Calculate the Mahalanobis distance for each point using estimated center and covariance matrix. There is one problem: If non-robust estimates are used, these distances might be misleading. This leads to an answer:
Mahalanobis distance based on robust estimates. This is implemented in R, so:
library(mvtnorm) # First simulate some example data:
set.seed(7 * 11 * 13) # my open seed
x <- rnorm(100, 10)
y <- rnorm(100, 10)
sigma <- 100*matrix(c( 1.0, 0.98,
0.98, 1.0), 2, 2, byrow=TRUE)
XY <- mvtnorm::rmvnorm(5, c(10, 10), sigma)
XY <- rbind(cbind(x, y), XY)
colnames(XY) <- c("x", "y")
XY <- as.data.frame(XY)
# Then estimating robust center and covariance:
corrob <- robust::covRob(XY, corr=TRUE)$cov[1, 2]
covrob <- robust::covRob(XY, corr=FALSE)
Srob <- covrob$cov
mu <- covrob$center
corrob
[1] -0.1315657
mu
x y
9.937185 9.916624
Srob
x y
x 1.4750940 -0.1256779
y -0.1256779 0.6186042
XYcent <- as.matrix(sweep(XY, 2, mu)) # subtracting robust center
Maha <- sqrt( diag(crossprod( t(XYcent), solve(Srob, t(XYcent)) )) )
with(XY, {plot(x, y, col=ifelse(Maha>5, "red", "blue"), main="Point cloud", sub="with large Mahalanobis distance in red")})
Producing the plot:
The cutoff for Mahalanobis distances at 5 was chosen from a histogram of distances (not shown). The covRob
function has many options not used, which can be studied in the documentation.
But all that wasn't really necessary, because in the process of robust estimation we did get the robust correlation estimate about $-0.13$, far away from the nonrobust Pearson correlation (try). And the robust
package even calculate the distances and make the plot for us:
plot(covrob) #not shown
which makes two plots (try).