我应该如何开始考虑我更喜欢哪种语法?
我的标准是效率(这是第一)和易读性/可运维性。
这
A <- B[A, on = .(id)] # very concise!
或者说
A[B, on = .(id), comment := i.comment]
或者甚至(正如PoGibas所建议的):
A <- merge(A, B, all.x = TRUE)
为了完整起见,更基本的方法是使用< code>match():
A[, comment := B[chmatch(A[["id"]], id), comment]]
示例数据:
library(data.table)
A <- data.table(id = letters[1:10], amount = rnorm(10)^2)
B <- data.table(id = c("c", "d", "e"), comment = c("big", "slow", "nice"))
为了效率和可运维性,我更喜欢“更新连接”习语:**
DT[WHERE, v := FROM[.SD, on=, x.v]]
它是“通过引用更新某些列行 - 通过引用进行子分配”下的小插(“数据表引用语义”)
中所示内容的扩展。一旦在连接上有可用的小插图,那也应该是一个很好的参考。
这是有效的,因为它只使用 WHERE
选择的行,并修改或添加列就地,而不是像更简洁的左联接 FROM[DT, on=]
那样创建一个新表。
这使得我的代码可读性更好,因为我可以很容易地看出连接的要点是添加列< code > v ;而且我不必考虑SQL中的“左”/“右”术语,也不必考虑连接后行数是否保持不变。
它对代码维护很有用,因为如果我以后想了解DT
如何获得一个名为v
的列,我可以在代码中搜索v :=
,而FORROM[DT,on=]
会掩盖正在添加哪些新列。此外,它允许 WHERE
条件,而左连接则不允许。例如,如果使用 FROM
来“填充”现有列 v
中的 NA,这可能很有用。
与其他更新连接方法DT[from, on=, v:=i. v]
相比,我可以想到两个优点。首先是使用WHERE
子句的选项,其次是在连接出现问题时通过警告实现透明度,例如From
中的重复匹配以on=
规则为条件。这是扩展OP示例的示例:
library(data.table)
A <- data.table(id = letters[1:10], amount = rnorm(10)^2)
B2 <- data.table(
id = c("c", "d", "e", "e"),
ord = 1:4,
comment = c("big", "slow", "nice", "nooice")
)
# left-joiny update
A[B2, on=.(id), comment := i.comment, verbose=TRUE]
# Calculated ad hoc index in 0.000s elapsed (0.000s cpu)
# Starting bmerge ...done in 0.000s elapsed (0.000s cpu)
# Detected that j uses these columns: comment,i.comment
# Assigning to 4 row subset of 10 rows
# my preferred update
A[, comment2 := B2[A, on=.(id), x.comment]]
# Warning message:
# In `[.data.table`(A, , `:=`(comment2, B2[A, on = .(id), x.comment])) :
# Supplied 11 items to be assigned to 10 items of column 'comment2' (1 unused)
id amount comment comment2
1: a 0.20000990 <NA> <NA>
2: b 1.42146573 <NA> <NA>
3: c 0.73047544 big big
4: d 0.04128676 slow slow
5: e 0.82195377 nooice nice
6: f 0.39013550 <NA> nooice
7: g 0.27019768 <NA> <NA>
8: h 0.36017876 <NA> <NA>
9: i 1.81865721 <NA> <NA>
10: j 4.86711754 <NA> <NA>
在左联接风格的更新中,即使 id == “e”
有两个匹配项,您也会静默地获得注释
的最终值;而在另一个更新中,您会收到一条有用的警告消息(在将来的版本中已升级为错误)。即使使用左连接方法打开 verbose=TRUE
也没有提供信息 - 它说有四行正在更新,但没有说一行正在更新两次。
我发现,当我的数据被安排到一组整洁/关系表中时,这种方法效果最好。哈德利·威克姆的论文就是一个很好的参考。
** 在此成语中,on=
部分应使用联接列名称和规则进行填充,如 on=(id)
或 on=.(from_date
下面是Matt Dowle解释< code>roll=
的一个更复杂的例子:为每一行查找特定值最近出现的时间
另一个相关示例:使用 data.table 进行左连接
我有两个结构相同的data.table。两个键列后跟许多数据列。数据列的数量可能会有所不同。我想将第二data.table的值添加到第一data.table.的相应行/列中 到目前为止,我的最佳选择如下: 请注意,nrow 和 ncol 以及 loc 和产品条目都是可变的,具体取决于源数据。 如果 DT2 中的每一行都与 DT1 中的一行匹配,则此方法有效,否则会产生意外的结果。有没有一种更严格/
我正在使用Ingres 11.0 DB,不确定它是否在其他数据库引擎上具有相同的行为,但这里是它 它不会返回表1中的所有记录,但我使用的是左连接,它应该从T1返回aa记录,从t2只处理行,只返回1条记录 如果我将其中一个条件从where子句移动到join条件,它的开始将返回我所期望的结果 问题是为什么它不工作在哪里所有搜索条件在哪里子句,但工作时,我移动t2.id_number从哪里加入条件? 我
当我添加一个左连接来获取外部表的计数时,它将我其他左连接表的总和值与计数相乘,我也不能在这里使用不同的总和,因为两个值可以是相同的:
我试图更多地理解滚动加入的工作方式,并有一些困惑,我希望有人能为我澄清这一点。举一个具体的例子: 我希望这会生成一个长的,其中滚动中的值: 另外,文档中说: 这使得看起来只有X中的东西应该返回,而正在执行的联接是内部联接,而不是外部联接。如果,但是中不存在特定的呢?再玩一点,我不明白列中有什么值。
主要内容:Oracle LEFT JOIN子句简介,Oracle LEFT JOIN示例在本教程中,您将学习如何使用Oracle 子句来查询多个表中的数据。 Oracle LEFT JOIN子句简介 以下语句说明连接两个表和时的子句的语法: 在这个查询中,是左表,是右表。查询将表中的每一行与表中的行进行比较。如果和表中的一对行满足连接谓词,查询将组合两个表中行的列值,并将结果行记录包含在结果集中。 如果表中的行在表中没有找到匹配的行,则查询将会将SELECT子句中出现在表的每个列的值
LEFT OUTER JOIN 左外连接 [ ] 需求:查询所有分类,如果该分类下没有商品,则不显示该分类 [ ] 实现: SELECT `goods`.`id`, `goods`.`title`, `goods`.`price`, `goods`.`cate_id`, `cate`.`id`, `cate`, `cate.title` F