R 从具有重复项的数据创建组,以便每个组都有一个表示一次的重复项
我对大约3000个样本进行了测序。样本最初被标记,并通过PCR进行重复扩增。使用的标记范围从Tag1到Tag26 第1对使用Tag1-Tag13,第2对使用Tag14-Tag26。这些标记被重新使用,以允许合并样本 合并过程将涉及将标签为1-26的样本混合到第一组中,将标签为1-26的下一个样本混合到第二组中,依此类推。值得注意的是,有时会丢失一些标签,因为相应的样本未能放大 在去实验室之前,我需要先把这些小组写在纸上 这是分组前的样本快照。(注意,R 从具有重复项的数据创建组,以便每个组都有一个表示一次的重复项,r,data.table,R,Data.table,我对大约3000个样本进行了测序。样本最初被标记,并通过PCR进行重复扩增。使用的标记范围从Tag1到Tag26 第1对使用Tag1-Tag13,第2对使用Tag14-Tag26。这些标记被重新使用,以允许合并样本 合并过程将涉及将标签为1-26的样本混合到第一组中,将标签为1-26的下一个样本混合到第二组中,依此类推。值得注意的是,有时会丢失一些标签,因为相应的样本未能放大 在去实验室之前,我需要先把这些小组写在纸上 这是分组前的样本快照。(注意,Tag01至Tag05用于样本数据集中的Tag
Tag01
至Tag05
用于样本数据集中的TagA
和Tag06
至Tag10
用于TagB
。)
这是分组后的相同数据
postGroup <- structure(list(SampleID = c(1L, 2L, 3L, 4L, 5L, 6L, 8L, 9L, 10L,
11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 7L), TagA = structure(c(3L,
4L, 5L, 3L, 4L, 5L, 2L, 3L, 1L, 2L, 3L, 1L, 3L, 4L, 1L, 2L, 3L,
4L, 1L), .Label = c("Tag01", "Tag02", "Tag03", "Tag04", "Tag05"
), class = "factor"), TagB = structure(c(5L, 1L, 2L, 4L, 5L,
1L, 2L, 3L, 5L, 1L, 2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 1L), .Label = c("Tag06",
"Tag07", "Tag08", "Tag09", "Tag10"), class = "factor"), group = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 5L, 5L, 5L, 5L, 6L,
6L, 7L), .Label = c("group1", "group2", "group3", "group4", "group5",
"group6", "group7"), class = "factor")), class = "data.frame", row.names = c(NA,
-19L))
我正在寻找一个R脚本,可以创建这些组,因为我们习惯于使用少于50个样本,我们将手动创建组,但是,这个任务的规模是压倒性的
最后,由于样本数在1000,因此如果代码能够尽可能地保持样本的原始顺序,即样本1更接近样本50,而不是样本500,则会更好,以便在实验室中实现简单的顺序检索过程(我希望这里有意义…)如果我理解正确,OP希望对他的样本进行分组,以便
TagA
元素和一个不同的TagB
元素library(data.table)
grouped <- as.data.table(preGroup)[order(SampleID)][, group := 1L][]
max_grp <- 1L
while (any(grouped[, anyDuplicated(TagA) | anyDuplicated(TagB), by = group]$V1)) {
max_grp <- max_grp + 1L
dups <- duplicated(grouped, by = c("group", "TagA")) |
duplicated(grouped, by = c("group", "TagB"))
grouped[dups, group := max_grp][]
stopifnot(max_grp <= nrow(grouped)) # just to prevent infinite looping
}
grouped
注意,这个结果比OP手工挑选的postGroup
少了一组,后者包含第七组,只有一个样本
我们可以执行一些检查来验证条件2。满足以下条件:
grouped[, anyDuplicated(TagA), by = group]
注
这可能不是最有效的方法和/或实施。然而,在开始考虑优化之前,我想手头上有一些能够提供预期结果的东西。谢谢@Uwe,太棒了!!特别是尽量保持样品的秩序。快速提问,如果用户不介意样本的顺序(这种情况是可以预见的)…你将如何实现…?如果目标是最小化总体组的数量,这可能会导致一般的优化问题(可能类似于“背包问题”)。我理解最小化总体组数量的必要性。然而,正如我在前面的评论中提到的,条件的变化导致了一个不同的问题。因此,我恭敬地建议你提出一个新问题,强调需要尽量减少群体数量。谢谢。注意,再次感谢@Uwe。。
SampleID TagA TagB group
1 1 Tag03 Tag10 group1
2 2 Tag04 Tag06 group1
3 3 Tag05 Tag07 group1
4 4 Tag03 Tag09 group2
5 5 Tag04 Tag10 group2
6 6 Tag05 Tag06 group2
7 8 Tag02 Tag07 group2
8 9 Tag03 Tag08 group3
9 10 Tag01 Tag10 group3
10 11 Tag02 Tag06 group3
11 12 Tag03 Tag07 group4
12 13 Tag01 Tag08 group4
13 14 Tag03 Tag09 group5
14 15 Tag04 Tag10 group5
15 16 Tag01 Tag07 group5
16 17 Tag02 Tag08 group5
17 18 Tag03 Tag09 group6
18 19 Tag04 Tag10 group6
19 7 Tag01 Tag06 group7
library(data.table)
grouped <- as.data.table(preGroup)[order(SampleID)][, group := 1L][]
max_grp <- 1L
while (any(grouped[, anyDuplicated(TagA) | anyDuplicated(TagB), by = group]$V1)) {
max_grp <- max_grp + 1L
dups <- duplicated(grouped, by = c("group", "TagA")) |
duplicated(grouped, by = c("group", "TagB"))
grouped[dups, group := max_grp][]
stopifnot(max_grp <= nrow(grouped)) # just to prevent infinite looping
}
grouped
SampleID TagA TagB group
1: 1 Tag03 Tag10 1
2: 2 Tag04 Tag06 1
3: 3 Tag05 Tag07 1
4: 4 Tag03 Tag09 2
5: 5 Tag04 Tag10 2
6: 6 Tag05 Tag06 2
7: 7 Tag01 Tag06 3
8: 8 Tag02 Tag07 2
9: 9 Tag03 Tag08 3
10: 10 Tag01 Tag10 4
11: 11 Tag02 Tag06 4
12: 12 Tag03 Tag07 4
13: 13 Tag01 Tag08 5
14: 14 Tag03 Tag09 5
15: 15 Tag04 Tag10 5
16: 16 Tag01 Tag07 6
17: 17 Tag02 Tag08 6
18: 18 Tag03 Tag09 6
19: 19 Tag04 Tag10 6
grouped[, anyDuplicated(TagA), by = group]
group V1
1: 1 0
2: 2 0
3: 3 0
4: 4 0
5: 5 0
6: 6 0
grouped[, anyDuplicated(TagB), by = group]
group V1
1: 1 0
2: 2 0
3: 3 0
4: 4 0
5: 5 0
6: 6 0