给出以下数据框:
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
有什么想法吗?
答案 0 :(得分:3)
您可以使用duplicated
,fromLast=F
和fromLast=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