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

R 데이터 가공: 결측값 처리, 그룹별 요약통계량 계산, 변환

by 냉철하마 2021. 4. 29.

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

www.yes24.com/Product/Goods/68712840

 

R 통계 프로그래밍의 이해

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

www.yes24.com

 

> #### 3.5 결측값 처리 ####

>

> # 3.5.1 na.omit() 함수 #

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

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

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

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

> xyz <- data.frame(name, gender, toeic, gpa)

> xyz

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 850 3.8

3 Jung M NA 4.5

4 Kim F 690 3.2

5 Lee F 730 NA

>

> na.omit(xyz) ## 결측값 NA가 포함된 행 전체를 제거

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 850 3.8

4 Kim F 690 3.2

>

> # 3.5.2 complete.cases() 함수 #

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

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

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

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

> xyz <- data.frame(name, gender, toeic, gpa)

>

> xyz.complete <- xyz[complete.cases(xyz), ] ## complete.cases() 적용 후 TRUE값만 출력

> complete.cases(xyz) ## 결측값 없는 행이면 TRUE, 있는 행이면 FALSE

[1] TRUE TRUE FALSE TRUE FALSE

> xyz.complete ## 결과값은 na.omit()과 동일하게 출력됨

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 850 3.8

4 Kim F 690 3.2

>

> # 3.5.3 is.na() 함수 #

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

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

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

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

> xyz <- data.frame(name, gender, toeic, gpa)

> xyz

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 850 3.8

3 Jung M NA 4.5

4 Kim F 690 3.2

5 Lee F 730 NA

>

> is.na(xyz$toeic) ## NA이면 TRUE, 아닌 경우는 FALSE로 반환

[1] FALSE FALSE TRUE FALSE FALSE

> xyz$toeic[is.na(xyz$toeic)] <- 0 ## 결측값 NA0점으로 만듬

> is.na(xyz$gpa)

[1] FALSE FALSE FALSE FALSE TRUE

> xyz$gpa[is.na(xyz$gpa)] <- 0

> xyz

   name gender toeic gpa

1 Cha M 990 4.5

2 Park F 850 3.8

3 Jung M 0 4.5

4 Kim F 690 3.2

5 Lee F 730 0.0

>

> #### 3.6 그룹별 요약통계량 계산 ####

>

> # 3.6.1 aggregate() 함수를 이용한 그룹별 요약통계량 계산 #

> install.packages("UsingR")

> library(UsingR)

> levels(reaction.time$age)

[1] "16-24" "25+"

> levels(reaction.time$gender)

[1] "F" "M"

> levels(reaction.time$control)

[1] "C" "T"

>

> aggregate(time ~ age, reaction.time, mean)

## 나이(age)에 따라 평균(mean) 반응시간(time)에 차이가 있는지 확인

   age time

1 16-24 1.382586

2 25+ 1.449084

> aggregate(time ~ gender, reaction.time, mean)

## 성별(gender)에 따라 평균 반응시간(time)에 차이가 있는지 확인

  gender time

1 F 1.441481

2 M 1.412356

> aggregate(time ~ control, reaction.time, mean)

## 휴대폰 사용 여부(control)에 따라 평균 반응시간(time)에 차이가 있는지 확인

  control time

1 C 1.389613

2 T 1.445571

> aggregate(time ~ age + control, reaction.time, mean)

## 나이와 평균에 따라 반응시간 차이 확인 (2개 이상 변수의 조합별로 그룹을 묶음)

   age control time

1 16-24 C 1.335592

2 25+ C 1.403119

3 16-24 T 1.394334

4 25+ T 1.479728

> aggregate(time ~ age + gender + control, reaction.time, mean)

   age gender control time

1 16-24 F C 1.330471

2 25+ F C 1.428567

3 16-24 M C 1.337299

4 25+ M C 1.383326

5 16-24 F T 1.390181

6 25+ F T 1.492488

7 16-24 M T 1.399673

8 25+ M T 1.464649

> str(aggregate(time ~ age, reaction.time, mean))

  'data.frame': 2 obs. of 2 variables:

$ age : Factor w/ 2 levels "16-24","25+": 1 2

$ time: num 1.38 1.45

>

> # 3.6.2 doBy::summaryBy() 함수를 이용한 그룹별 요약통계량 계산 #

> install.packages("doBy")

> install.packages("UsingR")

> library(doBy)

> library(UsingR)

 

> head(reaction.time)

age gender control time

1 16-24 F T 1.360075

2 16-24 M T 1.467939

3 16-24 M T 1.512036

4 16-24 F T 1.390647

5 16-24 M T 1.384208

6 16-24 M C 1.393875

>

> summaryBy(time ~ age, reaction.time, FUN=mean)

## time ~ age : 운전자의 나이(age) 그룹에 따라 반응 시간(time)의 평균값(FUN=mean)을 계산

   age time.mean

1 16-24 1.382586

2 25+ 1.449084

