首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匹配日期,但在R中使用data.table提供几天的回旋余地

匹配日期,但在R中使用data.table提供几天的回旋余地
EN

Stack Overflow用户
提问于 2022-10-24 04:04:23
回答 2查看 56关注 0票数 0

有时,当加入日期或与日期匹配时,如果两个日期相隔一天或两天并不重要。最近的一个例子发生在我使用快速财务管理软件的时候。我的快速对账出了点问题。我现在有了一张来自奎宁的交易表和另一张从我的银行下载的交易表。我使用data.table从两个单独的表中创建了一个rbindlist。我想找出在另一个表中哪些事务没有对应项。如果日期与美元和美分的数量完全一致,那就很容易了。但有时日期是2或3或4或5天,但不是2个月。使用data.table或基R(或者如果我真的必须,tidyverse),如果日期只有几天休假,我如何允许匹配?

示例

代码语言:javascript
复制
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代表“可复制的例子”。

代码语言:javascript
复制
          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来查看一个源中的内容,而不是另一个源中的内容。

代码语言:javascript
复制
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行显然是不同的,在银行中没有任何匹配的地方。但事实并非如此。其中有些是可行的,但很多则行不通。

只在银行

代码语言:javascript
复制
         date amount
1: 2022-10-15  78.00
2: 2022-10-05  89.56
3: 2022-10-01  65.01  

第1行和第3行不应显示。

只在奎宁

代码语言:javascript
复制
         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)。我的一个问题是模糊日期匹配可能是向后的或向前的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-24 05:51:14

你可以用roll="nearest"

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2022-10-26 11:02:56

您也可以使用非赤道联接。我不知道哪一种方式更有效,但是有选择是很好的!

代码语言:javascript
复制
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 date
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74176606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档