我有一个包含一些重复 ID 的数据框。我想删除具有重复 ID 的记录,只保留具有最大值的行。
所以对于这样的结构(其他变量未显示):
id var_1
1 2
1 4
2 1
2 3
3 5
4 2
我想生成这个:
id var_1
1 4
2 3
3 5
4 2
我知道唯一()和重复(),但我不知道如何合并最大化规则......
我有一个包含一些重复 ID 的数据框。我想删除具有重复 ID 的记录,只保留具有最大值的行。
所以对于这样的结构(其他变量未显示):
id var_1
1 2
1 4
2 1
2 3
3 5
4 2
我想生成这个:
id var_1
1 4
2 3
3 5
4 2
我知道唯一()和重复(),但我不知道如何合并最大化规则......
一种方法是对数据进行反向排序并用于duplicated
删除所有重复项。对我来说,这种方法在概念上比那些使用 apply 的方法更简单。我认为它也应该非常快。
# Some data to start with:
z <- data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,5,2))
# id var
# 1 2
# 1 4
# 2 1
# 2 3
# 3 5
# 4 2
# Reverse sort
z <- z[order(z$id, z$var, decreasing=TRUE),]
# id var
# 4 2
# 3 5
# 2 3
# 2 1
# 1 4
# 1 2
# Keep only the first row for each duplicate of z$id; this row will have the
# largest value for z$var
z <- z[!duplicated(z$id),]
# Sort so it looks nice
z <- z[order(z$id, z$var),]
# id var
# 1 4
# 2 3
# 3 5
# 4 2
编辑:我刚刚意识到上面的反向排序甚至根本不需要排序id
。您可以z[order(z$var, decreasing=TRUE),]
改用它,它也可以正常工作。
再想一想……如果var
列是数字,那么有一种简单的排序方法,即id
升序,但var
降序。这消除了最后排序的需要(假设你甚至希望它被排序)。
z <- data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,5,2))
# Sort: id ascending, var descending
z <- z[order(z$id, -z$var),]
# Remove duplicates
z <- z[!duplicated(z$id),]
# id var
# 1 4
# 2 3
# 3 5
# 4 2
您实际上想从具有相同 id 的元素中选择最大元素。为此,您可以使用ddply
包plyr:
> dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2))
> ddply(dt,.(id),summarise,var_1=max(var))
id var_1
1 1 4
2 2 3
3 3 4
4 4 2
unique
并且duplicated
用于删除重复记录,在您的情况下,您只有重复的 ID,而不是记录。
更新:这是有其他变量时的代码:
> dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2),bu=rnorm(6))
> ddply(dt,~id,function(d)d[which.max(d$var),])
base-R 解决方案将涉及split
,如下所示:
z<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2))
do.call(rbind,lapply(split(z,z$id),function(chunk) chunk[which.max(chunk$var),]))
split
将数据框拆分为一个块列表,我们在其上执行切割到具有最大值的单行,然后再次do.call(rbind,...)
将单行列表缩减为一个数据框。
我更喜欢使用ave
dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,3,3,4,2))
## use unique if you want to exclude duplicate maxima
unique(subset(dt, var==ave(var, id, FUN=max)))