【问题标题】:How to reduce aligned sequences to start and end coordinates?如何减少对齐的序列以开始和结束坐标?
【发布时间】:2019-12-07 22:48:00
【问题描述】:

我有一个标记坐标的数据表,在两组(A 和 B)之间对齐。例如:

dt_long <- data.table(LABEL_A = c(rep("A", 20), rep("A", 15), rep ("A", 10), rep ("A", 15), rep ("A", 10)),
                  SEQ_A = c(11:30, 61:75, 76:85, 86:100, 110:119),
                  LABEL_B= c(rep("C", 20), rep("D", 15), rep("F", 10), rep("G",15), rep("D", 10)),
                  SEQ_B = c(1:20, 25:11, 16:25, 15:1, 1:5, 8:12))

如何将这些信息简化为简短格式,其中给出了每个对齐序列的开始和结束坐标。例如:

dt_short <- data.table(LABEL_A = c("A", "A", "A", "A", "A", "A"),
                 Start_A = c(11, 61, 76, 86, 110, 115),
                 End_A = c(30, 75, 85, 100, 114, 119),
                 LABEL_B= c("C", "D", "F", "G", "D", "D"),
                 Start_B = c(1, 25, 16, 15, 1, 8),
                 End_B = c(20, 11, 25, 1, 5, 12))

每个对齐序列的长度应该相同。例如:

identical(abs(dt_short$End_A - dt_short$Start_A), abs(dt_short$End_B - dt_short$Start_B))

【问题讨论】:

  • LABEL 列和长度有关系吗
  • 不,标签列区分不同组中的序列。

标签: r data.table melt


【解决方案1】:

您可以使用rleid 并结合弗兰克的评论来删除分组列

dt_long[, .(
        LABEL_A=LABEL_A[1L], Start_A=SEQ_A[1L], End_A=SEQ_A[.N], 
        LABEL_B=LABEL_B[1L], Start_B=SEQ_B[1L], End_B=SEQ_B[.N]), 
    by=rleid(LABEL_A, LABEL_B,
        c(0L, cumsum(diff(SEQ_A) > 1L)), 
        c(0L, cumsum(diff(SEQ_B) > 1L)))][, (1) := NULL]

输出:

   LABEL_A Start_A End_A LABEL_B Start_B End_B
1:       A      11    30       C       1    20
2:       A      61    75       D      25    11
3:       A      76    85       F      16    25
4:       A      86   100       G      15     1
5:       A     110   114       D       1     5
6:       A     115   119       D       8    12

【讨论】:

  • 这是否可以调整,以便如果任一 SEQ 不是连续的,它们由单独的开始和结束坐标定义?我已经更新了示例数据集来证明这一点。谢谢。
  • 也解决了这个问题
  • 这个格式是否正确?它似乎缺少逗号和括号,并且出现错误。
  • 哎呀一些复制粘贴问题
  • 删除带有 DT[, (1) := NULL] 的列或我猜的更有效。我认为 DT[, -1] 创建了一个新表。
【解决方案2】:

直接的方法是按两个标签分组并获取每个组的firstlast,即

library(data.table)

dt_long[, .(Start_A = first(SEQ_A), End_A = last(SEQ_A), Start_B = first(SEQ_B), End_B = last(SEQ_B)), by = .(LABEL_A, LABEL_B)][]

#   LABEL_A LABEL_B Start_A End_A Start_B End_B
#1:       1       3      11    30       1    20
#2:       1       4      61    75      25    11
#3:       1       6      76    85      16    25
#4:       1       7      86   100      15     1

【讨论】:

  • 不幸的是,如果有多个序列具有相同的 LABEL,这将不起作用。我现在已经更新了示例。
  • 您认为可以添加一个 ID 列来对对齐的序列进行分组吗?
【解决方案3】:

我们可以只是子集和dcast。当有许多不同的列组时也可以无缝工作

dcast(dt_long[, .SD[c(1, .N)], .(LABEL_A, LABEL_B)], 
  LABEL_A + LABEL_B ~ c("Start", "End")[rowid(LABEL_A, LABEL_B)], 
     value.var = c("SEQ_A", "SEQ_B"))
#    LABEL_A LABEL_B SEQ_A_End SEQ_A_Start SEQ_B_End SEQ_B_Start
#1:       1       3        30          11        20           1
#2:       1       4        75          61        11          25
#3:       1       6        85          76        25          16
#4:       1       7       100          86         1          15

【讨论】:

  • 我收到以下错误:.subset2(x, i, exact = exact) 中的错误:下标越界
  • @Powege。是否是您帖子中相同示例的错误,我无法重现。我用data.table_1.12.2版本
  • 这是我使用当前示例数据集和 data.table 版本 1.10.4-3 时遇到的错误
  • @Powege。您是否可以更新 data.tablee 版本
  • 谢谢,现在运行;但是,它确实会产生与更新示例中相同的 dt_short。是否可以对其进行调整以确保每个对齐序列的长度相同?
猜你喜欢
  • 2020-04-05
  • 2021-11-12
  • 1970-01-01
  • 2023-02-25
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 2019-02-13
  • 1970-01-01
相关资源
最近更新 更多