我在使用data.table进行“双重”合并时遇到了一些麻烦。这是我想用简单的英语做的事情。我有一些图形/网络数据(即节点和边缘),我想将一些节点属性合并到包含边缘的data.table中。如何将“node”data.table中的附加信息合并到“edge”data.table中两次(一次用于“From”,一次用于“To”列)?第一次合并很容易,但在第二次合并中,我似乎无法弄清楚如何将新合并的列放入我的返回DT(即编写正确的 j 语句。这是一些示例数据说明:
set.seed(1)
nodes <- data.table( NodeID=c("N1", "N2", "N3", "N4", "N5"),
Name=c("Alice", "Bob", "Charlie", "David", "Emily"),
key="NodeID")
edges <- data.table( EdgeID=1:10,
From=sample(nodes$NodeID, 10, replace=TRUE),
To=sample(nodes$NodeID, 10, replace=TRUE))
setkey(edges, From, To)
我想要的输出是有一个新的data.table,它将节点data.table中的“Name”列添加到边缘data.table TWICE:一次用于“From”列,一次用于“To”列
From EdgeID To FromName ToName
1: N1 10 N4 Alice David
2: N2 2 N1 Bob Alice
3: N2 1 N2 Bob Bob
4: N2 5 N4 Bob David
5: N3 3 N4 Charlie David
6: N4 9 N2 David Bob
...
第一次合并(对于“From”列)很简单: 边缘[节点] 第二个更难,因为它需要一个单独的 by 参数(对于“To”列)。但是指定 by 参数会强制您同时指定 j 。但是,我如何引用仅在合并完成后才会创建的 new 列?
edges[nodes, ????, To]
也许我完全偏离了这里,并且有更好的方法。
答案 0 :(得分:3)
我会将edges
的密钥设置两次,然后加入两次。
setkey(edges, From)
edges[nodes, FromName := Name]
setkey(edges, To)
edges[nodes, ToName := Name]
## one-liner
setkey(setkey(edges, From)[nodes, FromName := Name], To)[nodes, ToName := Name]
答案 1 :(得分:1)
听起来你正在尝试做类似以下的事情:
library(reshape2)
packageVersion("data.table")
# [1] ‘1.8.11’
x <- melt(edges, id.vars="EdgeID")
setkey(x, "value")
setkey(nodes, "NodeID")
dcast.data.table(nodes[x], EdgeID ~ variable, value.var="Name")
# EdgeID From To
# 1: 1 Bob Bob
# 2: 2 Bob Alice
# 3: 3 Charlie David
# 4: 4 Emily Bob
# 5: 5 Bob David
# 6: 6 Emily Charlie
# 7: 7 Emily David
# 8: 8 David Emily
# 9: 9 David Bob
# 10: 10 Alice David
基本思想是在合并之前将“边缘”data.table
转换为“长”数据集,然后在合并后将输出重新整形为“宽”形式。
注意:要使用
dcast.data.table
,您需要更新版本的“data.table”(至少版本1.8.11)。要安装最新的开发版本,请使用以下命令安装:install.packages("data.table", repos="http://R-Forge.R-project.org")
如果您希望输出中包含原始的“From”和“To”列,您还可以再次与“edge”合并:
dcast.data.table(nodes[x], EdgeID ~ variable, value.var="Name")[edges]
# EdgeID From To From.1 To.1
# 1: 1 Bob Bob N2 N2
# 2: 2 Bob Alice N2 N1
# 3: 3 Charlie David N3 N4
# ///SNIP///
# 9: 9 David Bob N4 N2
# 10: 10 Alice David N1 N4