This problem is sometimes not due to intentional correction for continuity at all. After wasting time on this issue multiple times, here's a reference for others.
These psych functions sometimes provide confusing output. Take this example:
> x = matrix(c(29, 89, 387, 77, 108, 251), nrow = 3)
> x
[,1] [,2]
[1,] 29 77
[2,] 89 108
[3,] 387 251
A contingency matrix between ordinal variables from a paper I was reading. If we try the obvious way to get the latent correlation:
> psych::polychoric(x)
Call: psych::polychoric(x = x)
Polychoric correlations
C1 C2
R1 1.00
R2 0.32 1.00
with tau of
1 2 3 4 5
[1,] -0.43 -0.43 0.43 0.43 0.43
[2,] -Inf -0.43 -0.43 0.43 Inf
Warning message:
In matpLower(x, nvar, gminx, gmaxx, gminy, gmaxy) :
1 cells were adjusted for 0 values using the correction for continuity. Examine your data carefully.
We get a warning about the continuity adjustment. However, there is no empty cell in our matrix, so what is going on? We can expand our data into a full dataset and try some other methods:
x2 = splitstackshape::expandRows(data.frame(as.table(x)), "Freq") %>% map_df(ordered)
table(x2$Var1, x2$Var2)
which shows the same as the matrix.
If we try the function in polycor instead, we get:
> polycor::hetcor(as.data.frame(x2))
Two-Step Estimates
Correlations/Type of Correlation:
Var1 Var2
Var1 1 Polychoric
Var2 -0.342 1
Standard Errors:
Var1 Var2
0.0462
Levels: 0.0462
n = 941
P-values for Tests of Bivariate Normality:
Var1 Var2
0.287
Levels: 0.287
Thus, we get a different value, of -.34. So which is right, .32 or (-).34? We can try an alternative psych function (Note that it will give errors if not given numeric input! It won't auto-convert from ordered factors, quite annoying.):
> psych::mixedCor(x2 %>% map_df(as.numeric))
Starting polydi |....................................................................................................| 100%Call: psych::mixedCor(data = x2 %>% map_df(as.numeric))
Var1 Var2
Var1 1.00
Var2 -0.34 1.00
which turns out to agree with the polycor one. The problem is that the psych functions expect input in very particular format, in this case, if you want to input a contingency matrix, it must be a class table, not a matrix. If you give it matrix input, it doesn't figure out your data is a contingency table and tries to do something else on it that produces nonsense results, and has to be continuity corrected.
> psych::polychoric(as.table(x))
[1] "You seem to have a table, I will return just one correlation."
$rho
[1] -0.342
$objective
[1] 1.5
$tau.row
A B
-1.213 -0.462
$tau.col
A
0.092
One can also use table(x2$Var1, x2$Var2) %>% psych::polychoric()
.