【问题标题】:Choose a set of markers to distinguish individuals选择一组标记来区分个体
【发布时间】:2020-11-13 16:56:52
【问题描述】:

我有一些来自 8 个标记和 20 个个体的基因型数据。我想从 8 个标记中选择 5 个标记,它们可以为每个个体形成独特的基因型模式。目的是选择尽可能少的标记来区分这 20 个个体。

我知道我需要从 8 列中选择 5 列,然后比较每一行。如果发现重复行,则需要重新选择另外 5 列,直到找不到重复行为止。

但我不知道如何将它翻译成 R。有人可以帮忙吗?谢谢!

样本数据

Indiv   MN1 MN2 MN3 MN4 MN5 MN6 MN7 MN8
1   A   C   C   A   C   G   A   T
2   A   C   T   A   T   A   A   T
3   A   C   T   G   C   A   A   C
4   A   C   T   G   C   G   G   C
5   A   T   C   G   C   A   A   C
6   A   T   C   G   C   A   G   C
7   A   T   T   A   T   A   A   T
8   A   T   T   A   T   A   G   T
9   A   T   T   A   T   G   G   C
10  G   C   C   A   C   A   A   C
11  G   C   C   A   C   G   A   T
12  G   C   C   G   C   G   G   T
13  G   C   C   G   T   G   G   T
14  G   C   T   G   C   G   A   T
15  G   C   T   G   T   A   G   C
16  G   T   C   A   T   A   G   T
17  G   T   C   G   T   A   A   C
18  G   T   T   A   C   G   G   T
19  G   T   T   G   T   G   G   T

【问题讨论】:

    标签: r sampling


    【解决方案1】:

    不可能。假设我们不能改变标记的顺序。您需要至少 6 个标记来区分个体。考虑这个函数(蛮力解决方案)。

    distinct_combn <- function(df, m) {
      out <- combn(df, m, function(x) {
        if (nrow(unique(x)) == nrow(x)) names(x) else character(0L)
      }, simplify = FALSE)
      out[lengths(out) > 0L]
    }
    

    那么我们可以看到

    > distinct_combn(df[, -1L], 5)
    list()
    
    > distinct_combn(df[, -1L], 6)
    [[1]]
    [1] "MN1" "MN2" "MN3" "MN5" "MN6" "MN7"
    
    [[2]]
    [1] "MN1" "MN2" "MN3" "MN5" "MN7" "MN8"
    
    [[3]]
    [1] "MN1" "MN2" "MN4" "MN5" "MN6" "MN7"
    
    [[4]]
    [1] "MN1" "MN2" "MN4" "MN5" "MN7" "MN8"
    

    我使用的数据

    > df
       Indiv MN1 MN2 MN3 MN4 MN5 MN6 MN7 MN8
    1      1   A   C   C   A   C   G   A   T
    2      2   A   C   T   A   T   A   A   T
    3      3   A   C   T   G   C   A   A   C
    4      4   A   C   T   G   C   G   G   C
    5      5   A   T   C   G   C   A   A   C
    6      6   A   T   C   G   C   A   G   C
    7      7   A   T   T   A   T   A   A   T
    8      8   A   T   T   A   T   A   G   T
    9      9   A   T   T   A   T   G   G   C
    10    10   G   C   C   A   C   A   A   C
    11    11   G   C   C   A   C   G   A   T
    12    12   G   C   C   G   C   G   G   T
    13    13   G   C   C   G   T   G   G   T
    14    14   G   C   T   G   C   G   A   T
    15    15   G   C   T   G   T   A   G   C
    16    16   G   T   C   A   T   A   G   T
    17    17   G   T   C   G   T   A   A   C
    18    18   G   T   T   A   C   G   G   T
    19    19   G   T   T   G   T   G   G   T
    
    > dput(df)
    structure(list(Indiv = 1:19, MN1 = c("A", "A", "A", "A", "A", 
    "A", "A", "A", "A", "G", "G", "G", "G", "G", "G", "G", "G", "G", 
    "G"), MN2 = c("C", "C", "C", "C", "T", "T", "T", "T", "T", "C", 
    "C", "C", "C", "C", "C", "T", "T", "T", "T"), MN3 = c("C", "T", 
    "T", "T", "C", "C", "T", "T", "T", "C", "C", "C", "C", "T", "T", 
    "C", "C", "T", "T"), MN4 = c("A", "A", "G", "G", "G", "G", "A", 
    "A", "A", "A", "A", "G", "G", "G", "G", "A", "G", "A", "G"), 
        MN5 = c("C", "T", "C", "C", "C", "C", "T", "T", "T", "C", 
        "C", "C", "T", "C", "T", "T", "T", "C", "T"), MN6 = c("G", 
        "A", "A", "G", "A", "A", "A", "A", "G", "A", "G", "G", "G", 
        "G", "A", "A", "A", "G", "G"), MN7 = c("A", "A", "A", "G", 
        "A", "G", "A", "G", "G", "A", "A", "G", "G", "A", "G", "G", 
        "A", "G", "G"), MN8 = c("T", "T", "C", "C", "C", "C", "T", 
        "T", "C", "C", "T", "T", "T", "T", "C", "T", "C", "T", "T"
        )), class = "data.frame", row.names = c(NA, -19L))
    

    【讨论】:

    • 感谢您的优雅解决方案,@ekoam!我正在尝试 if 循环,但仍然进行到一半......只是一个简短的问题:我们是否可以更改标记的顺序是否重要?
    • 是的。组合和排列之间是有区别的。如果我们不能更改顺序,这是一个与组合有关的问题;否则,它就变成了一个关于排列的问题。请注意,一组 8 个标记只有 56 个 5 组合,但同一组有多达 6720 个 5 排列。 @zzz
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多