我有三个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函数。任何人都可以提出有效解决这个问题的想法吗?非常感谢
答案 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]