R:基于多个变量/列/约束查找相似/"duplicate"条目对

标签 r duplicates stata matching

我对 R 比较陌生,对 stackoverflow 也完全陌生(无论如何,我在这里进行了很多研究,因为我之前在 Stata、Excel、VBA 和 Little C 方面有一些经验)。

我有一个 R 数据帧 df1,类似于以下示例,只有几千行:

ID       Date         Value  Class  ZIP 
TRA0001  2007-09-25   150    1      75019
TRA0002  2002-08-09   200    2      30152
TRA0003  2010-08-31   500    3      12451
TRA0004  2005-06-17   75     1      45242
TRA0005  2010-08-26   410    3      14618
TRA0006  2008-07-07   155    1      70139
TRA0007  2010-01-15   450    3      12883
TRA0008  2000-11-03   80     4      45242
TRA0009  2003-05-01   120    2      63017
TRA0010  2000-10-01   85     5      23712

每一行代表一个交易。我需要找到的是基于以下“匹配标准”(AND 连接)组合的每笔交易的相似交易:

  1. 日期必须在 +/- 18 个月内,例如对于 TRA0001,唯一的匹配项是 TRA 0006
  2. 必须在原始行值的 +/- 20% 范围内,例如TRA0001 的匹配项将是 TRA0006 和 TRA0009
  3. 类别必须完全匹配,例如根据此标准,TRA0001 的匹配项将为 TRA0004 和 TRA0006

请注意,每个事务/行不能有匹配项、一个匹配项或多个匹配项。我最终需要的是一个关于上述三个标准组合的匹配列表。

对于给定的示例,结果 df2 将如下所示:

ID       ID_Match   ZIP_Match
TRA0001  TRA0006    70139
TRA0003  TRA0005    14618
TRA0003  TRA0007    12883
TRA0005  TRA0007    12883
TRA0006  TRA0001    75019
TRA0007  TRA0003    12451
TRA0007  TRA0005    14618

到目前为止,我尝试了重复搜索的各种组合,通过满足至少一个匹配条件并根据其他约束“过滤”此结果来更接近我想要的结果。我从类别条件开始,因为在我看来这是最简单的标准(也可能是最具选择性的)。我最终想到的只是一个包含重复项的所有类的列表,以及可以找到重复项的相应索引位置。为此,我使用了以下代码(在 stackoverflow 上找到,归功于用户“eddi”):

dups = duplicated(df1$Class) | duplicated(d1$Class, fromLast = T)
split(which(dups), df1$Class[dups])

但是,这仍然离我想要的结果很远,而且我不知道如何“整合”其他条件。希望我能提供所有必要的信息并能澄清我的问题。任何类型的提示、建议或解决方案都非常受欢迎!提前致谢!

此外:如果有人提出如何使用 Stata 完成所需工作的想法,这也将受到欢迎 - 我对 Stata 的了解比 R 略多一些。

最佳答案

我想我找到了一种方法可以做到这一点。基本上,我们定义一个函数,它将为一个 ID 执行您想要的操作,然后使用 sapply 迭代所有 ID,然后使用对 rbind 的调用来放置结果一起。

月数函数来自@Dirk,在 this post

df <- read.table(text = 
          "ID       Date         Value  Class  ZIP 
           TRA0001  2007-09-25   150    1      75019
           TRA0002  2002-08-09   200    2      30152
           TRA0003  2010-08-31   500    3      12451
           TRA0004  2005-06-17   75     1      45242
           TRA0005  2010-08-26   410    3      14618
           TRA0006  2008-07-07   155    1      70139
           TRA0007  2010-01-15   450    3      12883
           TRA0008  2000-11-03   80     4      45242
           TRA0009  2003-05-01   120    2      63017
           TRA0010  2000-10-01   85     5      23712", 
           header = T)
# turn a date into a 'monthnumber' relative to an origin
monnb <- function(d) { 
      lt <- as.POSIXlt(as.Date(d, origin="1900-01-01"))
      lt$year*12 + lt$mon
    } 

# compute a month difference as a difference between two monnb's
mondf <- function(d1, d2) { monnb(d2) - monnb(d1) }

find_fxn <- function(data, origID){
  #create subset with ID of interest
  orig_data <- subset(data, ID == origID)
  #subset of all other IDs
  other_data <- subset(data, ID != origID)
  #three matching criteria
  find_first <- which(abs(mondf(orig_data$Date, other_data$Date)) <= 18)
  find_second <- which(other_data$Value >= 0.8 * orig_data$Value & other_data$Value <= 1.2 * orig_data$Value)
  find_third <- which(other_data$Class == orig_data$Class)
  #use intersect to remove dups
  find_all <- intersect(intersect(find_first, find_second), find_third)
  if(length(find_all) > 0){
  cbind.data.frame(ID = orig_data$ID, 
                   IDMatch = other_data[find_all, 1],
                   ZipMatch = other_data[find_all, 5])
  }
}

do.call('rbind', sapply(df$ID, FUN = function(x) find_fxn(data = df, origID = x)))

       ID IDMatch ZipMatch
1 TRA0001 TRA0006    70139
2 TRA0003 TRA0005    14618
3 TRA0003 TRA0007    12883
4 TRA0005 TRA0007    12883
5 TRA0006 TRA0001    75019
6 TRA0007 TRA0003    12451
7 TRA0007 TRA0005    14618

关于R:基于多个变量/列/约束查找相似/"duplicate"条目对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37630794/

相关文章:

r - plm 函数和异方差鲁棒标准误差

R:按团队计算平均值

mysql - 如何检查mysql表中多列的重复项

ms-word - 如何在 Word 中为 Stata 中的相关表生成输出?

r - 像Stata命令计数一样如何计算R中的观察数

html - 为什么 extractHTMLStrip() from tm.plugin.webmining 会截断 61 个字符以下的字符串?

r - 在 R 中对数据行或列进行分组

php - Array Unique with Associative Array - 删除重复项

mysql - 如何删除 mySQL 重复条目

loops - 在 Stata 中通过字符串对循环