【问题标题】:data.table merge on duplicate column name / how to write J corresponding to names in Y?data.table 合并重复的列名/如何编写与 Y 中的名称相对应的 J?
【发布时间】:2013-12-24 21:43:33
【问题描述】:

我在使用 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 两次:一次用于“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
...

第一次合并(对于“发件人”列)很简单: 边[节点] 第二个更难,因为它需要一个单独的 by 参数(用于“To”列)。但是指定 by 参数会强制您同时指定 j。但是如何才能引用合并完成后才会创建的 new 列呢?

edges[nodes, ????, To]

也许我在这里完全偏离了轨道,有一种更好的方法可以做到这一点。

【问题讨论】:

  • 这不是 data.table 但如果你将节点和边转换为数据帧edges_df &lt;- as.data.frame(edges); nodes_df &lt;- as.data.frame(nodes) 那么 SQL 支持多路连接,可以像这样使用: library(sqldf); sqldf("select e.*, n1.Name as FromName, n2.Name as ToName from edges_df e, nodes_df n1, nodes_df n2 on e.'From' = n1.NodeID and e.'To' = n2.NodeID") `

标签: r data.table


【解决方案1】:

我会设置两次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 我知道我遗漏了一些关于 data.table 的非常基本的东西。
【解决方案2】:

听起来您正在尝试执行以下操作:

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”列出现在输出中,您也可以再次与“edges”合并:

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

【讨论】:

    猜你喜欢
    • 2013-05-26
    • 2015-05-24
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    相关资源
    最近更新 更多