Подмножество фрейма данных с топ-n строк для каждой группы и упорядочены по переменной

r group-by data.table plyr

7020 просмотра

6 ответа

Я хотел бы установить подкадр данных для n строк, которые сгруппированы по переменной и отсортированы по убыванию по другой переменной. Это было бы понятно на примере:

    d1 <- data.frame(Gender = c("M", "M", "F", "F", "M", "M", "F", 
  "F"), Age = c(15, 38, 17, 35, 26, 24, 20, 26))

Я хотел бы получить 2 строки, отсортированные по возрасту, для каждого пола. Желаемый результат:

Gender  Age  
F   35  
F   26  
M   38  
M   26  

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

Автор: karlos Источник Размещён: 17.05.2019 02:37

Ответы (6)


13 плюса

Решение

Одно решение с использованием ddply()отplyr

require(plyr)
ddply(d1, "Gender", function(x) head(x[order(x$Age, decreasing = TRUE) , ], 2))
Автор: Chase Размещён: 20.05.2011 06:05

6 плюса

С пакетом data.table

require(data.table)
dt1<-data.table(d1)# to speedup you can add setkey(dt1,Gender)
dt1[,.SD[order(Age,decreasing=TRUE)[1:2]],by=Gender]
Автор: Wojciech Sobala Размещён: 20.05.2011 06:34

1 плюс

Я уверен, что есть лучший ответ, но вот один из способов:

require(plyr)
ddply(d1, c("Gender", "-Age"))[c(1:2, 5:6),-1]

Если у вас есть фрейм данных большего размера, чем тот, который вы здесь предоставили, и не хотите визуально проверять, какие строки выбрать, просто используйте это:

new.d1=ddply(d1, c("Gender", "-Age"))[,-1]
pos=match('M',new.d1$Gender) # pos wil show index of first entry of M
new.d1[c(1:2,pos:(pos+1)),]
Автор: Manoel Galdino Размещён: 20.05.2011 06:08

0 плюса

Это даже проще, чем если вы просто хотите выполнить сортировку:

d1 <- transform(d1[order(d1$Age, decreasing=TRUE), ], Gender=as.factor(Gender))

Вы можете позвонить:

require(plyr)
d1 <- ddply(d1, .(Gender), head, n=2)

подмножество двух верхних из каждой подгруппы пола.

Автор: alphaG77 Размещён: 25.09.2011 04:56

0 плюса

У меня есть предложение, если вам нужны, например, первые 2 женщины и первые 3 мужчины:

library(plyr)
m<-d1[order(d1$Age, decreasing = TRUE) , ] 
h<-mapply(function(x,y) head(x,y), split(m$Age,m$Gender),y=c(2,3)) 
ldply (h, data.frame)

Вам просто нужно изменить имена конечного кадра данных.

Автор: Liliana Pacheco Размещён: 05.01.2017 07:28

0 плюса

d1 = d1[order(d1$Gender, -d1$Age),]  
d1 = d1[ave(d1$Age, d1$Gender, FUN = seq_along) <= 2, ]

У него была похожая проблема, и этот метод оказался очень быстрым при использовании на data.frame с 1,5 миллионами записей.

Автор: enkay Размещён: 30.03.2019 10:54
Вопросы из категории :
32x32