R 의 벡터나 데이터 프레임을 특정 기준에 따라서 정렬하는 방법에 대해여 알아 보도록 하겠습니다.  SAS를 사용해본 분석가라면 두개 이상의 데이터 셋을 특정 기준으로 merge() 하기 전에 정렬 sort 를 실행해봤을 겁니다.  데이터셋 사이즈가 커지면 merge 하기 전 sort 하느라 시간 많이 잡아먹곤 해서 퇴근하기 전이나 점심먹으러 가기 전에 sorting 돌려놓고 갔던 경험이 있지 않을까 추측해봅니다.  (참고로, R에서는 merge 할때 사전 sorting이 필요 없음)

 

R에서는 데이터 정렬을 위해 sort()와 order() 두개의 함수를 제공하는데요, sort()는 정렬된 값을 순서대로 보여주는 반면에, order()는 데이터 크기의 색인을 제공합니다.  order()가 색인을 제공한다는게 무슨 말인지 잘 이해가 안될 수도 있는데요, 아래 예시를 보면서 설명드리겠습니다.

 

 

 R 벡터, 데이터 프레임 정렬 : sort(), order()

 

 

예시를 위해 세개의 벡터(숫자형 2개, 문자형 1개)와 한개의 데이터 프레임을 만들어보겠습니다.

 

> v1 <- c(40, 30, 50, 50, 90, 40, 50)
> v2 <- c(5100, 6500, 2000, 2000, 9000, 4500, 3000)
> v3 <- c("A", "B", "A", "B", "A", "A", "B")
> v123 <- data.frame(v1, v2, v3)
> v123
  v1   v2 v3
1 40 5100  A
2 30 6500  B
3 50 2000  A
4 50 2000  B
5 90 9000  A
6 40 4500  A
7 50 3000  B

 

 

벡터의 정렬

 

 (1) 숫자 자체 정렬 sort()

 

> v1 [1] 40 30 50 50 90 40 50 >
>
sort(v1) # 오름차순 정렬 [1] 30 40 40 50 50 50 90 >

> sort(v1, decreasing = TRUE) # 내림차순 정렬 [1] 90 50 50 50 40 40 30

 

sort()의 디폴트 정렬순은 오름차순이 되겠습니다.  내림차순으로 하려면 decreasing = TRUE 라는 옵션을 붙여주면 됩니다.

 

 

(2) 정렬 색인 값 order()

 

> v1
[1] 40 30 50 50 90 40 50
> 
> order(v1)
[1] 2 1 6 3 4 7 5
> 

> v1[ order(v1) ] # sort(v1)과 결과 동일 [1] 30 40 40 50 50 50 90

 

 

order(v1) 했을 때 나오는 색인 숫자들 [1] 2 1 6 3 4 7 5 는 무슨 뜻이냐 하면요, v1 중 가장 작은 값(30)이 두번째에 있고, 두번째로 작은값(40)이 첫번째에 있고, 세번째로 작은 값(40)이 여섯번째에 있고.... 이런 뜻입니다.

 

따라서 v1[ order(v1) ] 처럼 v1의 요소를 order(v1)에서 제시한 정렬 색인으로 indexing을 해오면 (1)번의 sort(v1)과 동일한 결과를 얻을 수 있습니다.

 

그러면, 결과가 같은면 그냥 sort(v1)을 쓰면 되지 왜 굳이 order()를 구분해서 사용하고 또 배워야 하는지 의아할 수도 있겠습니다.  order()는 아래의 데이터 프레임에서의 정렬에서 사용하게 되며, sort()는 데이터 프레임에서는 사용할 수 없다는점 때문에 두개 다 배워두어야 합니다.

 

 

데이터 프레임의 정렬

 

> rm(v1, v2, v3) # 벡터 v1, v2, v3 제거
> attach(v123) # 데이터 프레임 활성화
> 

> # v123 데이터 프레임의 전체 행을 v1 오름차순, v2 내림차순, v3 오름차순의 순서대로 정렬

> v123_order <- v123[ order(v1, -v2, v3), ] >

> v123 # 원래 데이터셋 v1 v2 v3 1 40 5100 A 2 30 6500 B 3 50 2000 A 4 50 2000 B 5 90 9000 A 6 40 4500 A 7 50 3000 B >

> v123_order  # 정렬된 후의 데이터 셋
  v1   v2 v3
2 30 6500  B
1 40 5100  A
6 40 4500  A
7 50 3000  B
3 50 2000  A
4 50 2000  B
5 90 9000  A
> 
> detach(v123) 

 

위 예제에서 데이터 프레임 v123 의 행 전체를 v1 오름차순, v2 내림차순(변수 앞에 - 부호), v3 오름차순(문자형도 알파벳순 정렬 가능)의 순서대로 정렬하였습니다.

 

정렬된 후의 데이터 프레임 v123_order 의 제일 왼쪽의 row.names 가 order(v1, -v2, v3)의 색인 결과와 같게 정렬이 되어 있음을 알 수 있습니다. 

 

> order(v1, -v2, v3) [1] 2 1 6 7 3 4 5 >
>
row.names(v123_order) [1] "2" "1" "6" "7" "3" "4" "5" 

 

다시 한번 정리하자면, 데이터 프레임에서 정렬할 때는 order()로 정렬한 색인을 가져다가 index의 행의 위치 ( [, 열] 에 집어 넣고, 열 자리에는 비워둠으로써 [order(), ] 모든 열을 가져오게끔 해서 정렬을 키는 원리입니다.



plyr 패키지arrange() 함수를 사용해서 정렬하는 방법도 있습니다. 내림차순으로 정렬하고자 할 경우에는 desc() 옵션을 추가하면 됩니다.  arrange(data.frame, var1, desc(var2), ...) 이런 형식으로 사용하면 되겠습니다.  아래 예제는 위의 order와 indexing을 사용한 것과 동일한 경과를 얻었음을 알 수 있습니다. 


> library(plyr)

> arrange(v123, v1, desc(v2), v3)

  v1   v2 v3

1 30 6500  B

2 40 5100  A

3 40 4500  A

4 50 3000  B

5 50 2000  A

6 50 2000  B

7 90 9000  A 



많은 도움이 되었기를 바랍니다.

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

Posted by R Friend R_Friend