35

假设我有四个样本: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 只保留一个条目 - “值”列的绝对值最大的条目。即,这就是我想要的:

> a[c(2,4,5,6), ]
  id value
2  1     2
4  2    -4
5  3    -5
6  4     6

我怎么能在 R 中做到这一点?

4

7 回答 7

48

第一的。按顺序排序,将不太需要的项目放在id组中的最后

 aa <- a[order(a$id, -abs(a$value) ), ] #sort by id and reverse of abs(value)

然后:删除id组内第一个之后的项目

 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
于 2012-10-09T18:24:30.173 回答
14

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,以防真实数据集中有更多列。

于 2012-10-09T18:48:12.660 回答
10

这是一种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
于 2018-05-25T10:15:11.833 回答
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)),]))
于 2012-10-09T18:19:05.163 回答
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
于 2012-10-09T18:56:51.143 回答
3
library(plyr)
ddply(a, .(id), function(x) return(x[which(abs(x$value)==max(abs(x$value))),]))
于 2012-10-09T18:21:45.360 回答
1

您可以使用 dplyr 执行此操作,如下所示:

library(dplyr)
a %>%
  group_by(name) %>%
  filter(n == max(n)) %>%
  ungroup()
于 2018-11-14T22:51:43.970 回答