выбрать строки с наибольшим значением переменной в группе в r - PullRequest
9 голосов
/ 12 мая 2010
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)

r<-sapply(split(a.3,a.2),function(x) which.max(x$b.2))

a.3[r,]

возвращает индекс списка, а не индекс для всех data.frame

Я пытаюсь вернуть наибольшее значение b.2 для каждой подгруппы a.2. Как я могу сделать это эффективно?

Ответы [ 6 ]

10 голосов
/ 07 сентября 2012

Подходы ddply и ave, как мне кажется, довольно ресурсоемки. ave завершается неудачно из-за недостатка памяти для моей текущей проблемы (67 608 строк с четырьмя столбцами, определяющими уникальные ключи). tapply - это удобный выбор, но мне обычно нужно выбрать все целые строки с чем-то некоторым значением для каждого уникального ключа (обычно определяемого более чем одним столбцом). Лучшее решение, которое я нашел, - это выполнить сортировку, а затем использовать отрицание duplicated, чтобы выбрать только первую строку для каждого уникального ключа. Для простого примера здесь:

a <- sample(1:10,100,replace=T)
b <- sample(1:100,100,replace=T)
f <- data.frame(a, b)

sorted <- f[order(f$a, -f$b),]
highs <- sorted[!duplicated(sorted$a),]

Я думаю, что увеличение производительности по сравнению с ave или ddply, по крайней мере, является существенным. Это несколько сложнее для ключей с несколькими столбцами, но order будет обрабатывать целую кучу вещей для сортировки, а duplicated работает с фреймами данных, поэтому можно продолжать использовать этот подход.

8 голосов
/ 13 мая 2010
library(plyr)
ddply(a.3, "a.2", subset, b.2 == max(b.2))
6 голосов
/ 13 мая 2010
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)

Ответ Джонатана Чанга даст вам то, о чем вы явно просили, но я предполагаю, что вы хотите фактическую строку из фрейма данных.

sel <- ave(b.2, a.2, FUN = max) == b.2
a.3[sel,]
1 голос
/ 13 мая 2010
> a.2<-sample(1:10,100,replace=T)
> b.2<-sample(1:100,100,replace=T)
> tapply(b.2, a.2, max)
 1  2  3  4  5  6  7  8  9 10 
99 92 96 97 98 99 94 98 98 96 
1 голос
/ 13 мая 2010
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)
m<-split(a.3,a.2)
u<-function(x){
    a<-rownames(x)
    b<-which.max(x[,2])
    as.numeric(a[b])
    }
r<-sapply(m,FUN=function(x) u(x))

a.3[r,]

Это делает трюк, хотя и несколько громоздкий ... Но он позволяет мне брать строки для групповых наибольших значений. Любые другие идеи?

0 голосов
/ 04 мая 2017
a.2<-sample(1:10,100,replace=T)
b.2<-sample(1:100,100,replace=T)
a.3<-data.frame(a.2,b.2)

С помощью aggregate вы можете получить максимум для каждой группы в одной строке:

aggregate(a.3, by = list(a.3$a.2), FUN = max)

Это дает следующий вывод:

   Group.1 a.2 b.2
1        1   1  96
2        2   2  82
...
8        8   8  85
9        9   9  93
10      10  10  97
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...