> summaryBy(time ~ gender, reaction.time, FUN=mean)

## doBy::summaryBy() 함수는 aggregate() 함수와 달리 마지막 인수 부분에 "FUN="을 반드시 기록해야 함

   gender time.mean

1 F 1.441481

2 M 1.412356

> summaryBy(time ~ control, reaction.time, FUN=mean)

## summaryBy의 출력결과는 위 aggregate와 결과값 동일

   control time.mean

1 C 1.389613

2 T 1.445571

> summaryBy(time ~ age + control, reaction.time, FUN=mean)

   age control time.mean

1 16-24 C 1.335592

2 16-24 T 1.394334

3 25+ C 1.403119

4 25+ T 1.479728

> summaryBy(time ~ age + gender + control, reaction.time, FUN=mean)

   age gender control time.mean

1 16-24 F C 1.330471

2 16-24 F T 1.390181

3 16-24 M C 1.337299

4 16-24 M T 1.399673

5 25+ F C 1.428567

6 25+ F T 1.492488

7 25+ M C 1.383326

8 25+ M T 1.464649

>

> #summaryBy() 함수를 이용한 그룹별 함수 계산

> fn <- function(x){

+ c(m=mean(x), n=length(x), r=max(x))

+ }

> summaryBy(time ~ age + gender + control, reaction.time, FUN=fn) ## reaction.time에서의 그룹별 합수 계산

   age gender control time.m time.n time.r

1 16-24 F C 1.330471 1 1.330471

2 16-24 F T 1.390181 9 1.520244

3 16-24 M C 1.337299 3 1.393875

4 16-24 M T 1.399673 7 1.512036

5 25+ F C 1.428567 7 1.583610

6 25+ F T 1.492488 13 1.614979

7 25+ M C 1.383326 9 1.594901

8 25+ M T 1.464649 11 1.536446

> ## 'user defined function'이므로 사용자 임의로 응용 가능

> func. <- function(y){

+ c(mean=mean(y))

+ }

> summaryBy(age + weight + height ~ gender, kid.weights, FUN=func.)

## 응용: kid.weights에서의 그룹별 함수 계산

  gender age.mean weight.mean height.mean

1 F 45.41085 36.62016 36.03876

2 M 50.65289 40.26446 37.04132

 

> #### 3.7 데이터의 변환 ####

> y <- 101:120

> trt <- rep(LETTERS[1:4], each=5) ## 대문자 AAAAABB ... DDD를 만들어 trt 변수에 등록

> treatment = factor(paste("treatment", trt, sep=""))

## trt "treatment"에 결합 (treatmentA, treatmentA, ...., treatmentD)

> stackData <- data.frame(y, treatment) ## y treatment를 합쳐 stack된 데이터 프레임을 생성

> stackData

   y treatment

1 101 treatmentA

2 102 treatmentA

3 103 treatmentA

4 104 treatmentA

5 105 treatmentA

6 106 treatmentB

7 107 treatmentB

8 108 treatmentB

9 109 treatmentB

10 110 treatmentB

11 111 treatmentC

12 112 treatmentC

13 113 treatmentC

14 114 treatmentC

15 115 treatmentC

16 116 treatmentD

17 117 treatmentD

18 118 treatmentD

19 119 treatmentD

20 120 treatmentD

>

> unstackData <- unstack(stackData, y ~ treatment)

## stack된 데이터를 unstack 데이터로 변환 (실험계획 분야에서 많이 활용)

> unstackData

   treatmentA treatmentB treatmentC treatmentD

1 101 106 111 116

2 102 107 112 117

3 103 108 113 118

4 104 109 114 119

5 105 110 115 120

>

> newstackData <- stack(unstackData) ## unstack된 데이터를 다시 stack 데이터로 변환

> newstackData

   values ind

1 101 treatmentA

2 102 treatmentA

3 103 treatmentA

4 104 treatmentA

5 105 treatmentA

6 106 treatmentB

7 107 treatmentB

8 108 treatmentB

9 109 treatmentB

10 110 treatmentB

11 111 treatmentC

12 112 treatmentC

13 113 treatmentC

14 114 treatmentC

15 115 treatmentC

16 116 treatmentD

17 117 treatmentD

18 118 treatmentD

19 119 treatmentD

20 120 treatmentD

>

> names(newstackData) <- (c("y", "treatment")) ## 다시 stack된 데이터에 이름(names) 붙이기

> newstackData

   y    treatment

1 101 treatmentA

2 102 treatmentA

3 103 treatmentA

4 104 treatmentA

5 105 treatmentA

6 106 treatmentB

7 107 treatmentB

8 108 treatmentB

9 109 treatmentB

10 110 treatmentB

11 111 treatmentC

12 112 treatmentC

13 113 treatmentC

14 114 treatmentC

15 115 treatmentC

16 116 treatmentD

17 117 treatmentD

18 118 treatmentD

19 119 treatmentD

20 120 treatmentD

댓글