본문 바로가기
데이터 [Data]/R

R 데이터 가공: 정렬, 결합 및 분리

by 냉철하마 2021. 4. 28.

참고도서: R 통계 프로그래밍의 이해 - 차영준, 박진표 (자유아카데미) 3장

www.yes24.com/Product/Goods/68712840

 

R 통계 프로그래밍의 이해

'최근에 빅데이터와 관련된 용어들이 많이 사용되고 있다. 인공지능, 머신러닝, 데이터 과학, 데이터 과학자, 4차 산업혁명 등과 같은 단어들을 많이 접하게 된다. 이처럼 많은 사람들이 빅데이

www.yes24.com

 

> #### 3.3 데이터의 정렬 ####

>

> # 3.3.1 sort()order() 함수에 의한 데이터 정렬 #

> #벡터 정렬

> x <- c(44, 11, 22, 55, 33)

> sort(x) ## 오름차순 정렬

[1] 11 22 33 44 55

> sort(x, decreasing = TRUE) ## 내림차순 정렬

[1] 55 44 33 22 11

> order(x) ## 오름차순 정렬한 자료의 위치값 출력

[1] 2 3 5 1 4

> order(-x) ## 내림차순 정렬한 자료의 위치값 출력

[1] 4 1 5 3 2

> x[order(x)] ## sort(x)와 동일하나, 정렬 시 주로 sort()가 아닌 이 방식을 사용

[1] 11 22 33 44 55

> x[order(-x)]

[1] 55 44 33 22 11

>

> nation <- c("Korea", "USA", "China", "Canada", "Japan")

> sort(nation) ## 문자형 변수에도 마찬가지로 정렬 적용

[1] "Canada" "China" "Japan" "Korea" "USA"

> order(nation)

[1] 4 3 5 1 2

> nation[order(nation)]

[1] "Canada" "China" "Japan" "Korea" "USA"

>

> #데이터 프레임 정렬

> name <- c("Cha", "Park", "Jung", "Kim", "Lee")

> gender <- c("M", "F", "M", "F", "F")

> toeic <- c(990, 900, 950, 900, 900)

> gpa <- c(4.5, 3.8, 4.2, 3.2, 3.3)

> student <- data.frame(name, gender, toeic, gpa, stringsAsFactors = FALSE)

> student

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 900 3.8

3 Jung M 950 4.2

4 Kim F 900 3.2

5 Lee F 900 3.3

>

> student[order(toeic), ]

  name gender toeic gpa

2 Park F 900 3.8

4 Kim F 900 3.2

5 Lee F 900 3.3

3 Jung M 950 4.2

1 Cha M 990 4.5

> student[order(toeic, gpa), ]

  name gender toeic gpa

4 Kim F 900 3.2

5 Lee F 900 3.3

2 Park F 900 3.8

3 Jung M 950 4.2

1 Cha M 990 4.5

>

> #UsingR:kid.weights 데이터 세트 & doBy::orderBy() 함수

> install.packages("UsingR") ## kid.weights 데이터 세트를 사용하기 위해 UsingR 패키지 설치 및 로드

> library(UsingR)

 

> require(UsingR) ## [참고] 복구코드

> tail(kid.weights) ## 마지막 6행의 데이터 출력 (head와 반대)

      age weight height gender

245 64 49 40 M

246 10 18 27 F

247 5 14 25 M

248 23 26 33 M

249 122 85 40 M

250 5 14 27 M

> str(kid.weights) ## kid.weights의 데이터 구조 확인

  'data.frame': 250 obs. of 4 variables:

$ age : num 58 103 87 138 82 52 28 79 107 45 ...

$ weight: num 38 87 50 98 47 30 24 45 144 24 ...

$ height: num 38 43 48 61 47 24 29 48 59 24 ...

$ gender: Factor w/ 2 levels "F","M": 2 2 2 2 1 1 2 1 2 2 ...

>

