我希望根据“用户”列仅删除第一个出现的重复项。
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
我使用了复制函数但是没有成功。
如果有帮助的话,非常感谢!谢谢!
我希望根据“用户”列仅删除第一个出现的重复项。
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
我使用了复制函数但是没有成功。
如果有帮助的话,非常感谢!谢谢!
library(dplyr)
dd %>% group_by(User) %>% filter(duplicated(User) | n()==1)
duplicated()
函数会告诉你一个值是否之前已经出现过,但是它在第一次看到一个值时返回FALSE(表示还没有重复),然后在每次看到该值之后都返回TRUE。为了不丢弃只有一行的值,我们还保留了每个组中总行数n()
为1的值。这里提供了一种使用data.table
的选项。我们将'data.frame'转换为'data.table'(setDT(DF)
)。按'User'列进行分组后,选择除第一行外的所有行(tail(.SD, -1)
),其中.SD
是Data.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匹配的行。你之前回答过类似的问题吗? - user5249203duplicated(df[c('a', 'b')]) & df$c %in% 'B'
。 - akrun这不像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
选中了)希望我理解得没错。 :)