Выберите строки с наибольшим значением переменной в группе в R

StackOverflow https://stackoverflow.com/questions/2822156

  •  26-09-2019
  •  | 
  •  

Вопрос

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,]

Возвращает индекс списка, а не индекс для всех данных. Crame

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

Это было полезно?

Решение

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,]

Другие советы

То 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 Работает на кадрах данных, так что можно продолжать использовать этот подход.

library(plyr)
ddply(a.3, "a.2", subset, b.2 == max(b.2))
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,]

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

> 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 
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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top