R查找数据帧的行,其中某些列与另一列匹配

时间:2013-07-26 18:45:25

标签: r dataframe subset

我有一个R问题,我甚至不确定如何在一个句子中说出来,但却找不到答案。

我有两个数据框,我想“相交”,并找到列值在两个列中匹配的所有行。我已经尝试用&&连接两个intersect()和which()语句,但是它们都没有给我我想要的东西。

这就是我的意思。假设我有两个数据框:

> testData
               Email     Manual Campaign Bounced Opened Clicked ClickThru Unsubscribed
1 stack@overflow.com EIFLS0LS        1       0      0       0         0            0
2 stack@exchange.com EIFLS0LS        1       0      0       0         0            0
3     data@frame.com EIFLS0LS        1       0      0       0         0            0
4    block@quote.com EIFLS0LS        1       0      0       0         0            0
5          ht@ml.com EIFLS0LS        1       0      0       0         0            0
6     tele@phone.com EIFLS0LS        1       0      0       0         0            0

> testBounced
               Email Campaign
1 stack@overflow.com        1
2 stack@overflow.com        2
3     data@frame.com        2
4    block@quote.com        1
5          ht@ml.com        1
6        lap@top.com        1

如您所见,“电子邮件”列中有一些值相交,而某些值来自与Campaign相交的列。我想要testData中与BOTH列匹配的所有行。

即:

               Email     Manual Campaign Bounced Opened Clicked ClickThru Unsubscribed
1 stack@overflow.com EIFLS0LS        1       0      0       0         0            0
2    block@quote.com EIFLS0LS        1       0      0       0         0            0
3          ht@ml.com EIFLS0LS        1       0      0       0         0            0

编辑:

我找到这些列的目的是能够更新原始列中的行。所以我想要的最终输出是:

> testData
               Email     Manual Campaign Bounced Opened Clicked ClickThru Unsubscribed
1 stack@overflow.com EIFLS0LS        1       1      0       0         0            0
2 stack@exchange.com EIFLS0LS        1       0      0       0         0            0
3     data@frame.com EIFLS0LS        1       0      0       0         0            0
4    block@quote.com EIFLS0LS        1       1      0       0         0            0
5          ht@ml.com EIFLS0LS        1       1      0       0         0            0
6     tele@phone.com EIFLS0LS        1       0      0       0         0            0

如果这是重复的话,我表示道歉,并提前感谢您的帮助!

EDIT2 ::

我最后只使用for循环,没什么了不起,但感觉效率不高。但数据集很小,可以快速完成。如果有人有快速,R风格的方式,我会很高兴看到它!

2 个答案:

答案 0 :(得分:8)

您需要功能merge

merge通常用于将两个表合并为一个相似的公共,但by参数可以允许多个列:

merge(testData, testBounced, by=c("Email", "Campaign"))

默认情况下,将丢弃所有不匹配的EmailCampaign对。这可由参数all.xall.y控制,默认为FALSE

by的默认参数为intersect(names(x, y)),因此从技术上讲,您不需要在这种情况下指定列,但这样做有利于清晰。

答案 1 :(得分:7)

如果您使用data.tables并按要匹配的列键入,那么您可以在一行中完成目标:

    tData[tBounce, Bounced := 1L]



这是完整的过程:

library(data.table)
keys <- c("Email", "Campaign")
tData <- data.table(testData, key=keys)
tBounce <- data.table(testBounce, key=keys)

tData[tBounce, Bounced := 1L]

结果:

tData

                Email   Manual Campaign Bounced Opened Clicked ClickThru Unsubscribed
1:    block@quote.com EIFLS0LS        1       1      0       0         0            0
2:     data@frame.com EIFLS0LS        1       0      0       0         0            0
3:          ht@ml.com EIFLS0LS        1       1      0       0         0            0
4: stack@exchange.com EIFLS0LS        1       0      0       0         0            0
5: stack@overflow.com EIFLS0LS        1       1      0       0         0            0
6:     tele@phone.com EIFLS0LS        1       0      0       0         0            0
>