r - 匹配一个变量后,仅将一个变量从一个 R data.table 复制到另一个
问题描述
我可以通过类似的方式将数据框中的列的匹配副本复制到另一个中
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?
解决方案
如果我理解正确,OP 想要将列z
from附加DT1
到id 列匹配的列DT2
。y
使用data.table,这可以使用更新连接来解决:
library(data.table)
DT2[DT1, on = .(id2 = id1), y := i.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
更新的,即不复制整个数据对象。这对于 OP 数百万行的大型生产数据集可能很方便。
警告
这是有效的,因为id1
并且id2
是唯一的,示例用例就是这种情况。因此,请确保在更新重复值的连接时获得所需的内容。
让我们看看如果id1
列中有重复值会发生什么,例如
万一DT1
有id1 == 4
重复
(DT1 <- data.table(id1 = c(2:4, 4), x = LETTERS[1:4], z = 11:14))
id1 x z 1: 2 A 11 2: 3 B 12 3: 4 C 13 4: 4 D 14
然后
DT2[DT1, on = .(id2 = id1), y := i.z][]
返回
id2 x z y 1: 1 E 21 NA 2: 2 F 22 11 3: 3 G 23 12 4: 4 H 24 14
所以,更新加入
- 尚未在其中创建额外的行
DT2
(这可能是您可能希望避免复制大型数据集的内容), - 如果有多个匹配项,则选择了最后一次出现的
z
。
推荐阅读
- python - 计算具有聚类中心点的向量之间的欧几里得距离
- android - 如何在 Android 10 中显示每日离线通知?
- linux - 我不知道应该在 asm/ 中的文件是什么
- matlab - 不断收到无效的表达式错误
- sql - 如何设计一个 SQL Server 表来存储冗余和唯一的数据?
- android - 在我的应用上自动激活 GameBooster 应用
- sql - 如何使用 SQL Server 数据库的参数获取存储过程的历史运行?
- python - self.__dict__ 返回 keyError
- google-cloud-platform - 具有混合工作负载的数据流作业 - 流式插入和加载作业 (Python)
- javascript - 如何将模态窗口数据传递给 servlet 页面?