gpt4 book ai didi

r - 过滤表以仅保留非冗余组

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:12:36 25 4
gpt4 key购买 nike

我在 R 中进行系统发育分析已有一段时间了,使用了 ape、phangorn 和 phytools 等库。

在解决问题时,我遇到了一个存在/不存在 data.frame,它指定感兴趣的基因是否属于(或不属于)某个组。

这方面的一个例子是:

             gene11    gene25  gene33  gene54  gene55 gene65 gene73   gene88
group_1 1 1 0 0 0 0 0 0
group_2 1 1 1 0 0 0 0 0
group_3 1 0 1 0 0 0 0 0
group_4 0 1 1 0 0 0 0 0
group_5 0 0 0 1 1 0 0 0
group_6 0 0 0 1 0 0 0 0
group_7 0 0 0 0 1 0 0 0
group_8 0 0 0 0 0 1 1 1
group_9 0 0 0 0 0 1 1 0
group_10 0 0 0 0 0 1 0 1
group_11 0 0 0 0 0 0 1 1

正如预期的那样,在处理生物实体组时,这些实体之间有多种关联方式:基因 11、25 和 33 形成一个组,它们的关系也可以描述为更小的组,描述成对关系。

所以重要的是:group_2group_5group_8 是生物学相关的基因组,并且他们事先并不知道相关组。其他较小的组是由于这些相关组中显示的关系而出现的:group_1 与 gene11 和 gene25 相关,但它是嵌套在更广泛(和相关的)group_2 中的组。其他情况同理:group_8描述了gene65、gene73和gene88之间的关系;与这些基因相关的其他组(group_9、group_10 和 group_11)仅是描述作为更广泛组 group_8 的一部分的基因之间存在的成对关系的子组。

事先已知的是,基因形成不相交组的簇,每个簇由其他(逐渐变小的)簇组成。我有兴趣捕获最大的不相交组。

问题的明确定义由另一位用户 (@Shree) 完成:

Find minimum number of groups such that all other groups are a sub-group of at least one of those groups. Also a group has to have at least 2 genes i.e. two 1s in a row. Also assuming, 1,01,0 is a subgroup of 1,1,1,0 but 0,1,1,1 is not a subgroup of 1,1,1,0.

提前感谢大家!

最佳答案

这是一种使用混合整数规划方法的方法。我正在使用 ompr用于数学建模和glpk (免费开源)作为求解器。建模逻辑作为代码中的注释提供。

我认为这个问题可以用数学方式描述如下-

Filter dataframe to minimize number of rows such that sum of all columns is 1. Selected rows are called primary groups and every other row should be a subgroup of a primary group. A column (gene) can belong to only one primary group. Any unselected row is a subgroup of a primary group when subgroup <= primary group at all positions (columns). Therefore, (0,0,1,1) is subgroup of (0,1,1,1) but (1,0,1,1) is not a subgroup of (0,1,1,1).

library(dplyr)
library(ROI)
library(ROI.plugin.glpk)
library(ompr)
library(ompr.roi)

gene_mat <- as.matrix(df)
nr <- nrow(gene_mat)
nc <- ncol(gene_mat)

model <- MIPModel() %>%
# binary variable x[i] is 1 if row i is selected else 0
add_variable(x[i], i = 1:nr, type = "binary") %>%
# minimize total rows selected
set_objective(sum_expr(x[i], i = 1:nr), "min") %>%
# sum of columns of selected rows must be = 1
add_constraint(sum_expr(gene_mat[i,j]*x[i], i = 1:nr) == 1, j = 1:nc) %>%
solve_model(with_ROI(solver = "glpk"))

# get rows selected
group_rows <- model %>%
get_solution(x[i]) %>%
filter(value > 0) %>%
pull(i) %>%
print()

result <- df[group_rows, ]

gene11 gene25 gene33 gene54 gene55 gene65 gene73 gene88
group_2 1 1 1 0 0 0 0 0
group_5 0 0 0 1 1 0 0 0
group_8 0 0 0 0 0 1 1 1

重要提示-

上面的公式没有解决subgroup <= primary group而是依赖于 OP 提到的事实 “事先已知的是基因形成不相交组的簇”。这意味着数据中不存在如下所示的情况,因为第 1、3、4 行不形成不相交的组,即第 3 列属于 2 个主要组,这是不允许的。

1 1 0 0 0
0 1 0 0 0
1 0 1 0 0 <- this row is not a subgroup of any row
0 0 1 1 1

无论如何,这里的代码进行安全检查以确保所有未选择的行都是只有一个主要组的子组 -

test <- lapply(group_rows, function(x) {
sweep(df, 2, as.numeric(df[x, ]), "<=") %>%
{which(rowSums(.) == ncol(df))}
})

# all is okay if below returns TRUE
length(Reduce(intersect, test)) == 0

数据-

df <- structure(list(
gene11 = c(1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L),
gene25 = c(1L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
gene33 = c(0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
gene54 = c(0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L),
gene55 = c(0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L),
gene65 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L),
gene73 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 1L),
gene88 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L)),
class = "data.frame",
row.names = c("group_1", "group_2", "group_3", "group_4",
"group_5", "group_6", "group_7", "group_8",
"group_9", "group_10", "group_11")
)

关于r - 过滤表以仅保留非冗余组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57469898/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com