我正试图根据Addresses是否一起参与过事务来标记实体ID号。
其思想是,如果一个地址与另一个地址在一个事务中,则假设该事务中的所有地址,以及未来具有这些地址的事务中的全部地址,都归同一实体所有。
我目前正在SQL中使用循环在相当大的数据集(约1.5亿至1.8亿obs)上运行这项功能,但我觉得R的data.table可以更快、更简单的语法解决这一问题,我只是不知道如何做到。非常感谢您的帮助!
这里有一个例子:
DT <- data.table(Address=c('A','B','C','A','D','C','E'), Transaction=c(1,1,2,3,3,4,4))
Address Transaction
A 1
B 1
C 2
A 3
D 3
C 4
E 4
我正在寻找的结果是这样的:
Address Transaction Entity
A 1 1
B 1 1
C 2 2
A 3 1
D 3 1
C 4 2
E 4 2
我将继续迭代地址。对于每个地址,找到它的伙伴/邻居,并为他们提供相同的实体ID。从地址到实体的映射可以存储在一个单独的表中,并在循环完成后映射到事务表上。
setkey(DT,Address)
AE <- DT[,.(Address=unique(Address),Entity=NA_integer_)]
eid <- 0L
for (a in AE$Address){
ts <- DT[.(a)]$Transaction
fellows <- DT[Transaction %in% ts, unique(Address)]
f_ent <- AE[.(fellows)][!is.na(Entity), if (.N > 0) min(Entity) else 0L]
a_ent <- if (f_ent == 0L){
eid = eid + 1L
} else {
f_ent
}
AE[.(fellows),Entity:=a_ent]
}
DT[AE,Entity:=Entity][order(Transaction)]
# Address Transaction Entity
# 1: A 1 1
# 2: B 1 1
# 3: C 2 2
# 4: A 3 1
# 5: D 3 1
# 6: C 4 2
# 7: E 4 2
我确信这是可行的,但更一般的示例数据会有所帮助。
当你面对数百万张唱片时,你可能会想把它调整得更快一点。成本最高的步骤是计算CCD_ 1。
你几乎是在标记一个图的连接组件(参见图论)。将地址视为节点,将每个事务视为添加
- 新地址和
- 地址之间的新链接
R igraph
包可能是感兴趣的;更有可能的是,它计算连接的组件。(我对它不够熟悉,不知道。)
一般来说,如果你的数据集在增长,保持这个变量的最新将是一个真正令人头疼的问题,我认为你应该看看你是否可以不用它