假设我有四个样本:id = 1,2,3和4,每个样本都有一个或多个测量值:
> a <- data.frame(id=c(1,1,2,2,3,4), value=c(1,2,3,-4,-5,6))
> a
id value
1 1 1
2 1 2
3 2 3
4 2 -4
5 3 -5
6 4 6
我想删除重复项,每个ID只保留一个条目 - 具有“value”列绝对值最大的条目。即,这就是我想要的:
> a[c(2,4,5,6), ]
id value
2 1 2
4 2 -4
5 3 -5
6 4 6
我怎么能在R中这样做?
答案 0 :(得分:32)
aa <- a[order(a$id, -abs(a$value) ), ] #sort by id and reverse of abs(value)
aa[ !duplicated(aa$id), ] # take the first row within each id
id value
2 1 2
4 2 -4
5 3 -5
6 4 6
答案 1 :(得分:9)
结帐?aggregate
:
aggregate(value~id,a,function(x) x[which.max(abs(x))])
我喜欢@DWin的答案,但我想展示一下它如何与元数据一起使用:
aa<-merge(aggregate(value~id,a,function(x) x[which.max(abs(x))]),a)
# Fails if the max value is duplicated for a single id without next line.
aa[!duplicated(aa),]
我无法自拔,并创造了最后一个答案:
do.call(rbind,lapply(split(a,a$id),function(x) x[which.max(abs(x$value)),]))
答案 2 :(得分:9)
如果您的数据集非常大,则可能需要data.table
方法:
library(data.table)
aDT <- as.data.table(a)
setkey(aDT,"id")
aDT[J(unique(id)), list(value = value[which.max(abs(value))])]
或者不是那么快,但仍然很快的替代方案:
library(data.table)
as.data.table(a)[, .SD[which.max(abs(value))], by=id]
如果真实数据集中有更多内容,此版本将返回a
的所有列。
答案 3 :(得分:5)
另一种方法(尽管代码可能看起来有些麻烦)是使用ave()
:
a[which(abs(a$value) == ave(a$value, a$id,
FUN=function(x) max(abs(x)))), ]
# id value
# 2 1 2
# 4 2 -4
# 5 3 -5
# 6 4 6
答案 4 :(得分:3)
library(plyr)
ddply(a, .(id), function(x) return(x[which(abs(x$value)==max(abs(x$value))),]))
答案 5 :(得分:2)
这是dplyr
方法
library(dplyr)
a %>%
group_by(id) %>%
top_n(1, abs(value))
# A tibble: 4 x 2
# Groups: id [4]
# id value
# <dbl> <dbl>
#1 1 2
#2 2 -4
#3 3 -5
#4 4 6
答案 6 :(得分:0)
您可以使用dplyr进行以下操作:
df1 <- iris[c(1,51),4:5]
df2 <- iris[c(2,52),2:5]
df1
# Petal.Width Species
# 1 0.2 setosa
# 51 1.4 versicolor
df2
# Sepal.Width Petal.Length Petal.Width Species
# 2 3.0 1.4 0.2 setosa
# 52 3.2 4.5 1.5 versicolor