【发布时间】:2015-12-16 20:35:25
【问题描述】:
我有 2 组由 id1 和 id2 表示的节点。 我有一个数据表,其中包含对节点的惩罚——键(id1,id2),值是惩罚。
我如何有效地将 data.table 划分为具有最小惩罚的节点对,以使每个节点(id1 和 id2)出现一次?
简单示例:
输入数据表:
dtIn <- data.table(
id1 = rep(letters[1:3], each=3)
, id2 = rep(1:3, 3)
, penalty = 1:9
)
setkey(dtIn, id1, id2)
print(dtIn)
id1 id2 penalty
1: a 1 1
2: a 2 2
3: a 3 3
4: b 1 4
5: b 2 5
6: b 3 6
7: c 1 7
8: c 2 8
9: c 3 9
所需的输出数据表:
id1 id2 penalty
1: a 1 1
2: b 2 5
3: c 3 9
我知道如何实现编写循环的算法:按惩罚排序,遍历记录,如果之前没有节点匹配,则按顺序挑选每一对。请参阅下面的代码。
当然,对于我的真实大小的数据,这样的循环运行速度慢得令人难以忍受。
逻辑上正确但性能太差的手动循环功能:
manualIter <- function(dtIn) {
setkey(dtIn, penalty, id1, id2) # Enusred ordered by penalty.
id1Match <- NULL; id2Match <- NULL; pen <- NULL;
for (i in seq_len(nrow(dtIn))) {
if (!(dtIn$id1[i] %in% id1Match) && !(dtIn$id2[i] %in% id2Match)) {
id1Match <- c(id1Match, dtIn$id1[i])
id2Match <- c(id2Match, dtIn$id2[i])
pen <- c(pen, dtIn$penalty[i])
}
}
# Build the return data.table for the matching ids.
dtf <- data.table(id1 = id1Match, id2 = id2Match, penalty = pen)
setkey(dtf, id1, id2)
return(dtf)
}
那么问题是如何有效地向量化这个算法呢?
【问题讨论】:
标签: r data.table