我想列出一个包含关联“所有者”和日期的电子邮件列表,并将其与传入的订单进行匹配,并附上日期和值。匹配的密钥是电子邮件,但我希望它匹配最近的日期,因为在某些情况下,电子邮件地址可能有2个不同的所有者。
可重复的例子:
require(dplyr)
e <- c("e3r@gmail.com", "e3r@gmail.com", "poi@aol.com", "tyu@gmail.com", "poi@aol.com", "tyu@gmail.com")
d <- c("2017-01-01", "2017-04-05", "2017-04-12", "2017-05-05", "2017-08-05", "2017-12-05")
p <- c("Jeff", "Sam", "Sam", "Jeff", "Matt", "Matt")
df <- data_frame(e, d, p) %>% mutate(d=as.Date(d))
o <- c("e3r@gmail.com", "poi@aol.com", "sdf@gmail.com", "tyu@gmail.com")
d2 <- c("2017-02-02", "2017-04-28", "2017-05-05", "2017-07-01")
a <- c(600.50, 3000, 4999.99, 2050.6)
df2 <- data_frame(o, d2, a) %>% mutate(d2 = as.Date(d2))
第一个df是电子邮件地址的地图归p
人所有。 df2
是这些电子邮件地址附带的订单,我想在df2
添加一个列,其中包含正确的“所有者”,无论谁拥有分配给他们的电子邮件地址和的日期最接近。
期望的结果:
> df2
# A tibble: 4 x 3
o d2 a newowner
<chr> <date> <dbl> <char>
1 e3r@gmail.com 2017-02-02 600.50 "Jeff"
2 poi@aol.com 2017-04-28 3000.00 "Sam"
3 sdf@gmail.com 2017-05-05 4999.99 NA
4 tyu@gmail.com 2017-07-01 2050.60 "Jeff"
目前,这不是一个大问题 - 在“拥有”电子邮件地址的70k记录中,只有约86个重复案例。但是,所有权在一年的最后几个月都在发生变化,因此如果所有权转移,可能会引入大量重复。我目前正在从最远的日期开始接收所有者,并在这86个例子中覆盖其他所有者。
感谢您的帮助!
答案 0 :(得分:6)
这是data.table中的标准滚动更新连接:
library(data.table)
DT = data.table(df)
DT2 = data.table(df2)
DT2[DT, on=.(o = e, d2 = d), roll=-Inf, v := i.p ]
o d2 a v
1: e3r@gmail.com 2017-02-02 600.50 Jeff
2: poi@aol.com 2017-04-28 3000.00 Sam
3: sdf@gmail.com 2017-05-05 4999.99 NA
4: tyu@gmail.com 2017-07-01 2050.60 Jeff
如果根据标题,您想要最近的匹配,请使用roll = "nearest"
代替roll = -Inf
。
Dplyr没有滚动连接,并且永远不会有更新连接,所以那里没有类似的东西。
答案 1 :(得分:1)
@Frank的答案很棒,就像他说的那样,data.table
有滚动连接但dplyr
没有。所以我认为data.table
在这里是更好的选择。但是,如果你想留在dplyr
。这是一个想法。
library(dplyr)
df3 <- df %>%
full_join(df2, by = c("e" = "o")) %>%
mutate(Date_ABS_Diff = abs(d - d2)) %>%
arrange(e, Date_ABS_Diff) %>%
group_by(e) %>%
slice(1) %>%
select(o = e, d2, a, newowner = p)
df3
# A tibble: 4 x 4
# Groups: o [4]
o d2 a newowner
<chr> <date> <dbl> <chr>
1 e3r@gmail.com 2017-02-02 600.50 Jeff
2 poi@aol.com 2017-04-28 3000.00 Sam
3 sdf@gmail.com 2017-05-05 4999.99 <NA>
4 tyu@gmail.com 2017-07-01 2050.60 Jeff
此方法使用full_join
通过电子邮件组合所有可能的组合。之后,计算日期之间的绝对差异,并使用arrange
和slice
选择具有最小绝对日期的记录。