如何在网格方格中获得上三角或下三角的配对data.table?

时间:2016-08-03 09:40:15

标签: r data.table

我有三个data.table,其中每个都需要在方格中相互配对。我想只走在网格方块的上/下三角形上。我敢打赌这在其他编程语言如java中有点直截了当,但我不知道如何在R中制作它。有没有人知道这样做的任何技巧?

数据

mylist <- list(
  a <- data.table(
  start=seq(1, by=9, len=10), stop=seq(6, by=9, len=10),
  ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE)),
  b <- data.table(
    start=seq(2, by=11, len=10), stop=seq(8, by=11, len=10),
    ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE)),
  c <- data.table(
    start=seq(4, by=11, len=10), stop=seq(9, by=11, len=10),
    ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE))
)

方格中所有可能的对(我手动完成):

grid <- matrix((a,a), (a,b), (a,c),
               (b,a), (b,b), (b,c),
               (c,a), (c,b), (c,c),3,3)

我无法找到合适的方法来有效地创建网格对象,所以我粗略地手工制作网格。

期望的输出:

网格对象可以是矩阵或其他一些表示。这是一个临时代码,其中想象get.ovlp返回上面提到的网格表示,但重复重叠对。我的目标是仅通过在squre网格的上/下三角走

来移除这些重复的对
library(data.table)
mylist <- list(a,b,c)
get.ovlp <- function(set, idx=1L) {
  que <- set[[idx]]
  supp <- lapply(set[-idx], function(ele_) {
    ans <- data.table::foverlaps(que, ele_)
  })
  return(supp)
}

get.ovlp函数只是玩具示例,表示如何重复配对重叠,就像网格对象所代表的那样。

我只从正方形网格上方的上/下三角(包括对角线)上走,然后使用data.table包中的foverlaps函数。任何人都可以提出有效解决这个问题的想法吗?非常感谢

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望将函数应用于mylist中找到的元素对,例如("a", "b")。例如,您可以这样做(我使用merge作为函数的示例):

require(data.table)

# your data (I named the elements a, b, and c)
mylist <- list(a = data.table(start=seq(1, by=9, len=10), stop=seq(6, by=9, len=10),
                              ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE)),
               b = data.table(start=seq(2, by=11, len=10), stop=seq(8, by=11, len=10),
                              ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE)),
               c = data.table(start=seq(4, by=11, len=10), stop=seq(9, by=11, len=10),
                              ID=letters[seq(1:10)], score=sample(1:25, 10, replace = FALSE)))


# build pairs on upper triangle
# utilise fact that >= is meaningful for characters
dt_idx = CJ(i = names(mylist), j = names(mylist))[j >= i]

# apply function (here merge) by i, j:
dt_idx[,
       j = merge(x = mylist[[i]], y = mylist[[j]], by = c('start', 'stop', 'ID')),
       by = list(i, j)]

注意: 如果列表名称上的>=操作不再“有意义”(因为名称没有排序和/或更复杂),您可以始终使用integer索引,然后应用相同的逻辑...

dt_idx = CJ(i = seq.int(length(mylist)), j = seq.int(length(mylist)))[j >= i]