Another possible solution here. Your input is a bit more complicated for the “table”, because by default you have two sets “a” and “b” with binary indicators in each row indicating pairwise instances only between “a” and “b”, and you want to iterate over them, Below is a generalized (but maybe not very elegant) function that will work with different lengths a and b:
tmp2 <- structure(list(a1 = c(1L, 0L, 0L), a2 = c(1L, 0L, 1L), a3 = c(0L,
1L, 0L), b1 = c(1L, 0L, 1L), b2 = c(1L, 0L, 0L), b3 = c(0L, 1L,
1L)), .Names = c("a1", "a2", "a3", "b1", "b2", "b3"), class = "data.frame", row.names = c(NA,
-3L))
fun = function(x) t(do.call("cbind", lapply(x[,grep("a", colnames(x))],
function(p) rowSums(do.call("rbind", lapply(x[,grep("b", colnames(x))],
function(q) q*p ))))))
fun(tmp2)
set.seed(1)
m = matrix(rbinom(size=1, n=50, prob=0.75), ncol=10, dimnames=list(paste("instance_", 1:5, sep=""), c(paste("a",1:4,sep=""), paste("b",1:6,sep=""))))
fun(as.data.frame(m))