2015년 1월 29일 목요일

R pivot, R group by order

#R pivot, R group by order

#Grouping 해서 order 한후 원하는 rank뽑아 내기

#문제 x 를 Group으로 그룹핑한 후 각 그룹에 Quantity별로 해당 랭크를 뽑아 나열해라
#  Group Name Quantity
#1     A    v        3
#2     A    u        3
#3     A    w        4
#4     A    x        5
#5     C    x        2
#6     C    y        0

#각 그룹별 2위는?
#답
#  Group Name Quantity
#A     A    w        4
#C     C    y        0

#function is copyed from
#http://stackoverflow.com/questions/14421338/how-do-i-create-order-statistics-by-group-in-r
#author Matthew Plourde

x <- data.frame(Group=c("A","A", "A", "A", "C", "C"),
                Name=c("v", "u", "w","x", "x", "y"),
                Quantity=c(3,3,4,5,2,0))
#  Group Name Quantity
#1     A    v        3
#2     A    u        3
#3     A    w        4
#4     A    x        5
#5     C    x        2
#6     C    y        0

order(x$Quantity, -rank(x$Name))
#[1] 6 5 1 2 3 4
#tail로 뒷 순위에서 부터 랭킹을 가져옴으로 asc로 정렬
in.order <-  function(group) with(group, group[order(Quantity, -rank(Name)), ])
in.order(x)
#  Group Name Quantity
#6     C    y        0
#5     C    x        2
#1     A    v        3
#2     A    u        3
#3     A    w        4
#4     A    x        5

#그냥 적용할 경우 그룹별 랭킹이 나옴
groups.row <- by(x, x$Group, function(group) in.order(group))
groups.row
#x$Group: A
#  Group Name Quantity
#1     A    v        3
#2     A    u        3
#3     A    w        4
#4     A    x        5
#----------------------
#x$Group: C
#  Group Name Quantity
#6     C    y        0
#5     C    x        2

# select 2등
head(tail(groups.row$A,2),1)
#Group Name Quantity
#3     A    w        4

#해당 tail -> head 를 적용
N <- 2
groups.row <- by(x, x$Group, function(group) head(tail(in.order(group),N),1))
#x$Group: A
#  Group Name Quantity
#3     A    w        4
#-----------------------
#x$Group: C
#  Group Name Quantity
#6     C    y        0

#그룹별 랭킹을 하나의 데이터프래임으로 묶기
#rbind(groups.row$A,groups.row$C)
do.call(rbind, groups.row)
#  Group Name Quantity
#A     A    w        4
#C     C    y        0