如何高效地找到序列坐标inn R的两个数据表之间的重叠?

How to efficiently find the overlap between two data tables of sequence coordinates inn R?

我有两个大数据table,坐标不同。例如:

library(data.table)

dt1 <- data.table(cat = c(rep("A", 2), rep("B", 2)),
                  start = c(1, 4, 2, 15),
                  end = c(6, 9, 5, 20))
dt2 <- data.table(cat = c(rep("A", 2), rep("B", 2)),
                  start = c(2, 1, 10, 17),
                  end = c(7, 3, 12, 20))

我需要为重叠序列创建坐标数据 table(即出现在两个数据 table 中给出的序列中的整数,对于每个类别)。我目前可以使用 for 循环执行此操作。例如:

seq2 <- Vectorize(seq.default, vectorize.args = c("from", "to"))
out_list <- list()
for(i in 1:length(unique(dt1$cat))){
  sub1 <- dt1[cat == unique(dt1$cat)[i]]
  sub2 <- dt2[cat == unique(dt1$cat)[i]]
  vec1 <- unique(unlist(c(seq2(from = sub1$start, to = sub1$end))))
  vec2 <- unique(unlist(c(seq2(from = sub2$start, to = sub2$end))))
  
  vec <- Reduce(intersect, list(vec1, vec2))
  
  vec_dt <- data.table(V1 = vec)
    output <- vec_dt[order(V1), 
                     .(start = min(V1),
                       end = max(V1)),
                     by = .(grp = rleid(c(0, cumsum(diff(V1) > 1))))
                     ]
    output$grp <- NULL
    output$cat <- unique(dt1$cat)[i]
  out_list[[i]] <- output
  print(i)
}
output_dt <- do.call("rbind", out_list)

但是,我需要应用它的数据集非常大(行数和向量大小)。有人能提出提高性能的方法吗?

谢谢

您可以 (a) 将 start/end 变量转换为序列,(b) 执行内部联接,(c) 转换回 start/end。

library(data.table)

dt1 <- data.table(cat = c(rep("A", 2), rep("B", 2)),
                  start = c(1, 4, 2, 15),
                  end = c(6, 9, 5, 20))
dt2 <- data.table(cat = c(rep("A", 2), rep("B", 2)),
                  start = c(2, 1, 10, 17),
                  end = c(7, 3, 12, 20))

# convert to sequence
dt1 = dt1[, .(sequence = start:end), by=.(cat, 1:nrow(dt1))][
          , nrow := NULL]
dt2 = dt2[, .(sequence = start:end), by=.(cat, 1:nrow(dt2))][
          , nrow := NULL]

# inner join + unique
overlap = merge(dt1, dt2)
overlap = unique(overlap)

# convert to start/end
overlap = overlap[, .(start=min(sequence), end=max(sequence)), by=.(cat)]

# result
overlap
#>    cat start end
#> 1:   A     1   7
#> 2:   B    17  20