> # 3.3.2 doBy::orderBy() 함수를 이용한 데이터 정렬 #

> # & order() 함수를 이용한 UsingR::kid.weights 정렬

> # "[order()]""orderBy()"의 결과를 같게끔 코딩 #

> install.packages("doBy") ## orderBy 함수를 사용하기 위해 doBy 패키지 설치 및 로드

> library(doBy)

 

> x <- kid.weights[order(kid.weights$age), ] ## kid.weights를 나이(age)를 기준으로 정렬

> head(x)

    age weight height gender

14 3 10 29 F

79 3 12 23 F

100 3 13 24 F

146 3 13 24 F

173 3 12 23 F

189 3 17 27 F

> head(orderBy( ~ age, kid.weights))

## 'x <- kid.weights[order(kid.weights$age)], x''orderBy( ~ age, kid.weights)'가 같다 보면 됨.

    age weight height gender

14 3 10 29 F

79 3 12 23 F

100 3 13 24 F

146 3 13 24 F

173 3 12 23 F

189 3 17 27 F

>

> y <- kid.weights[order(kid.weights$weight), ]

> head(y)

    age weight height gender

14 3 10 29 F

28 5 11 25 M

46 5 11 23 F

196 5 11 23 F

79 3 12 23 F

173 3 12 23 F

> head(orderBy( ~ weight, kid.weights))

    age weight height gender

14 3 10 29 F

28 5 11 25 M

46 5 11 23 F

196 5 11 23 F

79 3 12 23 F

173 3 12 23 F

>

> z <- kid.weights[order(kid.weights$gender, kid.weights$weight), ]

> head(z)

    age weight height gender

14 3 10 29 F

46 5 11 23 F

196 5 11 23 F

79 3 12 23 F

173 3 12 23 F

209 4 12 23 F

> head(orderBy( ~ gender + weight, kid.weights))

## 성별(gender)를 기준으로 1, 몸무게(weight)를 기준으로 2차 정렬

    age weight height gender

14 3 10 29 F

46 5 11 23 F

196 5 11 23 F

79 3 12 23 F

173 3 12 23 F

209 4 12 23 F

>

> tail(orderBy( ~ time, reaction.time))

    age gender control time

59 25+ M T 1.527699

54 25+ M T 1.536446

30 25+ F T 1.562813

42 25+ F C 1.583610

24 25+ M C 1.594901

58 25+ F T 1.614979

> u <- reaction.time[order(reaction.time$time), ]

> tail(u)

age gender control time

59 25+ M T 1.527699

54 25+ M T 1.536446

30 25+ F T 1.562813

42 25+ F C 1.583610

24 25+ M C 1.594901

58 25+ F T 1.614979

>

> tail(orderBy( ~ gender + age + time, reaction.time))

    age gender control time

28 25+ M T 1.502757

53 25+ M T 1.517435

40 25+ M T 1.520106

59 25+ M T 1.527699

54 25+ M T 1.536446

24 25+ M C 1.594901

> v <- reaction.time[order(reaction.time$gender, reaction.time$age, reaction.time$time), ]

> tail(v)

    age gender control time

28 25+ M T 1.502757

53 25+ M T 1.517435

40 25+ M T 1.520106

59 25+ M T 1.527699

54 25+ M T 1.536446

24 25+ M C 1.594901

>

> #### 3.4 데이터의 결합 및 분리 ####

>

> # 3.4.1 rbind()cbind() 함수를 이용한 데이터 결합

> name <- c("Cha","Park","Jung","Kim","Lee")

> toeic <- c(900, 850, 990, 690, 730)

> gpa <- c(4.5, 3.8, 4.5, 3.2, 3.1)

> data <- data.frame(toeic, gpa)

> data

  toeic gpa

1 900 4.5

2 850 3.8

3 990 4.5

4 690 3.2

5 730 3.1

>

> rData <- rbind(data, c(900, 4.5)) ## datac(900, 4.5)를 행으로 결합

