program permtab
version 9.0
args rowvar colvar
tempname tabmat

di "Tabulating raw data:"
tab `rowvar' `colvar' , matcell(`tabmat')

di "Calculating permutation (can be slow):"
mata: permute_square_table("`tabmat'")
end

mata
void permute_square_table (string matrix tabmat) {
// Read stata matrix into mata
G=st_matrix(tabmat)

if (rows(G)!=cols(G)) {
_error("Table isn't square")
} else { //else substatement not needed in mata function call?

// generate permutation col-vector
perm=range(1,rows(G),1)
grandtotal=sum(G)

// initialise
permmax=perm
kmax = 0

// Setup and loop through all permutations
info=cvpermutesetup(perm)

while ((p=cvpermute(info)) != J(0,1,.)) {

po=trace(G[.,p])/grandtotal
pe=trace(rowsum(G[.,p])*colsum(G[.,p])/grandtotal)/grandtotal
temp = (po-pe)/(1-pe)

if (temp>kmax) {
 kmax=temp
 permmax=p
}
}

// Report max and permutation
         printf("Kappa max: %6.4f\n",kmax)
         printf("Permutation vector:\n")
permmax

         // Show permuted and original crosstab matrices
         printf("Permuted table:\n")
G[.,permmax]
         printf("Original table:\n")
G
}
}
end