r - 특정 열에 순위를 매길 때 분할하는 방법?
dataframe rank (3)
모든:
나는 다음과 같은 데이터 프레임을 가지고있다. 나는 이처럼 전 세계적으로 순위를 매길 수 있음을 안다.
dt <- data.frame(
ID = c('A1','A2','A4','A2','A1','A4','A3','A2','A1','A3'),
Value = c(4,3,1,3,4,6,6,1,8,4)
);
> dt
ID Value
1 A1 4
2 A2 3
3 A4 1
4 A2 3
5 A1 4
6 A4 6
7 A3 6
8 A2 1
9 A1 8
10 A3 4
dt$Order <- rank(dt$Value,ties.method= "first")
> dt
ID Value Order
1 A1 4 5
2 A2 3 3
3 A4 1 1
4 A2 3 4
5 A1 4 6
6 A4 6 8
7 A3 6 9
8 A2 1 2
9 A1 8 10
10 A3 4 7
하지만 어떻게 글로벌 순위 대신 특정 ID에 대한 순위 순서를 설정할 수 있습니다. 어떻게해야합니까? T-SQL에서는 다음 구문으로이 작업을 수행 할 수 있습니다.
RANK() OVER ( [ < partition_by_clause > ] < order_by_clause > )
어떤 생각?
data.table 패키지를 사용할 수 있습니다.
setDT(dt) dt[, Order := rank(Value, ties.method = "first"), by = "ID"] dt <- as.data.frame(dt)
원하는 출력을 제공합니다.
ID Value Order
1 A1 4 1
2 A2 3 2
3 A4 1 1
4 A2 3 3
5 A1 4 2
6 A4 6 2
7 A3 6 2
8 A2 1 1
9 A1 8 3
10 A3 4 1
내 방식이지만 가능성은 더 좋아. 결코 순위를 사용하지 마라. 그것에 대해 알지 마라. 고마워, 유용 할 수 있습니다.
#Your Data
dt <- data.frame(
ID = c('A1','A2','A4','A2','A1','A4','A3','A2','A1','A3'),
Value = c(4,3,1,3,4,6,6,1,8,4)
)
dt$Order <- rank(dt$Value,ties.method= "first")
#My approach
dt$id <- 1:nrow(dt) #needed for ordering and putting things back together
dt <- dt[order(dt$ID),]
dt$Order.by.group <- unlist(with(dt, tapply(Value, ID, function(x) rank(x,
ties.method = "first"))))
dt[order(dt$id), -4]
수율 :
ID Value Order Order.by.group
1 A1 4 5 1
2 A2 3 3 2
3 A4 1 1 1
4 A2 3 4 3
5 A1 4 6 2
6 A4 6 8 2
7 A3 6 9 2
8 A2 1 2 1
9 A1 8 10 3
10 A3 4 7 1
편집하다:
데이터의 원래 순서를 유지하는 데 신경 쓰지 않는다면 적은 코드로 작동합니다.
dt <- dt[order(dt$ID),]
dt$Order.by.group <- unlist(with(dt, tapply(Value, ID, function(x) rank(x,
ties.method= "first"))))
ID Value Order.by.group
1 A1 4 1
5 A1 4 2
9 A1 8 3
2 A2 3 2
4 A2 3 3
8 A2 1 1
7 A3 6 2
10 A3 4 1
3 A4 1 1
6 A4 6 2
많은 옵션.
plyr 패키지의 ddply 사용 :
library(plyr)
ddply(dt,.(ID),transform,Order = rank(Value,ties.method = "first"))
ID Value Order
1 A1 4 1
2 A1 4 2
3 A1 8 3
4 A2 3 2
5 A2 3 3
6 A2 1 1
7 A3 6 2
8 A3 4 1
9 A4 1 1
10 A4 6 2
또는 data.table 패키지를 사용하여 성능이 문제 (즉, 매우 큰 데이터) 인 경우 :
library(data.table)
DT <- data.table(dt,key = "ID")
DT[,transform(.SD,Order = rank(Value,ties.method = "first")),by = ID]
ID Value Order
[1,] A1 4 1
[2,] A1 4 2
[3,] A1 8 3
[4,] A2 3 2
[5,] A2 3 3
[6,] A2 1 1
[7,] A4 1 1
[8,] A4 6 2
[9,] A3 6 2
[10,] A3 4 1
또는 모든 lapply
세부 사항에서 기본 R 솔루션은 split
lapply
do.call
및 rbind
.
do.call(rbind,lapply(split(dt,dt$ID),transform,
Order = rank(Value,ties.method = "first")))