【发布时间】:2021-11-20 18:21:32
【问题描述】:
我可以通过类似的方式将数据框中的列的匹配副本复制到另一个中
DF2$y <- DF1[match(DF2$id2, DF1$id1), "z"] # DF1 and DF2 are data frames
DF2$id2 与 DF1$id1 匹配。我想知道对于这种操作我可以用 数据表 做什么。我的数据表有数百万行和数百列。我已经完成了setkey(DT1, id1) 和setkey(DT2, id2)。
这行得通:
DT2[, y := DT1[match(DT2$id2, DT1$id1), "z"]] # DT1 and DT2 are data tables
但我担心match 部分可能会花费很长时间。 (或者这是不可避免的?)
我了解我还可以使用列选择、merge 和重命名:
tmp <- DT1[, c("id1", "z")] # column selection
DT3 <- merge(DT2, tmp, by.x = "id2", by.y = "id1", all.x = TRUE, suffixes = c("", ".y")) # merge
setnames(DT3, "z.y", "y") # rename
(前两行可以写在一行上)但这似乎有点太复杂了。会有更简单快捷的解决方案吗?
谢谢。
例子:
library(data.table)
DF1 <- data.frame(id1=2:4, x=LETTERS[1:3], z=11:13)
DF2 <- data.frame(id2=1:4, x=LETTERS[5:8], z=21:24)
DF1
# id1 x z
# 1 2 A 11
# 2 3 B 12
# 3 4 C 13
DF2
# id2 x z
# 1 1 E 21
# 2 2 F 22
# 3 3 G 23
# 4 4 H 24
DT1 <- data.table(DF1)
DT2 <- data.table(DF2)
setkey(DT1, id1)
setkey(DT2, id2)
DF2$y <- DF1[match(DF2$id2, DF1$id1), "z"]
DF2 # correct
# id2 x z y
# 1 1 E 21 NA
# 2 2 F 22 11
# 3 3 G 23 12
# 4 4 H 24 13
DT2[, y := DT1[match(DT2$id2, DT1$id1), "z"]]
DT2
# id2 x z y
# 1: 1 E 21 NA
# 2: 2 F 22 11
# 3: 3 G 23 12
# 4: 4 H 24 13
DT2[, y := NULL]
tmp <- DT1[, c("id1", "z")]
DT3 <- merge(DT2, tmp, by.x = "id2", by.y = "id1", all.x = TRUE, suffixes = c("", ".y"))
setnames(DT3, "z.y", "y")
DT3
# id2 x z y
# 1: 1 E 21 NA
# 2: 2 F 22 11
# 3: 3 G 23 12
# 4: 4 H 24 13
## Simpler alternatives?
【问题讨论】:
-
@GregorThomas 谢谢。但我只想“合并”一个变量,而不是完整的数据集。为此,我需要按照我在问题中的解释进行列选择、合并,然后重命名。有更简单的方法吗?
-
merge很简单。对于这个特定的示例,您的 ID 列的名称不匹配,并且您要添加的列的名称需要更改,但重命名是一种非常有效的单行代码,这很烦人。 -
我同意你的担心——我希望
data.table::merge比base::match快得多,尤其是在键控表上。但我不同意您的看法,即重命名几列过于复杂。 -
或者更简单一点,
merge(DT2, setnames(DT1[, c("id1", "z")], c("id2", "y")), all.x = TRUE) -
@GregorThomas 当然。谢谢。我想知道是否还有其他解决方案,我很高兴得知我不需要寻找其他解决方案。我已经在这个问题上徘徊了这么久。
标签: r data.table