2015-09-28 32 views
1

之间的关系,考虑下面的数据帧:找到一个对一个,一到多,多到一列

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正在有关姓氏:

  • 一对一(即,存在如first_name 和last_name之间的独特关系)
  • 一对多(即,一个如first_name点被用于多个 last_name的值)
  • 多对一(即多个FIRST_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软件包。

+2

你想'duplicateated()'函数 –

+0

[这里](http://www.cookbook-r.com/Manipulating_data/Finding_and_removing_duplicate_records/)是一些使用'duplicated()'的例子代码,但我认为它会如果你能给我们一些具体的东西,请冷静一下,@RichardScriven。我并不是想解决这个问题。 TY。 –

回答

6

通常,您可以使用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 

请注意,您还可以使用table函数定义dduplicated的帮助:

d <- function(x) table(x)[x] > 1 

虽然这种替代定义稍微简洁些,我也觉得它不太可读。

+4

我有点儿希望我的名字是特里达克蒂尔现在 –

+0

@RichardScriven我会期待“特里Dactyl”,但是,这将是一个伟大的谈话起动器! – josliber

+0

是不会把'function(x)duplicated(x)'和'duplicated(x,fromLast = TRUE)'看作是两个独立的部分? –