当他们用不同的标识符表示时,我如何识别 1 个 ID 下的唯一人

时间:2021-06-11 19:07:41

标签: sql r postgresql

我试图通过提供唯一标识符来确保所有相同的客户不会被表示为多人。 我正在处理的信息是事务性的,因此每笔交易都可能在不同的时间记录不同的信息。

如果“A”人使用电子邮件“A”和电话“A”

“B”使用电子邮件“A”和电话“B”

“C”使用电子邮件“B”和电话“B”

我想推断出 Person 'A' = Person 'B' = Person 'C',即使标识符存在变化。

下面是一个示例表

起点:

<头>
名字 姓氏 电子邮件 电话 街道地址
j 杰克逊 jj@gmail 12 619 丁香
乔恩 杰克逊 jj@gmail 34
乔恩 杰克逊 jj@yahoo 34
玛丽亚 杰克逊 maj@gmail 45 619 丁香
凯蒂 鲱鱼 katy@yahoo 67
达利亚 史密斯 ds@gmail 89 439 梧桐
达利亚 史密斯 ds@yahoo 439 梧桐

预期结果:

<头>
名字 姓氏 电子邮件 电话 街道地址 唯一客户
j 杰克逊 jj@gmail 12 619 丁香 1
乔恩 杰克逊 jj@gmail 34 1
乔恩 杰克逊 jj@yahoo 34 1
玛丽亚 杰克逊 maj@gmail 45 619 丁香 2
凯蒂 鲱鱼 katy@yahoo 67 3
达利亚 史密斯 ds@gmail 89 439 梧桐 4
达利亚 史密斯 ds@yahoo 439 梧桐 4

最终,我想找一个地方来查看家庭交易,因此可以将与孩子 (Dalia Smith/Dalia Smith jr) 具有相同姓名和电话号码的父母视为相同的唯一客户暂且。此外,我使用的地址更具体,因此我可以使用合适的数字来破译具有相同街道地址的人。

1 个答案:

答案 0 :(得分:0)

这是一种令人难以置信的蛮力方法来完成我认为您在 R 中所追求的目标。基本上:

  1. 您需要找到电话号码、电子邮件和地址的每个唯一值。这可以通过 unique() 函数

    完成
  2. 您需要找到与这些变量的每个唯一值匹配的所有行。这可以通过 match() 函数

    完成
  3. 您必须使用条件逻辑对行进行迭代比较,以确定它们是否与任何其他行匹配。可能有更优雅的解决方案,但我不是一个优雅的人,所以我将使用双 for() 循环。

  4. 您必须为唯一的行解析任何 NA 值

这是一个例子:

##Fake Data##
First_Names<-c("John", "J", "John", "Maria", "Maria", "M", "Carlos", "C", "Carlos")
Last_Names<-c("Smith", "Smith", "Jones", "Valesquez", "Hidalgo", "Hidalgo","Garcia", "Garcia", "Lopez")
Email<-c("js@mail.com", "js@mail.com", "jj@mail.com", "M.V@othermail.com", "M_Hidalgo@mail.com", "M.Hidalgo@mail.com", "C_G@othermail.com", "C_G@othermail.com", "Lopez.Carlos@mail.com")
Phone<-c("555-1111", "666-1111", "555-2222", "555-3333", "555-4444", "555-4444", "555-5555", "555-5555", "555-6666")
Address<-c("1 A st", "1 A st", "2 B st", "3 C st", "4 D st", "4 D st", "5 E st", "5 E st", "6 F st")

DF<-data.frame(First_Names=First_Names, Last_Names=Last_Names, Email=Email, Phone=Phone, Address=Address)

#List of all possible Emails, Phones, and Addresses
email<-unique(DF$Email)
phone<-unique(DF$Phone)
address<-unique(DF$Address)

#finding matching values#
email_match<-match(DF$Email,email)
phone_match<-match(DF$Phone,phone)
address_match<-match(DF$Address,address)
DF$email_match<-email_match
DF$phone_match<-phone_match
DF$address_match<-address_match

#Create a blank field for Unique ID
DF[,"UID"]<-NA

#Nasty Double, nested for loop to compare all three match variables
for(i in 1:(nrow(DF)-1)){
  if(i==1){
    DF$UID[i]<-1
  }
    
  for(j in 2:nrow(DF)){
    if(!is.na(DF$UID[j])){
     DF$UID[j]<-DF$UID[j]
    }else{
      if(DF$email_match[i]==DF$email_match[j]|
        DF$phone_match[i]==DF$phone_match[j]|
         DF$address_match[i]==DF$address_match[j]
         ){
        DF$UID[j]<-i
      }
      
      }
    }
}

##Find any non-matching values##

for(i in 1:length(DF$UID)){
  tmp<-0
  if(is.na(DF$UID[i])){
    tmp<-tmp+1
    DF$UID[i]<-max(DF$UID[-which(is.na(DF$UID))])+1
  }
}

print(DF)
相关问题