YYM17
YYM17

Reputation: 353

How to make contingency table for combining several pair of variables in R?

I have several binary variables (1, 0) e.g., a1, a2, a3, a4. I'd like to make a table combining a1, a2, a3, a4 (like pairwise) to see the number of "1" in either pair of variables.

  a1 a2 a3 a4
1  1  0  1  0
2  0  0  1  0
3  1  1  0  0
4  1  1  1  0
5  0  1  0  1
6  1  0  1  0
7  0  0  1  1
structure(list(a1 = c(1, 0, 1, 1, 0, 1, 0), a2 = c(0, 0, 1, 1, 
1, 0, 0), a3 = c(1, 1, 0, 1, 0, 1, 1), a4 = c(0, 0, 0, 0, 1, 
0, 1)), class = "data.frame", row.names = c(NA, -7L))

The table is something like below:

=="1"
     a1  a2  a3  a4
a1        2   3   0
a2   2        1   0
a3   3    1       1
a4   0    0   1   

I trid combn but it returned multiple 2X2 table combining either two variables. I'm wondering if there is a way to make a table like above? Thank you.

Upvotes: 2

Views: 799

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 389325

One way would be using outer calculating count's of 1's for every combination of column names.

calculate_fun <- function(x, y) sum(df[x] == 1 & df[y] == 1)

mat <- outer(names(df), names(df), Vectorize(calculate_fun))
diag(mat) <- 0
dimnames(mat) <- list(names(df), names(df))
mat

#   a1 a2 a3 a4
#a1  0  2  3  0
#a2  2  0  1  1
#a3  3  1  0  1
#a4  0  1  1  0

Upvotes: 1

chinsoon12
chinsoon12

Reputation: 25223

Another base R option:

p <- rbind(data.frame(V1=names(DF), V2=names(DF)), 
    do.call(rbind, apply(DF, 1L, function(x) {
    y <- names(DF)[x==1L]
    if (length(y) > 1L) t(combn(y, 2L))
})))
ans <- table(p)
ans <- ans + t(ans)
diag(ans) <- 0
ans

Upvotes: 1

user2974951
user2974951

Reputation: 10385

apply(df,2,function(x){
  apply(df,2,function(y){
    sum(x==1 & y==1)
  })
})
   a1 a2 a3 a4
a1  4  2  3  0
a2  2  3  1  1
a3  3  1  5  1
a4  0  1  1  2

ignoring the diagonal or replacing it.

Upvotes: 6

Related Questions