2014-02-07 73 views
3

鉴于以下数据帧:条件消除重复

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 

这里(和其他国家)关于消除基于多列重复有几个职位,我已经尝试过各种形式的复制()和独特(),但似乎无法打在正确的编码,这样做。这个问题与我见过的其他帖子有点不同,因为要消除的行是基于z1中存在的重复值并且以z2中的值为条件,但是当z1中不存在重复时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 

有什么想法?

回答

3

您可以使用duplicated,与fromLast=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 

剩下的工作就是要限制为要么不复制或解决方案有“X”值X2

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 
+0

该解决方案运行良好。发布的一些解决方案似乎取决于初始数据框的排序。这是我提供一个快速放在一起的玩具例子的错。无论如何,在我迄今为止的测试中,这种方法似乎提供了答案,无论数据帧排序如何。好的解决方案谢谢! –

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 
+0

有趣。我想知道为什么当z1中出现重复时,为什么选择z2 = X而不是其他可能性。是否由于订购? –

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  
+0

请务必检查''duplicate''和''''from'Last = T'以确保您标记第一个重复的值(请参阅我的回复)。 – josliber

+0

@josilber谢谢!更新了我的答案 –

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 
+2

使用给出的示例数据,但是如果'z1'中有重复项,那么在'z2'中也具有'X'的值。如果最初的问题有数据显示问题描述 –

+0

是的,你是对的。我认为josilber已经钉了它。 –