选择包含所有独特元素的一组组合

时间:2015-07-29 13:50:32

标签: r matrix combinatorics

目的

我正在尝试选择一组包含一组唯一元素(inbreds)的组合。最终目的是设置微阵列数据的设计矩阵。在combi_mat列中,我使用了所有行(inbreds)的唯一名称。在行中,我有数组,其中列中的一些行之间有相应的组合名称。

虚拟数据

所有组合的设计矩阵构建如下:

### Function for the setup of a design matrix.
expand.grid.unique <- function(x, y, include.equals = FALSE) {
x <- unique(x)
y <- unique(y)
g <- function(i) {
    z <- setdiff(y, x[seq_len(i - include.equals)])
    if (length(z)) cbind(x[i], z, deparse.level = 0)
}
do.call(rbind, lapply(seq_along(x), g))
}

### Unique inbred lines.
inbreds <- c("F001", "F002", "F003", "F004", "F005", "P001", "P002", "P003")

### Create arrays (i.e. hybridization pairs).
hybrids <- expand.grid.unique(inbreds, inbreds)
hybrids <- paste0(hybrids[, 1], ".", hybrids[, 2])

### When an inbred line is an element of an array (`hybrids`), assign 
### `1` to the corresponding cell.
comb_mat <- matrix(0, nrow = length(hybrids), ncol = length(inbreds),
                   dimnames = list(hybrids, inbreds))
splnames <- gsub(pattern = "[.]", replacement = "|", x = rownames(comb_mat))
for (i in seq_len(nrow(comb_mat))) {
comb_mat[i, grep(splnames[i], colnames(comb_mat))] <- 1
}

约束

我的目标是选择comb_mat中符合以下约束条件的行:

  1. 每个列名必须存在于最后一组数组中。
  2. 最终数组的大小必须小于列数。
  3. 为了满足这两个条件,我定义了一个向量fin_count,它指定inbreds的两个元素只能出现一次(组合链的头部和尾部),而所有其他元素必须出现两次(链接重叠)。

    fin_count <- c(1, 1, rep(2, times = length(inbreds) - 2))
    

    我当前的方法

    我通过选择length(inbreds) - 1行(条件2)并通过fin_count(条件1)检查所选数组中元素的频率来测试上述条件:

    repeat {
    rand_design <- comb_mat[sample(seq_len(nrow(comb_mat)),
                                    size = length(inbreds) - 1), ]
    if (all(colSums(rand_design) %in% fin_count)) break
    }
    

    这个小例子的输出如下,其中列名表示包含行中所有近交行的唯一数组:

              F001 F002 F003 F004 F005 P001 P002 P003
    F001.P001    1    0    0    0    0    1    0    0
    F004.P002    0    0    0    1    0    0    1    0
    F003.P003    0    0    1    0    0    0    0    1
    F002.P001    0    1    0    0    0    1    0    0
    F004.F005    0    0    0    1    1    0    0    0
    F003.F005    0    0    1    0    1    0    0    0
    F002.P002    0    1    0    0    0    0    1    0
    

    如何优化上述代码?

    问题是这种方法仅适用于小型线和杂交对。实际上,我有多达103个独特的近交系和多达400个杂交配对,我必须从中选择。您对如何改进此代码有任何建议吗?我以前曾考虑使用expand.grid(),但这似乎不适合这么多组合。

0 个答案:

没有答案