I have a series of individuals who have ranked items in particular orders. For example, 6 individuals ranking 4 items (individuals are rows, items are columns, values are their rank, e.g. individual 2 ranked item 4 2nd best).
set.seed(2109)
d= t(replicate(6,sample(1:4)))
d[sample(1:prod(dim(d)),3)] = NA
d[1,3] = 3
d[1,2] = NA
d[4,3] = 1
d[5,4] = 1
d
[,1] [,2] [,3] [,4]
[1,] 1 NA 3 2
[2,] 1 3 4 2
[3,] 2 3 4 1
[4,] 2 3 1 NA
[5,] NA 2 3 1
[6,] 1 3 2 4
I'd like to know how many unique compatible orders there are. However, some of the individuals have not ranked some of the items (missing data). For example, individual 1 and 2 above have a compatible order (being anti-conservative), and the same for individuals 3 and 4. So there are 4 unique compatible orders. Looking for unique orders does not work:
> length(unique(apply(d,1,paste,collapse='')))
[1] 6
I could go through each row and see if there is a compatible order using a regular expression, but that would only count 2 unique rows. Is there some formula or algorithm that will return the correct number of unique compatible orders?
Edit:
We can identify compatible pairs with the functions below. uniqueCompatibleOrders creates a matrix of compatibility between each pair of individuals, and returns the sum in the lower triangle.
matchCompatibleij = function(i,j,data){
# Take two row indices and check if the
# ranks of the vectors of the rows in data
# are in a compatible order.
# Rows can include missing data.
ix = data[i,]
jx = data[j,]
complete = !(is.na(ix)|is.na(jx))
all(order(ix[complete])==order(jx[complete]))
}
matchCompatible <- Vectorize(matchCompatibleij, vectorize.args=list("i","j"))
uniqueCompatibleOrders = function(data){
# Compare all individuals to all others,
# checking if each is compatible
matches = outer(1:nrow(data),1:nrow(data),matchCompatible,data=data)
numCompatiblePairs = sum(matches[lower.tri(matches,diag = F)])
return(numCompatiblePairs)
}
Then calculate the difference between the maximum number of unique pairs and the number of compatible individuals.
> numCompatiblePairs = uniqueCompatibleOrders(d)
> numCompatiblePairs
[1] 4
> # Maximum number of unique individuals
> numIndividuals = nrow(d)
> uniqueCompatibleIndividuals = numIndividuals - numCompatiblePairs
> uniqueCompatibleIndividuals
[1] 2
However, this does not work in many cases:
> d2 = matrix(rep(1:4,6),ncol=4, byrow = T)
> uniqueCompatibleOrders(d2)
[1] 15
> numCompatiblePairs2 = uniqueCompatibleOrders(d2)
> numCompatiblePairs2
[1] 15
> # Maximum number of unique individuals
> numIndividuals2 = nrow(d2)
> uniqueCompatibleIndividuals2 = numIndividuals2 - numCompatiblePairs2
> uniqueCompatibleIndividuals2
[1] -9
What am I doing wrong?