R 행 합계 - R haeng habgye

Data Analysis

『R』 결측치 처리 및 열끼리 행끼리 계산하기 (is.na, na.rm)

'결측치'라는 건 비어있다정도로 해석을 하고 있다.

실습데이터들은 대체로 비어있는 것이 없지만, 실제 데이터를 보다보면 결측치는 어마어마하게 많이 존재한다.

결측치는 그냥 비어있는 칸이기 때문에 계산할때 제대로 실행되지 않는 경우가 많다.

첨부되어 있는 파일을 보면 몇 개의 칸은 비어있는 걸 볼 수 있다.

'시험을 안 봤다면 점수가 없고 아예 비어둔다.' 정도로 생각 할 수 있다.

우리가 손쉽게 할 수 있는 덧셈이나 평균을 낼 때 이런 값들이 있다면, 계산불가...

RStudio에서 살펴보자.

#### 결측치 처리 및 열끼리 행끼리 계산하기 ####
# 파일 읽어오기
score = read.csv("score.csv", stringsAsFactors = FALSE)

# 파일 확인하기
score

# 파일을 보면 NA라는 값들이 들어있다. 저걸 결측치라고 한다.

# 실제 엑셀 파일에서는 비어있는 값을 R에서는 NA라고 표기한 것.

# 이대로 계산해보기
# 열 더하기
sum(score$국어) # 국어 열을 모두 더해라.
mean(score$영어) # 영어 열을 평균내라.

# 계산하는 열에 NA값이 존재하면 이런 식으로 계산 불가하다.

# NA를 0으로 바꾸자
# 국어열 NA = 0 으로 바꾸기
score_2 = score
score_2[ is.na(score_2$국어), "국어"] = 0
score_2

# score_2라는 곳에 일단 score를 복사해놓고

# score_2에서 국어 열이 na라면 0을 넣어라. 라는 뜻이다.

# 결과를 보면 국어 열만 NA대신에 0이 들어간 것을 알 수 있다.

# 계산해보기
# 열 더하기
sum(score_2$국어)
mean(score_2$영어)

# 국어열은 NA를 0으로 바꿨기 때문에 계산이 가능하지만

# 영어열은 여전히 NA값이 존재하여 계산 불가능

# 모든 데이터의 결측치를 처리하는 법(0으로 바꾸자)
score_3 = score
score_3[is.na(score_3)] = 0
score_3

# 우선 score_3에 score을 복사하고

# score_3에 있는 모든 NA를 0으로 바꿔라. 라는 뜻이다.

# NA값이 모두 0으로 바뀐 것을 볼 수 있다.

# 계산하기
# 열 더하기
sum(score_3$국어)
mean(score_3$영어)

#### 일일히 열을 계산하기에는 귀찮은 짓이다. 한번에 계산하는 방법 ####

# 열끼리 행끼리 계산하기

colSums(score_3)
rowSums(score_3)

# 이대로 계산하면 에러가 나온다. 왜냐하면 score_3을 보게되면 사람 이름이 적혀있다.

# 합이나, 평균을 구하려하는데 사람이름이 나오면 구할 수가 없기 때문이다.

# 열끼리 행끼리 계산하기

# 그래서 이름란을 뺴야한다. [,-1]이라는 건 첫 번째 열을 삭제한다는 것이다.

score_3 = score_3[,-1]
score_3

# 제거한 상태로 계산하면 아래와 같이 결과가 나온다.

colSums(score_3)
rowSums(score_3)

#### 따로 결측치를 처리하지 않고 계산하는 방법 ####

# 또 다른 방법으로는 colSums의 사용법을 보면 na를 제거하고 계산할 수 있는 사용법이 적혀있다.

# 함수의 기본 사용법과 어떻게 사용하는 지 궁금할 때는 R에 "?함수이름"라고 적으면 친절하게 설명해준다.

?colSums

# 오른쪽 밑에 Help에 창이 뜬다.

# Description을 보면 na.rm = FALSE 가 기본사용법으로 적혀있는 것을 볼 수 있다.

# 이 뜻은 따로 na.rm을 적지 않으면 na.rm  = FALSE로 간주한다는 뜻이다.

# score_4에 복사해주고 이 역시도 사람 이름은 계산할 수 없기 때문에 이름열을 뺴준다.

score_4 = score
score_4 = score_4[,-1]
score_4

# NA값이 그대로 존재하는 것을 볼 수 있다.

# 이대로 colSums와 rowSums를 계산해보자.

colSums(score_4, na.rm = TRUE)
rowSums(score_4, na.rm = TRUE)

# na.rm이란 na remove. 즉, 계산할 때 na값을 제거하고 계산한다는 뜻이다. 

# na값을 처리하지 않아도 na.rm = TRUE 라고 적으면 알아서 0값으로 계산하고 처리해준다.

R 행 합계 - R haeng habgye

해당 포스트에서는 R에서 행 평균값을 계산하여 새로운 컬럼에 저장하는 방법을 소개합니다.

1. INTRO

R에는 평균을 계산해 주는 mean() 기본 함수가 있습니다. 벡터 또는 리스트 내의 평균을 계산하는 경우는 mean() 함수로 간단히 해결할 수 있지만, 행 별로 평균을 계산해야 하는 경우는 다른 풀이가 필요합니다.

