Reputation: 145
Here is what I want to do. Starting form this matrix :
A B C D E F
A 3 0 2 1 2 0
B 4 4 0 0 4 1
C 2 0 3 0 2 0
D 1 0 0 5 1 0
E 5 0 0 3 6 1
F 0 0 0 0 2 3
I would like to determine all combinations containing 0 elements. For instance : (B,C,D) as :
column B has zeros for C and D, C
I did the following in R :
library(gtools)
mat <- matrix(c(3, 0, 2, 1, 2, 0, 4, 4, 0, 0, 4, 1, 2, 0, 3, 0, 2, 0, 1, 0, 0, 5,
1, 0, 5, 0, 0, 3, 6, 1, 0, 0, 0, 0, 2, 3), nrow=6, ncol=6)
rownames(mat) <- colnames(mat) <- c("A", "B", "C", "D", "E", "F")
mat <- t(mat) # start matrix (as shown above)
non_diag <- mat - diag(diag(mat)) # matrix with non diagonal only
mat_check <- t(non_diag) + non_diag
colnames(mat_check) <- colnames(mat)
rownames(mat_check) <- rownames(mat)
diag(mat_check) <- diag(mat) # Needed for later
res <- apply(mat_check, 1, function(x) x[x == 0]) # Get elements that are zero (for each col)
j <- 1
list_seq <- list()
for (i in res) {
tmp <- list(sequences=mixedsort(c(names(res)[j], names(res[[j]]))))
list_seq [j] <- tmp
j <- j + 1
}
unique(list_seq)
unique(list_seq)
and this outputs
[[1]]
[1] "A" "F"
[[2]]
[1] "B" "C" "D"
[[3]]
[1] "B" "C" "D" "F"
[[4]]
[1] "E"
[[5]]
[1] "A" "C" "D" "F"
which is not ok as
[[5]]
[1] "A" "C" "D" "F"
is not among possibilities.
Is there some way to do this ?
Upvotes: 2
Views: 213
Reputation: 72848
Try this.
diag(mat) <- NA
r <- lapply(colnames(mat), \(x) {
sort(c(x, intersect(names(which(mat[x, ] == 0)), names(which(mat[, x] == 0)))))
})
for (i in seq_along(r)) {
r[-(1:i)] <- lapply(r[-(1:i)], setdiff, r[[i]])
}
lapply(r[lengths(r) > 0], toString)
# [[1]]
# [1] "A, F"
#
# [[2]]
# [1] "B, C, D"
#
# [[3]]
# [1] "E"
Upvotes: 2