gpt4 book ai didi

r - 首选使用哪种data.table语法进行左联接(一列)

转载 作者:行者123 更新时间:2023-12-04 10:06:29 25 4
gpt4 key购买 nike

我应该如何开始考虑首选哪种语法?

我的标准是效率(这是第一位)以及可读性/可维护性。


A <- B[A, on = .(id)] # wow such. concision

或者那个
A[B, on = .(id), comment := i.comment]

甚至(如PoGibas所建议的那样):
A <- merge(A, B, all.x = TRUE)

为了完整起见,一种更基本的方法是使用 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]]

它是 vignette("datatable-reference-semantics")中“按引用更新某些列的行-按引用子分配”下显示的内容的扩展。一旦在连接上有一个小插图可用,那也应该是一个很好的引用。

这是有效的,因为它仅使用 WHERE选择的行并就地修改或添加列,而不是像更简洁的左连接 FROM[DT, on=]一样创建新表。

因为我可以很容易地看到联接的重点是添加列 v,所以它使我的代码更具可读性;而且我不必考虑SQL中的“左”/“右”行话,也不必考虑联接后是否保留行数。

这对代码维护很有用,因为如果以后我想找出 DT如何获得名为 v的列,则可以在我的代码中搜索 v :=,而 FROM[DT, on=]则遮盖了要添加的新列。另外,它允许 WHERE条件,而左联接则不允许。例如,如果是 using FROM to "fill" NAs in an existing column v ,这可能会很有用。

与其他更新联接方法 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>

在左连接风格的更新中,即使 comment有两个匹配项,您也可以默默地获得 id == "e"的最终值;在其他更新中,您会收到一条有用的警告消息(已升级为 an error in a future release)。即使使用左连接方法打开 verbose=TRUE也不能提供信息-它说有四行被更新,但没有说一行被更新了两次。

我发现,当我将数据整理到一组整洁/关系表中时,这种方法最有效。一个很好的引用是 Hadley Wickham's paper

**在此惯用语中, on=部分应使用连接列名称和规则(例如 on=.(id)on=.(from_date >= dt_date))填充。可以使用 roll=mult=nomatch=传递其他加入规则。有关详细信息,请参见 ?data.table。感谢@RYoda在评论中指出这一点。

这是Matt Dowle解释 roll=的更复杂的示例: Find time to nearest occurrence of particular value for each row

另一个相关示例: Left join using data.table

关于r - 首选使用哪种data.table语法进行左联接(一列),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54312225/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com