Если вам не нужны комбо-имена в результирующем объекте, тогда мы можем комбинировать элементы ответов @ DWin's и @ Owen, чтобы обеспечить действительно векторизованный подход к проблеме.(Вы можете добавить имена комбинаций в виде имен строк с одним дополнительным шагом в конце.)
Сначала данные:
dat <- read.table(con <- textConnection(" A B C D
w 0 0 1 1
x 0 1 0 1
y 0 0 1 1
z 0 0 0 1
"), header=TRUE)
close(con)
Возьмите идею combn()
из ответа @ DWin, ноиспользуйте его для индексов строк из dat
:
combs <- combn(seq_len(nrow(dat)), 2)
Строки combs
теперь индексируют строки dat
, которые мы хотим умножить вместе:
> combs
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 2 2 3
[2,] 2 3 4 3 4 4
Теперь мы возьмем идею, показанную @Owen, а именно dat[i, ] * dat[j, ]
, где i
и j
- первая и вторая строки combs
соответственно.Мы конвертируем в матрицу с data.matrix()
, так как это будет более эффективно для больших объектов, но код будет работать с dat
также как фрейм данных.
mat <- data.matrix(dat)
mat[combs[1,], ] * mat[combs[2,], ]
, который производит:
> mat[combs[1,], ] * mat[combs[2,], ]
A B C D
w 0 0 0 1
w 0 0 1 1
w 0 0 0 1
x 0 0 0 1
x 0 0 0 1
y 0 0 0 1
Чтобы увидеть, как это работает, обратите внимание, что mat[combs[k,], ]
создает матрицу с различными строками, повторяемыми в порядке, указанном комбинациями:
> mat[combs[1,], ]
A B C D
w 0 0 1 1
w 0 0 1 1
w 0 0 1 1
x 0 1 0 1
x 0 1 0 1
y 0 0 1 1
> mat[combs[2,], ]
A B C D
x 0 1 0 1
y 0 0 1 1
z 0 0 0 1
y 0 0 1 1
z 0 0 0 1
z 0 0 0 1
Чтобы получить именно то, что опубликовал ОП, мы можемизменить имена строк с помощью второго combn()
вызова:
> out <- mat[combs[1,], ] * mat[combs[2,], ]
> rownames(out) <- apply(combn(rownames(dat), 2), 2, paste, collapse = "")
> out
A B C D
wx 0 0 0 1
wy 0 0 1 1
wz 0 0 0 1
xy 0 0 0 1
xz 0 0 0 1
yz 0 0 0 1