有时,当加入日期或与日期匹配时,如果两个日期相隔一天或两天并不重要。最近的一个例子发生在我使用快速财务管理软件的时候。我的快速对账出了点问题。我现在有了一张来自奎宁的交易表和另一张从我的银行下载的交易表。我使用data.table从两个单独的表中创建了一个rbindlist。我想找出在另一个表中哪些事务没有对应项。如果日期与美元和美分的数量完全一致,那就很容易了。但有时日期是2或3或4或5天,但不是2个月。使用data.table或基R(或者如果我真的必须,tidyverse),如果日期只有几天休假,我如何允许匹配?
示例
rep.exmpl <- data.table(date = as.IDate(c("2022-10-23", "2022-10-23", "2022-10-20", "2022-10-20", "2022-10-15", "2022-10-12", "2022-10-05", "2022-10-01", "2022-09-30", "2022-08-05")), amount = c(10.00, 10.00, 1.53, 1.53, 78.00, 78.00, 89.56, 65.01, 65.01, 65.01), source = c("bank", "quicken", "bank", "quicken","bank", "quicken", "bank", "bank", "quicken", "quicken"))
rep.exmpl rep.exmpl代表“可复制的例子”。
date amount source
1: 2022-10-23 10.00 bank
2: 2022-10-23 10.00 quicken
3: 2022-10-20 1.53 bank
4: 2022-10-20 1.53 quicken
5: 2022-10-15 78.00 bank
6: 2022-10-12 78.00 quicken
7: 2022-10-05 89.56 bank
8: 2022-10-01 65.01 bank
9: 2022-09-30 65.01 quicken
10: 2022-08-05 65.01 quicken我使用fsetdiff来查看一个源中的内容,而不是另一个源中的内容。
fsetdiff(x = rep.exmpl[source=="bank", .(date, amount)], y = rep.exmpl[source=="quicken", .(date, amount)])# in bank only
fsetdiff(x = rep.exmpl[source=="quicken", .(date, amount)], y = rep.exmpl[source=="bank", .(date, amount)])# in quicken only第5行和第6行应该被视为相同的,因为它们仅相隔3天,因此不应将其显示为只出现在一个源中的事务。第7行应该给我看,因为它只出现在银行里。第10行应该显示给我,因为与第8行和第9行相比,第8行和第9行显然是不同的,在银行中没有任何匹配的地方。但事实并非如此。其中有些是可行的,但很多则行不通。
只在银行
date amount
1: 2022-10-15 78.00
2: 2022-10-05 89.56
3: 2022-10-01 65.01 第1行和第3行不应显示。
只在奎宁
date amount
1: 2022-10-12 78.00
2: 2022-09-30 65.01
3: 2022-08-05 65.01第1行和第2行不应显示。只应显示第3行。
你将如何巧妙地解决这个问题?我想尝试在快速表中创建几个+/- 7天的列,然后使用滚动连接(roll = TRUE)或者可能是快速重叠连接(foverlaps)。我的一个问题是模糊日期匹配可能是向后的或向前的。
发布于 2022-10-24 05:51:14
你可以用roll="nearest"
bank <- rep.exmpl[source=="bank", .(date, amount)]
quicken <- rep.exmpl[source=="quicken", .(date, amount)]
maxdays <- 7
bank[quicken,.(bank.date=x.date,quicken.date=date,bank.amount=x.amount,quicken.amount=amount)
,on=.(amount,date)
,roll='nearest'][abs(difftime(bank.date,quicken.date,unit="days"))>maxdays|is.na(bank.date)]
# bank.date quicken.date bank.amount quicken.amount
# <IDat> <IDat> <num> <num>
#1: 2022-10-01 2022-08-05 65.01 65.01
quicken[bank,.(bank.date=date,quicken.date=x.date,bank.amount = amount,quicken.amount = x.amount)
,on=.(amount,date)
,roll='nearest'][abs(difftime(bank.date,quicken.date,unit="days"))>maxdays]
# bank.date quicken.date bank.amount quicken.amount
# <IDat> <IDat> <num> <num>
#1: 2022-10-05 <NA> 89.56 NA发布于 2022-10-26 11:02:56
您也可以使用非赤道联接。我不知道哪一种方式更有效,但是有选择是很好的!
range <- 7
rep.exmpl[
rep.exmpl[,
.(amount,
low = date - range, # Create the date range in i
high = date + range,
source)],
.(amount,
date = x.date, # Relabel cols in join for interpretation
present.source = source,
missing.source = i.source),
on = .(amount, # Equi-join on amount
date >= low, # Non-equi join on date ranges
date <= high)][,
.SD[all(present.source == missing.source)], # Rows where only one source matched from the join
.(amount, date)] # By amount and datehttps://stackoverflow.com/questions/74176606
复制相似问题