아래에서는 네이버 지식인에 올라온 질문을 기반으로 tibble()data.frame() 구조에서 행별 평균을 구하는 방법을 설명드리겠습니다.

R 행 합계 - R haeng habgye
▲ 네이버 지식인 질문

2. 문제 풀이

tibble 사용하기

데이터 생성

먼저 질문자가 제시한 표를 데이터(mydata)로 생성해 보겠습니다. 참고로 아래 내용에 dplyr 문법이 언급된 것이 보이니 tibble() 구조로 생성하겠습니다.

library(tidyverse)

mydata <- tibble(
  이름  = c("김철수", "김영희", "박영수"),
  수학  = c(50, 58, 65),
  과학  = c(46, 58, 87),
  영어  = c(13, 74, 13)
)
mydata
# A tibble: 3 x 4
  이름    수학  과학  영어
      
1 김철수    50    46    13
2 김영희    58    58    74
3 박영수    65    87    13


문제에서 제시한 데이터와 동일한 구조의 데이터가 생성되었습니다. 이제 각 행(이름) 별로 평균을 계산하고 새로운 컬럼을 만들어 저장해 보겠습니다.

새로운 컬럼에 평균값 저장

dplyr 패키지에서는 새로운 컬럼을 생성하여 데이터를 저장할 수 있도록 mutate() 함수를 제공하고 있습니다. 자세한 설명은 dplyr 공식 페이지 에서 확인할 수 있으며, 이번 포스트에서는 문제 풀이에 필요한 부분만 다루겠습니다.

mutate()함수는 'mutate(새로운컬럼명 = 계산식)'으로 간단하게 사용할 수 있으며 이번 문제에서는 새로운 컬럼명에 '평균'을 넣고 계산식에 '(수학+과학+영어)/3'를 입력하면 됩니다. 이 내용을 코드로 보면 아래와 같습니다.

mydata_add_mean <- mydata %>% 
  mutate(평균 = (수학+과학+영어)/3)

mydata_add_mean
# A tibble: 3 x 5
  이름    수학  과학  영어  평균
       
1 김철수    50    46    13  36.3
2 김영희    58    58    74  63.3
3 박영수    65    87    13  55

출력 결과를 보면, 계산식이 정상적으로 계산되어 새로운 컬럼인 평균에 저장된 것을 볼 수 있습니다.

dplyr 패키지를 사용하지 않는다면?

위 풀이는 dplyr 패키지를 사용한 풀이로, 질문자 분이 요청에 맞춰 작성되었습니다. 그러나 초심자 분들은 tidyverse 의 tibble() 자료 구조보다 기본 구조인 data.frame이 더 익숙하실 거라 생각됩니다.

데이터 생성

데이터는 위에서 생성한 mydatadata.frame()로 변경하여 사용하겠습니다.

mydata2 <- as.data.frame(mydata)
mydata2
    이름 수학 과학 영어
1 김철수   50   46   13
2 김영희   58   58   74
3 박영수   65   87   13

tibble() 구조의 데이터를 as.data.frame() 함수를 이용해 데이터 프레임 구조로 변경하여 mydata2 변수에 저장하였습니다.
출력 결과를 보면 tibble()과는 다르게 각 컬럼의 타입이 무엇인지 나타나지 않는 것을 볼 수 있습니다. 이 부분은 사소하지만 필요한 정보를 먼저 제공해 주는 tibble()이 좀 더 유용하다고 생각됩니다.

새로운 컬럼에 평균값 저장

위 풀이와 동일하게 '평균' 컬럼을 생성해 보겠습니다.

mydata2$평균 <- rowMeans(mydata2[,c('수학','과학','영어')])
mydata2

# 같은 결과
# mydata2$평균 <- (mydata2$수학 + mydata2$과학 + mydata2$영어)/3
# mydata2
    이름 수학 과학 영어     평균
1 김철수   50   46   13 36.33333
2 김영희   58   58   74 63.33333
3 박영수   65   87   13 55.00000

출력 결과를 보면 소수점 표현이 약간 다르지만 같은 결과가 출력된 것을 볼 수 있습니다.

위에서 사용한 rowMeans()함수는 2차원 배열을 가지는 데이터셋에서 행 평균을 구해주는 함수로, mydata2에서 '수학, 과학, 영어' 컬럼만 선택한 뒤 rowMeans()로 행 평균을 계산하여 '평균' 컬럼에 저장하였다고 생각하시면 됩니다.

3. 마무리

이번 포스트에서는 R에서 행평균을 계산하여 새로운 컬럼에 저장하는 방법을 설명하였습니다. 결과는 같더라도 과정은 다양할 수 있으며, 자신만의 스타일 또는 주어진 환경을 고려해 문제를 해결하시면 됩니다.

참고로 R은 한글 친화적인 언어가 아니다보니 한글을 변수명이나 데이터에 사용하는 경우 다양한 에러가 발생할 수 있습니다. 가능하다면 한글 변수명이나 데이터는 영어로 치환하여 작업하시는 것을 추천드립니다.

4. 관련링크

[1] tidyverse 공식페이지
[2] dplyr 공식페이지


R 행 합계 - R haeng habgye