条件重复消除

时间:2014-02-07 15:37:31

标签: r

给出以下数据框:

   z1 z2
1   A  X
2   A  Y
3   B  X
4   B  Y
5   C  X
6   C  Z
7   D  X
8   D  Z
9   E  X
10  E  Y
11  F  X
12  G  Z
13  H  X
14  I  Y
15  J  X
16  K  Z

我试图找到一种更有效的方法(比我提出的方法)消除第一列中的重复值z1,给定第二列中的值,z2,不是指定的值“ X”。这是我追求的输出:

   z1 z2
1   A  X
3   B  X
5   C  X
7   D  X
9   E  X
11  F  X
12  G  Z
13  H  X
14  I  Y
15  J  X
16  K  Z

这里(以及其他地方)有几篇关于基于多列消除重复的帖子,我已尝试过各种形式的duplicated()和unique(),但似乎无法找到正确的编码。这个问题与我见过的其他帖子略有不同,要消除的行是基于z1中存在的重复值,并且以z2中的值为条件但是当z1中不存在重复时,条件on z2不适用。我使用subset()提出了以下解决方案,但问题是我需要输入z1中重复的值以使其工作。我当前的解决方案是低效的,因为我需要先通过另一个过程找到重复的值,然后将它们硬编码到子命令中。

这是我一直在使用的数据框和代码:

z1=c(rep(c("A","B","C","D","E"),each=2),"F","G","H","I","J","K")
z2=c(rep(c("X","Y"),2),rep(c("X","Z"),2),rep(c("X","Y","X","Z"),2))
z=data.frame(cbind(z1,z2))

t1=subset(z, 
    (z$z1!="A" | z$z2=="X")&
    (z$z1!="B" | z$z2=="X")&
    (z$z1!="C" | z$z2=="X")&
    (z$z1!="D" | z$z2=="X")&
    (z$z1!="E" | z$z2=="X"))
t1

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

您可以使用duplicatedfromLast=FfromLast=T来确定是否重复z1值:

duplicated(z$z1) | duplicated(z$z1, fromLast=T)
#  [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
# [14] FALSE FALSE FALSE

剩下的就是限制为非重复或X2值为“X”的解决方案:

subset(z, !(duplicated(z1) | duplicated(z$z1, fromLast=T)) | z2 == "X")
#    z1 z2
# 1   A  X
# 3   B  X
# 5   C  X
# 7   D  X
# 9   E  X
# 11  F  X
# 12  G  Z
# 13  H  X
# 14  I  Y
# 15  J  X
# 16  K  Z

答案 1 :(得分:1)

喜欢这个吗?

> wh = with(DF, match(unique(z1),z1))
> DF[wh,]
 z1 z2
1   A  X
3   B  X
5   C  X
7   D  X
9   E  X
11  F  X
12  G  Z
13  H  X
14  I  Y
15  J  X
16  K  Z

答案 2 :(得分:1)

z[!(duplicated(z$z1) | duplicated(z$z1, fromLast = TRUE) & z$z2 != "X"),]

##    z1 z2                                                                                                                                                                                                                                   
## 1   A  X                                                                                                                                                                                                                                   
## 3   B  X                                                                                                                                                                                                                                   
## 5   C  X                                                                                                                                                                                                                                   
## 7   D  X                                                                                                                                                                                                                                   
## 9   E  X                                                                                                                                                                                                                                   
## 11  F  X                                                                                                                                                                                                                                   
## 12  G  Z                                                                                                                                                                                                                                   
## 13  H  X                                                                                                                                                                                                                                   
## 14  I  Y                                                                                                                                                                                                                                   
## 15  J  X                                                                                                                                                                                                                                   
## 16  K  Z     

答案 3 :(得分:0)

实际上很容易。

创建数据框:

df <- read.table(text="  z1 z2
1   A  X
2   A  Y
3   B  X
4   B  Y
5   C  X
6   C  Z
7   D  X
8   D  Z
9   E  X
10  E  Y
11  F  X
12  G  Z
13  H  X
14  I  Y
15  J  X
16  K  Z", stringsAsFactors=FALSE)

现在

t1<-df[!duplicated(df$z1),]

那会给你:

  z1 z2
1   A  X
3   B  X
5   C  X
7   D  X
9   E  X
11  F  X
12  G  Z
13  H  X
14  I  Y
15  J  X
16  K  Z