在数据框中匹配其他数据框

时间:2017-04-25 16:32:20

标签: r match rounding

您好我有一个匹配两个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")

Dataframe 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")

有人知道如何做到这一点,特别是对于大型数据集吗?

非常感谢!

3 个答案:

答案 0 :(得分:3)

使用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提供了不匹配的行。要切换它...... DF2[is.na(D), D := NaN]

要删除新的DF2$A列,请使用DF2[, A := NULL]

  

有人知道如何做到这一点,特别是对于大型数据集吗?

这会修改DF2(而不是像Mike的回答那样创建像vanilla join这样的新表),因此对于大型表来说它应该是相当有效的。如果在两个表中将A存储为整数而不是浮点数,它可能会表现得更好。

在data.table 1.9.6上,使用on="A", B代替on=.(A), x.B。感谢Mike H检查这个。

答案 1 :(得分:2)

您可以创建一个查找表,其中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

答案 2 :(得分:2)

对于这些类型的合并,我喜欢sql:

string DecryptedText = Decrypt("GENERATED_KEY", "MY_16_CHAR_KEY:)");