R 提取单元格组合而不重复索引

R 提取单元格组合而不重复索引,r,combinations,combinatorics,R,Combinations,Combinatorics,我试图计算矩阵元素的组合,但每个元素只应出现一次 实矩阵是对称的,最多可包含5个元素,约2000个元素: o <- matrix(runif(25), ncol = 5, nrow = 5) dimnames(o) <- list(LETTERS[1:5], LETTERS[1:5]) # A B C D E # A 0.4400317 0.1715681 0.7319108946 0.399

我试图计算矩阵元素的组合,但每个元素只应出现一次

实矩阵是对称的,最多可包含5个元素,约2000个元素:

o <- matrix(runif(25), ncol = 5, nrow = 5)
dimnames(o) <- list(LETTERS[1:5], LETTERS[1:5])

#           A         B            C         D         E
# A 0.4400317 0.1715681 0.7319108946 0.3994685 0.4466997
# B 0.5190471 0.1666164 0.3430245044 0.3837903 0.9322599
# C 0.3249180 0.6122229 0.6312876740 0.8017402 0.0141673
# D 0.1641411 0.1581701 0.0001703419 0.7379847 0.8347536
# E 0.4853255 0.5865909 0.6096330935 0.8749807 0.7230507
其中单个元素的值仅为1

不需要的组合:

AB, BC: Element B appears twice  
AB, AC: Element A appears twice
我尝试过的事情:

我考虑删除矩阵中不需要的部分:

out <- which(upper.tri(o), arr.ind = TRUE)
out <- cbind.data.frame(out, value = o[upper.tri(o)])

out[, 1] <- colnames(o)[out[, 1]]
out[, 2] <- colnames(o)[out[, 2]]
#    row col     value
# 1    A   B 0.1715681
# 2    A   C 0.7319109
# 3    B   C 0.3430245
# 4    A   D 0.3994685
# 5    B   D 0.3837903
# 6    C   D 0.8017402
# 7    A   E 0.4466997
# 8    B   E 0.9322599
# 9    C   E 0.0141673
# 10   D   E 0.8347536

如何有效地提取所有这些组合?

也许下面的内容就是您想要的。 请注意,我更感兴趣的是正确,而不是表现

此外,我还设置了RNG种子,以获得可重复的结果

set.seed(9840)    # Make reproducible results

o <- matrix(runif(25), ncol = 5, nrow = 5)
dimnames(o) <- list(LETTERS[1:5], LETTERS[1:5])

cmb <- combn(LETTERS[1:5], 2)
n <- ncol(cmb)
res <- NULL
nms <- NULL
for(i in seq_len(n)){
  for(j in seq_len(n)[-seq_len(i)]){
    x <- unique(c(cmb[, i], cmb[, j]))
    if(length(x) == 4){
      res <- c(res, o[cmb[1, i], cmb[2, i]] * o[cmb[1, j], cmb[2, j]])
      nms <- c(nms, paste0(cmb[1, i], cmb[2, i], '*', cmb[1, j], cmb[2, j]))
    }
  }
}

names(res) <- nms

res

这可能有用。我在N个元素=5和6上进行了测试

请注意,这并没有得到优化,希望能为您提供一个工作框架。对于更大的阵列,我可以看到涉及apply和combn的步骤是一个瓶颈

这里的想法是,在从另一个存储集合值的data.frame计算集合的乘积之前,首先生成一组唯一集合

通过计算所有组合对中唯一元素的数量来识别唯一集。例如,如果N个元素=6,我们期望lengthunlistcombination==6。如果N个元素=7,则只有3对加上一个余数元素也是如此。在N个元素为奇数的情况下,我们可以忽略剩余的未配对元素,因为它受到其他元素的约束

图书馆弹琴 图书馆2 一些功能
独特的,听起来好像你在计算排列。这个问题可能会有帮助:不,这里的顺序无关紧要:1ab,CD与CD,AB相同,甚至比BA,DC或两者之间的任何组合都相同,2ab是矩阵的一个单元而不是列表的一个元素,我不想重复组合中已经使用过的元素的行或列的任何单元。我们可以有像AE这样的重复项吗,BD和AE,DB?@YOLO,在输出列表中?如果您不知道所有副本都是重复的,或者您不知道副本的顺序,则不会。这就是我创建out data.frame的原因,它将进行进一步的计算。我想我遵循代码,除了第二个for循环,为什么省略1到I?当只有2对时,它工作,但如果矩阵为6,则有三对,只要可能,所有元素都应出现在组合上。你认为可以扩展它以包含所需的多对吗?我将编辑问题?@Llopis如果我不从1到I省略,它将重复列名和行名。谢谢你建议这种方法。目前,我可以测试它,但它似乎工作
AB, CD: 0.137553
set.seed(9840)    # Make reproducible results

o <- matrix(runif(25), ncol = 5, nrow = 5)
dimnames(o) <- list(LETTERS[1:5], LETTERS[1:5])

cmb <- combn(LETTERS[1:5], 2)
n <- ncol(cmb)
res <- NULL
nms <- NULL
for(i in seq_len(n)){
  for(j in seq_len(n)[-seq_len(i)]){
    x <- unique(c(cmb[, i], cmb[, j]))
    if(length(x) == 4){
      res <- c(res, o[cmb[1, i], cmb[2, i]] * o[cmb[1, j], cmb[2, j]])
      nms <- c(nms, paste0(cmb[1, i], cmb[2, i], '*', cmb[1, j], cmb[2, j]))
    }
  }
}

names(res) <- nms

res