删除第一个重复的行并保留其余行?

7

我希望根据“用户”列仅删除第一个出现的重复项。

DF:

User  No
A     1
B     1
A     2
A     3
A     4
C     1
B     2
D     1

结果:

(已删除A1和B1)


User  No  
A     2
A     3
A     4
C     1
B     2
D     1

我使用了复制函数但是没有成功。

如果有帮助的话,非常感谢!谢谢!


3
“我一直在尝试使用复制功能,但没有成功”,这句话的意思是什么?你到目前为止尝试了什么?请分享一些代码,否则这个问题肯定会被关闭。 - user3710546
3个回答

17
如果我理解正确的话,这应该可以运行。
library(dplyr)
dd %>% group_by(User) %>% filter(duplicated(User) | n()==1)
duplicated()函数会告诉你一个值是否之前已经出现过,但是它在第一次看到一个值时返回FALSE(表示还没有重复),然后在每次看到该值之后都返回TRUE。为了不丢弃只有一行的值,我们还保留了每个组中总行数n()为1的值。

我花了一秒钟的时间才明白你做了什么。谢谢! - ant

13

这里提供了一种使用data.table的选项。我们将'data.frame'转换为'data.table'(setDT(DF))。按'User'列进行分组后,选择除第一行外的所有行(tail(.SD, -1)),其中.SDData.table的子集。但是,如果'User'组中只有一行,则此方法还会删除该行。我们可以通过使用一个if/else条件来避免这种情况,即如果行数大于1(.N>1),则删除第一行或返回该行(.SD)。

library(data.table)
setDT(DF)[, if(.N>1) tail(.SD,-1) else .SD , by = User]
#   User No
#1:    A  2
#2:    A  3
#3:    A  4
#4:    B  2
#5:    C  1
#6:    D  1

或者像@MrFlick的dplyr代码中一样,使用逻辑条件和duplicated.N(行数)。我们通过检查具有单个观察值的“用户”组来创建一个列“N”(.N==1),在下一步中,我们将子集为TRUE或为“User”重复的duplicated的行。对于duplicate行,duplicated返回TRUE值,使第一个值为FALSE

setDT(DF)[DF[, N:=.N==1, by = User][, N|duplicated(User)]][,N:=NULL][]
或者使用base R选项,通过使用ave来获取逻辑索引(“indx2”),检查每个“User”组的length是否为1即可。我们可以将其与上面描述的duplicated一起使用,对数据集进行子集筛选。
indx2 <- with(DF, ave(seq_along(User), User, FUN=length)==1)
DF[duplicated(DF$User)|indx2,]
#   User No
#3    A  2
#4    A  3
#5    A  4
#6    C  1
#7    B  2
#8    D  1

我需要根据几列条件删除重复行,但是要满足另一列的匹配条件。例如,duplicated(df$a,df$b) & df$c %in% "B"),因此列df$a和df$b存在重复,但它们的df$c列具有A和B两个不同的值。我想保留这些重复中与B匹配的行。你之前回答过类似的问题吗? - user5249203
你需要使用 duplicated(df[c('a', 'b')]) & df$c %in% 'B' - akrun
没有起作用,我在这里添加了一个新问题 https://stackoverflow.com/questions/67627831/remove-duplicate-row-based-on-conditional-matching-in-another-column - user5249203

5

这不像MrFlick和akrun的方法那样容易理解,但它是一个基于R语言的一行解决方案。

#data
DF=data.frame(User=c("A","B","A","A","A","C","B","D"),No=c(1,1,2,3,4,1,2,1))
#solution
subset(DF,duplicated(User)|!duplicated(User,fromLast=TRUE))

它提供了

#  User No
#3    A  2
#4    A  3
#5    A  4
#6    C  1
#7    B  2
#8    D  1

解释:

subset(DF,logicalA|logicalB)
  • logicalA ... 选择所有重复的条目,因此省略了所有只有一个条目的用户
  • logicalB ... 选择所有只有一个条目的用户,并选择最后一个条目(参见fromLast=TRUE),对于有多行的用户,选择它们的最后一行(这些用户已经被logicalA选中了)

希望我理解得没错。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接