35

id=1、2、3、および 4 の 4 つのサンプルがあり、これらのサンプルのそれぞれに 1 つ以上の測定値があるとします。

> 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ごとに1つのエントリのみを保持して、重複を削除したい-「値」列の絶対値が最大のもの。つまり、これは私が欲しいものです:

> 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 に答える
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),]

私は自分自身を助けることができず、最後の答えを1つ作成しました:

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 に答える