在r中匹配来自多个列的数据

在r中匹配来自多个列的数据,r,match,subset,lookup,R,Match,Subset,Lookup,我有两个数据集: Contacts2:包含约100000个联系人及其各自的标题和一组列,这些列描述了可能涉及的工作联系人的类型。以下是一个示例数据集: First<-c("George","Thomas","James","Jimmy","Howard","Herbert") Last<-c("Washington", "Jefferson", "Madison", "Carter", "Taft", "Hoover") Title<-c("CEO", "Accountant"

我有两个数据集:

Contacts2:包含约100000个联系人及其各自的标题和一组列,这些列描述了可能涉及的工作联系人的类型。以下是一个示例数据集:

First<-c("George","Thomas","James","Jimmy","Howard","Herbert")
Last<-c("Washington", "Jefferson", "Madison", "Carter", "Taft", "Hoover")
Title<-c("CEO", "Accountant","Communications Specialist", "President", "Accountant", "CFO")
Finance<-NA
Executive<-NA
Communications<-NA

Contacts2<-as.data.frame(cbind(First,Last,Title,Finance,Executive,Communications))

    First       Last                     Title Finance Executive Communications
1  George Washington                       CEO    <NA>      <NA>           <NA>
2  Thomas  Jefferson                Accountant    <NA>      <NA>           <NA>
3   James    Madison Communications Specialist    <NA>      <NA>           <NA>
4   Jimmy     Carter                 President    <NA>      <NA>           <NA>
5  Howard       Taft                Accountant    <NA>      <NA>           <NA>
6 Herbert     Hoover                       CFO    <NA>      <NA>           <NA>

首先这里有一个使用
dplyr
的解决方案。这基本上是一些评论者已经建议的,只是这满足了不复制
Contacts2
最后3列中任何预先存在的数据的要求

请注意,
ifelse()
在处理大型数据集时可能会非常慢,但对于您指定的任务来说,这应该不是很明显。在算法上,这个解决方案在其他方面也有点笨拙,但我在这里追求最大的可读性

Contacts2 <- left_join(Contacts2, TableOfTitle, by = "Title") %>%
             transmute(First = First,
                       Last = Last,
                       Title = Title,
                       Finance = ifelse(is.na(Finance.x), Finance.y, Finance.x),
                       Executive = ifelse(is.na(Executive.x), Executive.y, Executive.x),
                       Communications = ifelse(is.na(Communications.x), Communications.y, Communications.x))
联系人2%
转化(第一=第一,
最后的,
头衔,
Finance=ifelse(is.na(Finance.x)、Finance.y、Finance.x),
Executive=ifelse(is.na(Executive.x),Executive.y,Executive.x),
通信=ifelse(is.na(Communications.x)、Communications.y、Communications.x))
示例输出:

First        Last                     Title Finance Executive Communications
George Washington                       CEO    <NA>        1           <NA>
Thomas  Jefferson                Accountant      1       <NA>          <NA>
James     Madison Communications Specialist    <NA>      <NA>            1
Jimmy      Carter                 President      1       <NA>          <NA>
Howard       Taft                Accountant      1       <NA>          <NA>
Herbert    Hoover                       CFO      1         1           <NA>
首末标题财务主管沟通
乔治华盛顿首席执行官1
托马斯·杰斐逊会计1
詹姆斯·麦迪逊通讯专家1
吉米·卡特总统1
霍华德·塔夫特会计师1
赫伯特·胡佛首席财务官1

为什么不
合并这两个集合呢?只需使用
合并(Contacts2,TableOfTitle,by=“Title”,all.x=TRUE)
执行一个左联接,您不需要第一个表中的财务、执行和通信列,因为它们将添加到联接中。不过,这可能是一个选项,我想做的事情有点复杂。在我的实际数据集中,Contacts2的最后三列中已经有一些值。我最终会编写一条规则,说明如果某个值已经存在,则不要替换。然后在合并之前重命名第二个数据集中的列,然后运行
ifelse
逻辑。
First        Last                     Title Finance Executive Communications
George Washington                       CEO    <NA>        1           <NA>
Thomas  Jefferson                Accountant      1       <NA>          <NA>
James     Madison Communications Specialist    <NA>      <NA>            1
Jimmy      Carter                 President      1       <NA>          <NA>
Howard       Taft                Accountant      1       <NA>          <NA>
Herbert    Hoover                       CFO      1         1           <NA>