10

我有一个 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

如您所见,Email 列中有一些值相交,而 Campaign 列中的一些值相交。我想要 testData 中两列都匹配的所有行。

IE:

               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

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

编辑2::

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

4

2 回答 2

8

你想要的功能merge

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

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

默认情况下,所有不匹配的Email和对都将被丢弃。Campaign这可以通过参数all.x和来控制all.y,默认为FALSE.

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

于 2013-07-26T18:50:39.613 回答
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
> 
于 2013-07-26T19:51:31.643 回答