通过其他数据帧列中最接近的值匹配数据帧中的列
Matching column in dataframe by nearest values in column of other dataframe
你好,我有一个匹配两个的问题data.frames。
假设我有两个数据集:
数据框 1:
"A" "B"
91 1
92 3
93 11
94 4
95 10
96 6
97 7
98 8
99 9
100 2
structure(list(A = 91:100, B = c(1, 3, 11, 4, 10, 6, 7, 8, 9,
2)), .Names = c("A", "B"), row.names = c(NA, -10L), class = "data.frame")
数据框 2:
"C" "D"
91.12 1
92.34 3
93.65 11
94.23 4
92.14 10
96.98 6
97.22 7
98.11 8
93.15 9
100.67 2
91.45 1
96.45 3
83.78 11
84.66 4
100 10
structure(list(C = c(91.12, 92.34, 93.65, 94.23, 92.14, 96.98,
97.22, 98.11, 93.15, 100.67, 91.25, 96.45, 83.78, 84.66, 100),
D = c(1, 3, 11, 4, 10, 6, 7, 8, 9, 2, 1, 3, 11, 4, 10)), .Names = c("C",
"D"), row.names = c(NA, -15L), class = "data.frame")
现在我想找到 A 列和 C 列之间的舍入匹配项,并将 D 列替换为 Dataframe 1 中 B 列中的相应值。如果没有相应的值(通过 A 和 C 之间的舍入匹配项),我想要为替换的列 D 获取 NaN。
result:
"C" "newD"
91.12 1
92.34 3
93.65 4
94.23 4
92.14 3
96.98 7
97.22 7
98.11 8
93.15 11
100.67 NaN
91.25 1
96.45 6
83.78 NaN
84.66 NaN
100 2
structure(list(C = c(91.12, 92.34, 93.65, 94.23, 92.14, 96.98,
97.22, 98.11, 93.15, 100.67, 91.25, 96.45, 83.78, 84.66, 100),
D = c(1, 3, 4, 4, 3, 7, 7, 8, 11, NaN, 1, 6, NaN, NaN, 2)), .Names = c("C",
"D"), row.names = c(NA, -15L), class = "data.frame")
有没有人知道如何做到这一点,尤其是对于大型数据集?
非常感谢!
您可以创建一个查找 table,其中 A 中的值用于查找 B 中的值。
Lookup = df1$B
names(Lookup) = df1$A
df3 = data.frame(C = df2$C, newD = Lookup[as.character(round(df2$C))])
df3$newD[is.na(df3$newD)] = NaN
对于这些类型的合并,我喜欢 sql:
library(sqldf)
res <- sqldf("SELECT l.C, r.B
FROM df2 as l
LEFT JOIN df1 as r
on round(l.C) = round(r.A)")
res
# C B
#1 91.12 1
#2 92.34 3
#3 93.65 4
#4 94.23 4
#5 92.14 3
#6 96.98 7
#7 97.22 7
#8 98.11 8
#9 93.15 11
#10 100.67 NA
#11 91.45 1
#12 96.45 6
#13 83.78 NA
#14 84.66 NA
#15 100.00 2
与 data.table 进行更新连接:
library(data.table)
setDT(DF1); setDT(DF2)
DF2[, A := round(C)]
DF2[, D := DF1[DF2, on=.(A), x.B] ]
# alternately, chain together in one step:
DF2[, A := round(C)][, D := DF1[DF2, on=.(A), x.B] ]
这会在不匹配的行中给出 NA
s。要切换它... DF2[is.na(D), D := NaN]
.
要删除新的 DF2$A
列,请使用 DF2[, A := NULL]
。
Does anybody knows how to do that especially for large datasets?
这会就地修改 DF2(而不是像 Mike 的回答中那样创建一个新的 table,就像普通连接),因此它对于大型 table 应该相当有效。如果 A 在两个 tables.
中都存储为整数而不是浮点数,它可能会表现更好
在 data.table 1.9.6 上,使用 on="A", B
而不是 on=.(A), x.B
。感谢 Mike H 检查这个。
你好,我有一个匹配两个的问题data.frames。
假设我有两个数据集:
数据框 1:
"A" "B"
91 1
92 3
93 11
94 4
95 10
96 6
97 7
98 8
99 9
100 2
structure(list(A = 91:100, B = c(1, 3, 11, 4, 10, 6, 7, 8, 9,
2)), .Names = c("A", "B"), row.names = c(NA, -10L), class = "data.frame")
数据框 2:
"C" "D"
91.12 1
92.34 3
93.65 11
94.23 4
92.14 10
96.98 6
97.22 7
98.11 8
93.15 9
100.67 2
91.45 1
96.45 3
83.78 11
84.66 4
100 10
structure(list(C = c(91.12, 92.34, 93.65, 94.23, 92.14, 96.98,
97.22, 98.11, 93.15, 100.67, 91.25, 96.45, 83.78, 84.66, 100),
D = c(1, 3, 11, 4, 10, 6, 7, 8, 9, 2, 1, 3, 11, 4, 10)), .Names = c("C",
"D"), row.names = c(NA, -15L), class = "data.frame")
现在我想找到 A 列和 C 列之间的舍入匹配项,并将 D 列替换为 Dataframe 1 中 B 列中的相应值。如果没有相应的值(通过 A 和 C 之间的舍入匹配项),我想要为替换的列 D 获取 NaN。
result:
"C" "newD"
91.12 1
92.34 3
93.65 4
94.23 4
92.14 3
96.98 7
97.22 7
98.11 8
93.15 11
100.67 NaN
91.25 1
96.45 6
83.78 NaN
84.66 NaN
100 2
structure(list(C = c(91.12, 92.34, 93.65, 94.23, 92.14, 96.98,
97.22, 98.11, 93.15, 100.67, 91.25, 96.45, 83.78, 84.66, 100),
D = c(1, 3, 4, 4, 3, 7, 7, 8, 11, NaN, 1, 6, NaN, NaN, 2)), .Names = c("C",
"D"), row.names = c(NA, -15L), class = "data.frame")
有没有人知道如何做到这一点,尤其是对于大型数据集?
非常感谢!
您可以创建一个查找 table,其中 A 中的值用于查找 B 中的值。
Lookup = df1$B
names(Lookup) = df1$A
df3 = data.frame(C = df2$C, newD = Lookup[as.character(round(df2$C))])
df3$newD[is.na(df3$newD)] = NaN
对于这些类型的合并,我喜欢 sql:
library(sqldf)
res <- sqldf("SELECT l.C, r.B
FROM df2 as l
LEFT JOIN df1 as r
on round(l.C) = round(r.A)")
res
# C B
#1 91.12 1
#2 92.34 3
#3 93.65 4
#4 94.23 4
#5 92.14 3
#6 96.98 7
#7 97.22 7
#8 98.11 8
#9 93.15 11
#10 100.67 NA
#11 91.45 1
#12 96.45 6
#13 83.78 NA
#14 84.66 NA
#15 100.00 2
与 data.table 进行更新连接:
library(data.table)
setDT(DF1); setDT(DF2)
DF2[, A := round(C)]
DF2[, D := DF1[DF2, on=.(A), x.B] ]
# alternately, chain together in one step:
DF2[, A := round(C)][, D := DF1[DF2, on=.(A), x.B] ]
这会在不匹配的行中给出 NA
s。要切换它... DF2[is.na(D), D := NaN]
.
要删除新的 DF2$A
列,请使用 DF2[, A := NULL]
。
Does anybody knows how to do that especially for large datasets?
这会就地修改 DF2(而不是像 Mike 的回答中那样创建一个新的 table,就像普通连接),因此它对于大型 table 应该相当有效。如果 A 在两个 tables.
中都存储为整数而不是浮点数,它可能会表现更好在 data.table 1.9.6 上,使用 on="A", B
而不是 on=.(A), x.B
。感谢 Mike H 检查这个。