2014-10-06 8 views
0

данных:Subset наивысшие значения каждой группы в R

ID<-c(1,2,3,4,5,6,7,8) 
Value<-c(5,4,7,2,6,3,9,4) 
Group<-c(1,1,1,2,3,2,2,3) 
data<-data.frame(ID,Value,Group) 
I would like to take the 2 of every Group with the highest Values into a new DataFrame. 

Конечный результат должен выглядеть следующим образом: ID < -1,3,6,7,5,8 Значение < -5, 7,3,9,6,4 Группа < -1,1,2,2,3,3 FinalData < - (ID, Value, группа)

Мой подход:

Finaldata<-head(data[order(Value,decreasing=TRUE),],n=2) 

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

ответ

4

С помощью «data.table» вы можете попробовать что-то вроде этого:

library(data.table) 
as.data.table(data)[order(Group, -Value), head(.SD, 2), by = Group] 
# Group ID Value 
# 1:  1 3  7 
# 2:  1 1  5 
# 3:  2 7  9 
# 4:  2 6  3 
# 5:  3 5  6 
# 6:  3 8  4 
1

используя dplyr. Если вы используете dplyr_0.3 ie. версия devel, slice, в противном случае вы могли бы использовать do. Вы можете установить версию Devel по:

devtools::install_github("hadley/dplyr") #first you need to install `devtools`. 

Кроме того, вы можете проверить ссылку https://github.com/hadley/dplyr

library(dplyr) 
data%>% 
    group_by(Group) %>% 
    arrange(desc(Value)) %>% 
    slice(1:2) # do(head(.,2)) #in dplyr 0.2 

дает результат

# ID Value Group 
#1 3  7  1 
#2 1  5  1 
#3 7  9  2 
#4 6  3  2 
#5 5  6  3 
#6 8  4  3 

Используя slice, вы можете получить второй самый высокий значение (т.е. slice(2)) для каждой группы или от любой начальной строки до любой конечной строки, которая действительно имеет набор данных. В этом примере (slice(2:3) дает строку 1 для группы 3, поскольку в этой группе было всего 2 строки.

или с помощью base R

data[with(data, ave(-Value, Group, FUN=rank)%in% 1:2),] 
# ID Value Group 
#1 1  5  1 
#3 3  7  1 
#5 5  6  3 
#6 6  3  2 
#7 7  9  2 
#8 8  4  3 
0

Try:

ll = lapply(split(data, Group), function(x) tail(x[order(x$Value),],2)) 
ll 
$`1` 
    ID Value Group 
1 1  5  1 
3 3  7  1 

$`2` 
    ID Value Group 
6 6  3  2 
7 7  9  2 

$`3` 
    ID Value Group 
8 8  4  3 
5 5  6  3 

Для привязки кадра данных:

do.call(rbind, ll) 
    ID Value Group 
1.1 1  5  1 
1.3 3  7  1 
2.6 6  3  2 
2.7 7  9  2 
3.8 8  4  3 
3.5 5  6  3 

или:

rbindlist(ll) 
    ID Value Group 
1: 1  5  1 
2: 3  7  1 
3: 6  3  2 
4: 7  9  2 
5: 8  4  3 
6: 5  6  3 
Смежные вопросы