考虑以下数据框:
first_name last_name
1 Al Smith
2 Al Jones
3 Jeff Thompson
4 Scott Thompson
5 Terry Dactil
6 Pete Zah
data <- data.frame(first_name=c("Al","Al","Jeff","Scott","Terry","Pete"),
last_name=c("Smith","Jones","Thompson","Thompson","Dactil","Zah"))
在此数据框中,first_name 与 last_name 的关联方式有以下三种:
和姓氏)
last_name 值)
到一个姓氏)
我希望能够快速识别三种情况中的每一种并将它们输出到数据框。因此,生成的数据帧将是:
一对一
first_name last_name
1 Terry Dactil
2 Pete Zah
一对多
first_name last_name
1 Al Smith
2 Al Jones
多对一
first_name last_name
1 Jeff Thompson
2 Scott Thompson
我想在 dplyr 包中执行此操作。
最佳答案
通常,您可以使用 duplicated
函数检查值是否重复(如@RichardScriven 在对您的问题的评论中所述)。但是,默认情况下,此函数不会将多次出现的元素的第一个实例标记为重复:
duplicated(c(1, 1, 1, 2))
# [1] FALSE TRUE TRUE FALSE
由于您还想处理这些情况,您通常希望在每个向量上运行
duplicated
两次,一次向前,一次向后:duplicated(c(1, 1, 1, 2)) | duplicated(c(1, 1, 1, 2), fromLast=TRUE)
# [1] TRUE TRUE TRUE FALSE
我发现这需要大量输入,因此我将定义一个辅助函数来检查一个元素是否出现多次:
d <- function(x) duplicated(x) | duplicated(x, fromLast=TRUE)
现在你想要的逻辑都是简单的单行:
# One to one
data[!d(data$first_name) & !d(data$last_name),]
# first_name last_name
# 5 Terry Dactil
# 6 Pete Zah
# One to many
data[d(data$first_name) & !d(data$last_name),]
# first_name last_name
# 1 Al Smith
# 2 Al Jones
# Many to one
data[!d(data$first_name) & d(data$last_name),]
# first_name last_name
# 3 Jeff Thompson
# 4 Scott Thompson
请注意,您也可以使用
d
函数在没有 duplicated
帮助的情况下定义 table
:d <- function(x) table(x)[x] > 1
虽然这个替代定义稍微简洁一些,但我也发现它不太可读。
关于r - 查找列之间的一对一、一对多和多对一关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32828094/