5  R 팩터(factor)

R 언어는 원래 통계 분석을 염두에 두고 개발된 언어답게, 통계학에서 다루는 카테고리형(categorical) 변수 및 순서형(ordinal) 변수를 위한 특수한 형태의 벡터를 지원한다.

참고로 통계학에서는 (책마다 조금씩 다르기는 하지만) scales of measurement을 다음과 같이 정의한다.

통계학에는 어떤 변수가 어떤 scales을 가지는지에 따라서 데이터를 써머리하거나 그래프를 만들거나, 통계 검정법을 어떤 것을 쓸지가 결정되기 때문에 무척 중요하다.

이런 내용은 R 언어에서도 중요하다. 여기에서 카테고리형 변수를 표현하기 위한 R 팩터 데이터 타입에 대해서 설명한다.

5.1 문자열 벡터와 팩터(factor)

뇌전증 약물의 효과를 “sz_free”, “more_than_fifty”(>= 50%), “less_than_fifty”(< 50%), “no_response”로 구분한다고 생각해 보자.

20명의 결과가 다음과 같다고 해보자.

treatment_effect <- c("sz_free", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "no_response", "sz_free", "sz_free", "more_than_fifty")
treatment_effect
 [1] "sz_free"         "sz_free"         "more_than_fifty" "less_than_fifty"
 [5] "less_than_fifty" "no_response"     "sz_free"         "more_than_fifty"
 [9] "less_than_fifty" "less_than_fifty" "no_response"     "sz_free"        
[13] "more_than_fifty" "less_than_fifty" "less_than_fifty" "no_response"    
[17] "no_response"     "sz_free"         "sz_free"         "more_than_fifty"

지금 treatment_effect 벡터는 문자열 벡터이다. 이 상태로도 기본 계산 등은 가능하다. 예를 들어 각 카테고리와 거기에 해당되는 개수를 카운팅해 보자. 이런 것을 contingency table이라고 한다. R에 table() 함수는 이런 contigency table을 만들어 주는 함수이다.

table(treatment_effect)
treatment_effect
less_than_fifty more_than_fifty     no_response         sz_free 
              6               4               4               6 

이를 바탕으로 막대 그래프(bar plot)을 만들 수 있다.

barplot(table(treatment_effect), col = "orange3")

Contingency table이나 bar plot을 자세힌 관찰해 보면 이 데이터가 가지고 있는 순서(ordinal)의 의미를 제대로 반영하지 못하고 있다. 이런 문제를 해결하기 위해서는 이 벡터를 팩터, 특히 ordinal 의미가 있는 팩터(factor)로 만들어줄 필요가 있다.

5.2 팩터로 만들기

다음 문자열 벡터 treatment_effectfactor() 함수를 사용하여 팩터로 만들고자 한다.

treatment_effect <- c("sz_free", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "sz_free", "more_than_fifty", "less_than_fifty", "less_than_fifty", "no_response", "no_response", "sz_free", "sz_free", "more_than_fifty")
treatment_effect
 [1] "sz_free"         "sz_free"         "more_than_fifty" "less_than_fifty"
 [5] "less_than_fifty" "no_response"     "sz_free"         "more_than_fifty"
 [9] "less_than_fifty" "less_than_fifty" "no_response"     "sz_free"        
[13] "more_than_fifty" "less_than_fifty" "less_than_fifty" "no_response"    
[17] "no_response"     "sz_free"         "sz_free"         "more_than_fifty"

R 언어에서 어떤 팩터가 취할 수 있는 값들의 종류를 그 팩터의 레벨(levels)라고 한다. 그리고 그 레벨은 다음과 같이 factor() 함수에서 levels라는 인자로 지정할 수 있다.

tx_factor <- factor(treatment_effect,
    levels = c("sz_free", "more_than_fifty", "less_than_fifty", "no_response")
)
tx_factor
 [1] sz_free         sz_free         more_than_fifty less_than_fifty
 [5] less_than_fifty no_response     sz_free         more_than_fifty
 [9] less_than_fifty less_than_fifty no_response     sz_free        
[13] more_than_fifty less_than_fifty less_than_fifty no_response    
[17] no_response     sz_free         sz_free         more_than_fifty
Levels: sz_free more_than_fifty less_than_fifty no_response

levelsfactor() 함수에서 지정하지 않으면 값들을 읽어서 자동으로 레벨을 정하고 (의미없는) 알파벳 순서에 따르게 된다. 성별과 같이 순서가 중요하지 않은 완전한 nominal data라면 이 방법을 따라도 좋다. 하지만 분석과 결과에서 일관성을 유지하려면 levels을 지정하는 것이 좋다.

위에서 팩터를 출력한 결과를 보면, 마지막에 “Levels: …”가 보인다. 이것을 보더라도 이 변수가 팩터이고, 이런 순서로 레벨이 정해져 있음을 알 수 있다. 또 어떤 팩터 벡터의 레벨을 확인할 때는 levels()라는 함수를 사용한다.

levels(tx_factor)
[1] "sz_free"         "more_than_fifty" "less_than_fifty" "no_response"    

이제 팩터로 제대로 바뀌었으니까, 다시 contingency table과 bar plot을 만들어 보자. 위에 문자열 벡터로 시행했던 결과들과 비교해 보면, 치료의 효과라는 순서(order)에 따라, 우리가 지정한 levels에 따라서 표가 정리되고, 막대 그래프가 만들어지는 것을 확인할 수 있다.

table(tx_factor)
tx_factor
        sz_free more_than_fifty less_than_fifty     no_response 
              6               4               6               4 
barplot(table(tx_factor), col = "steelblue")

5.3 더 참고할 자료

R의 카테고리형 데이터를 표시하는 팩터(factor)는 때로는 아주 까다로운 문제로 다가올 수 있다. 이 페이지에서 설명한 기초를 이해하고, 팩터를 사용하다 곤란한 문제가 생기면 forcats라는 팩터를 전문으로 다루는 패키지가 해법이 될 수 있다. 팩터와 이 패키지 사용법은 다은 자료에 아주 잘 설명되어 있다.