> rData

  toeic gpa

1 900 4.5

2 850 3.8

3 990 4.5

4 690 3.2

5 730 3.1

6 900 4.5

>

> cData <- cbind(data, name, stringsAsFactors=F)

## dataname을 열로 결합 (이름이 문자이므로 팩터변환 FALSE)

> cData

  toeic gpa name

1 900 4.5 Cha

2 850 3.8 Park

3 990 4.5 Jung

4 690 3.2 Kim

5 730 3.1 Lee

>

> # 3.4.2 merge() 함수를 이용한 데이터 프레임 결합 #

> idNum <- c(2018001, 2018003, 2018002, 2018004, 2018005)

> gender <- c("M", "F", "M", "F", "F")

> grade <- c("B", "A", "C", "B", "F")

> dataA <- data.frame(idNum, gender, grade)

> dataA

  idNum gender grade

1 2018001 M B

2 2018003 F A

3 2018002 M C

4 2018004 F B

5 2018005 F F

>

> idNum <- c(2018002, 2018001, 2018003, 2018004, 2018005, 2018009)

> rScore <- c(80, 95, 60, 80, 50, 90)

> pythonScore <- c(85, 90, 80, 85, 55, 90)

> dataB <- data.frame(idNum, rScore, pythonScore)

> dataB

  idNum rScore pythonScore

1 2018002 80 85

2 2018001 95 90

3 2018003 60 80

4 2018004 80 85

5 2018005 50 55

6 2018009 90 90

>

> merge(dataA, dataB)

## 공통변수를 기준으로 합병한 후 자동 오름차순 정렬, 변수가 결측값이 있는 행은 생략

   idNum gender grade rScore pythonScore

1 2018001 M B 95 90

2 2018002 M C 80 85

3 2018003 F A 60 80

4 2018004 F B 80 85

5 2018005 F F 50 55

> merge(dataA, dataB, by='idNum')

## 'idNum'을 기준으로 합병 및 정렬, 결측값 행 생략 (위와 동일)

   idNum gender grade rScore pythonScore

1 2018001 M B 95 90

2 2018002 M C 80 85

3 2018003 F A 60 80

4 2018004 F B 80 85

5 2018005 F F 50 55

> merge(dataA, dataB, by='idNum', all=TRUE)

## 공통변수 idNum에 일치하지 않는 경우도 결합된 데이터 프레임에 포함

   idNum gender grade rScore pythonScore

1 2018001 M B 95 90

2 2018002 M C 80 85

3 2018003 F A 60 80

4 2018004 F B 80 85

5 2018005 F F 50 55

6 2018009 <NA> <NA> 90 90

>

> # 3.4.3 split() 함수를 이용한 데이터 분리 #

> install.packages("UsingR")

> library(UsingR)

> split(reaction.time, reaction.time$gender)

$F

age gender control time

1 16-24 F T 1.360075

4 16-24 F T 1.390647

8 16-24 F T 1.461187

9 16-24 F T 1.382461

12 16-24 F T 1.331092

14 16-24 F C 1.330471

15 16-24 F T 1.344506

17 16-24 F T 1.520244

19 16-24 F T 1.348420

20 16-24 F T 1.373000

22 25+ F C 1.384192

26 25+ F T 1.472212

27 25+ F T 1.440685

(이하생략)

 

$M

age gender control time

2 16-24 M T 1.467939

3 16-24 M T 1.512036

5 16-24 M T 1.384208

6 16-24 M C 1.393875

7 16-24 M T 1.419043

10 16-24 M C 1.260152

11 16-24 M T 1.292917

13 16-24 M T 1.369171

16 16-24 M C 1.357869

18 16-24 M T 1.352397

21 25+ M C 1.306813

23 25+ M T 1.345643

24 25+ M C 1.594901

25 25+ M T 1.341972

28 25+ M T 1.502757

(이하생략)

 

댓글