bar*_*rka 5 merge r data.table
我有两组数据。
样本set_A(总行数:45467):
ID_a a1 a2 a3 time_a
2 35694 5245.2 301.6053 00.00944
3 85694 9278.9 301.6051 23.00972
4 65694 9375.2 301.6049 22.00972
5 85653 4375.5 301.6047 19.00972
6 12694 5236.3 301.6045 22.00972
7 85697 5345.2 301.6043 21.00972
8 85640 5274.1 301.6041 20.01000
9 30694 5279.0 301.6039 20.01000
Run Code Online (Sandbox Code Playgroud)
样本set_B(总行数:4798):
ID_b b1 b2 source time_b
2 34.20 15.114 set1.csv.1 20.35750
7 67.20 16.114 set1.csv.2 21.35778
12 12.20 33.114 set1.csv.3 22.35806
17 73.20 67.114 set2.csv.1 23.35833
23 88.20 42.114 set2.csv.2 19.35861
28 90.20 52.114 set3.csv.1 00.35889
Run Code Online (Sandbox Code Playgroud)
我对结果感兴趣,其中set_B、 的行与和的set_A最接近的值匹配(输出行总数:4798)。In的值可以重复多次(例如和) - 哪一行将与来自的行合并(在本例中为)并不重要。预期结果示例:time_atime_bset_Atime_aID_a[8,][ID_a[9,]set_BID_b[1,]
ID_b b1 b2 source time_b ID_a a1 a2 a3 time_a
2 34.20 15.114 set1.csv.1 20.35750 8 85640 5274.1 301.6041 20.01000
7 67.20 16.114 set1.csv.2 21.35778 7 85697 5345.2 301.6043 21.00972
12 12.20 33.114 set1.csv.3 22.35806 4 65694 9375.2 301.6049 22.00972
17 73.20 67.114 set2.csv.1 23.35833 3 85694 9278.9 301.6051 23.00972
23 88.20 42.114 set2.csv.2 19.35861 5 85653 4375.5 301.6047 19.00972
28 90.20 52.114 set3.csv.1 00.35889 2 35694 5245.2 301.6053 00.00944
Run Code Online (Sandbox Code Playgroud)
我在 stackoverflow 上遇到了很多类似的问题,我真的很喜欢data.table库代码,因为它们看起来非常优雅。然而,我做了几次失败的尝试,我收到了一个基于两组(总行数 45467)构建的表,或者仅将一列合并time_a到set_B...不过,我不会挑剔,如果有人有其他想法我将非常感谢您的帮助。
我正在处理的代码示例:
setDT(set_B)
setDT(set_A)
setkey(set_B, time_b) [, time_a:=time_b]
test_ab <- set_B[set_A, roll='nearest']
Run Code Online (Sandbox Code Playgroud)
结果,我不仅收到一个包含应被忽略的数据的表,而且收到列名称中的“混乱”(例如,包含ID_a值的列称为time_a)。
我真的很感谢你的帮助!
以下是基于您提供的示例数据的分步示例:
# Sample data
library(data.table)
setDT(set_A)
setDT(set_B)
# Create time column by which to do a rolling join
set_A[, time := time_a]
set_B[, time := time_b]
setkey(set_A, time)
setkey(set_B, time)
# Rolling join by nearest time
set_merged <- set_B[set_A, roll = "nearest"]
unique(set_merged[order(ID_b)], by = "time")
# ID_b b1 b2 source time_b time ID_a a1 a2 a3
# 1: 2 34.2 15.114 set1.csv.1 20.35750 20.01000 8 85640 5274.1 301.6041
# 2: 7 67.2 16.114 set1.csv.2 21.35778 21.00972 7 85697 5345.2 301.6043
# 3: 12 12.2 33.114 set1.csv.3 22.35806 22.00972 4 65694 9375.2 301.6049
# 4: 17 73.2 67.114 set2.csv.1 23.35833 23.00972 3 85694 9278.9 301.6051
# 5: 23 88.2 42.114 set2.csv.2 19.35861 19.00972 5 85653 4375.5 301.6047
# 6: 28 90.2 52.114 set3.csv.1 0.35889 0.00944 2 35694 5245.2 301.6053
# time_a
# 1: 20.01000
# 2: 21.00972
# 3: 22.00972
# 4: 23.00972
# 5: 19.00972
# 6: 0.00944
Run Code Online (Sandbox Code Playgroud)
两条评论:
time中的原始时间列之一。如果需要,您可以随时在连接后删除该列。set_Aset_Btimeunique删除重复的行。您在帖子中提到“合并哪一行并不重要”,但如果您确实想保留特定行,则可能需要调整这行代码。timeID_bset_A正如@Henrik 指出的,您所追求的实际上是关于 的滚动联接set_B,在这种情况下您不需要处理重复的行。
这意味着
library(data.table)
setDT(set_A)
setDT(set_B)
# Create time column by which to do a rolling join
set_A[, time := time_a]
set_B[, time := time_b]
set_A[set_B, on = "time", roll = "nearest"][order(ID_a)]
# ID_a a1 a2 a3 time_a time ID_b b1 b2 source
#1: 2 35694 5245.2 301.6053 0.00944 0.35889 28 90.2 52.114 set3.csv.1
#2: 3 85694 9278.9 301.6051 23.00972 23.35833 17 73.2 67.114 set2.csv.1
#3: 5 85653 4375.5 301.6047 19.00972 19.35861 23 88.2 42.114 set2.csv.2
#4: 6 12694 5236.3 301.6045 22.00972 22.35806 12 12.2 33.114 set1.csv.3
#5: 7 85697 5345.2 301.6043 21.00972 21.35778 7 67.2 16.114 set1.csv.2
#6: 9 30694 5279.0 301.6039 20.01000 20.35750 2 34.2 15.114 set1.csv.1
# time_b
#1: 0.35889
#2: 23.35833
#3: 19.35861
#4: 22.35806
#5: 21.35778
#6: 20.35750
Run Code Online (Sandbox Code Playgroud)
set_A <- read.table(text =
"ID_a a1 a2 a3 time_a
2 35694 5245.2 301.6053 00.00944
3 85694 9278.9 301.6051 23.00972
4 65694 9375.2 301.6049 22.00972
5 85653 4375.5 301.6047 19.00972
6 12694 5236.3 301.6045 22.00972
7 85697 5345.2 301.6043 21.00972
8 85640 5274.1 301.6041 20.01000
9 30694 5279.0 301.6039 20.01000", header = T)
set_B <- read.table(text =
"ID_b b1 b2 source time_b
2 34.20 15.114 set1.csv.1 20.35750
7 67.20 16.114 set1.csv.2 21.35778
12 12.20 33.114 set1.csv.3 22.35806
17 73.20 67.114 set2.csv.1 23.35833
23 88.20 42.114 set2.csv.2 19.35861
28 90.20 52.114 set3.csv.1 00.35889", header = T)
Run Code Online (Sandbox Code Playgroud)