Reputation: 353
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
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
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
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