티스토리 뷰

기타/R

[R] 데이터 타입

words 2014. 1. 23. 17:19

아래 글의 내용은 Coursera의 Computing for Data Analysis 를 참고하였습니다. 문제시 삭제하겠습니다.



나는 대학원에서 Social Computing, Online Social Network analysis 등에 관해 연구를 하고 있는데, 데이터 분석을 위해 주로 R을 사용한다. 처음에는 연구실 사람들이 다 쓰니까 썼지만, R은 언어가 쉽기도 하지만 다양한 통계패키지들이 잘 되어 있고 비주얼라이제이션도 잘 되기 때문에 많이 사용되는 것 같다. 특히 R의 단점 중 하나가 싱글 머신에서의 대용량 처리에 적합하지 않다는 것인데 (single core를 이용하며, in-memory 방식으로 동작한다), 데이터 분석을 할때는 싱글머신 이상의 데이터를 한번에 올리는 경우는 그렇게 많지 않아 연구를 할 때 많이 사용된다.



<source: wikipedia.org>



R을 배우면서, 처음에 가장 혼란이 왔던 부분이 Data type이었던 것 같다. 나는 학부때 전산을 전공하고 주로 C, Java 같은 언어만 사용하다가 통계 연산이 주가 되는 R을 처음 사용하게 되었다. 거의 대부분의 데이터 타입이 벡터를 기반으로 하고 타입도 명시적으로 지정을 안해줘도 사용이 가능하여 데이터 타입에 대한 고민을 그렇게 하지 않았고 그때그때 찾아서 했던것 같다. 그래서 함수나 패키지 사용시에 헷갈리는 부분들이 많았던 것 같다. R 초심자들 대부분 비슷한 어려움을 겪을 것 같아 데이터 타입에 대해 정리해 봤다.


1. 기본 클래스

R에서는 모든 것이 벡터 (vector) 이다. 하나의 element만 있더라도 vector로 간주된다. 

벡터는 기본적으로 character (문자), numeric (실수), integer (정수), complex (복소수), logical (논리) 등의 타입을 가질 수 있으며, 한 벡터 내의 타입은 항상 같아야 한다.

이와는 다르게 List라는 타입의 자료구조는 서로 다른 class의 벡터를 가질 수가 있다.

예를 들어, 한 리스트의 첫번째 인덱스에는 character 벡터를 두번째 인덱스에는 실수형 벡터를 가질 수 있는 것이다. 이 리스트는 처음엔 다루기도 까다롭고 귀찮은데 여러모로 활용도가 높으니 사용법을 알아두면 좋다.


2. 데이터 할당

데이터 할당을 위해서는 <- 를 이용한다.

> a <- c(1, 2, 3)

> # a라는 객체에, [1,2,3] 이라는 실수형 벡터를 할당함.

# 는 주석의 역할을 한다.


3. 벡터 만들기

벡터를 만들기 위해서 c(), vector() 등의 함수를 사용한다.

첫째로, c()는 여러 벡터들을 붙여주는 (concatenate) 함수이다. 예를 들어 a <- c(1, 2) 와 같은 식으로 사용하여 벡터를 만들 수 있다. 이 경우에는 1과 2가 원소가 하나를 가지는 벡터로 간주되어 두 벡터가 합쳐진 [1, 2] 벡터가 생성되는 것이다.

이와는 다르게, vector()는 명시적으로 벡터 오브젝트를 만들게 되며, type 지정이 가능하다.

> a <- c(1,2) # [1, 2] 벡터를 생성

> b <- vector(mode="logical", length=2)   # 길이가 2인 논리 벡터를 생성


주의 - 벡터 할당 시에 서로 다른 종류의 타입이 들어온다면?

한 벡터는 한 가지의 타입만을 가질 수 있기 때문에 다른 타입의 element를 c()로 벡터로 만들려고 하면 coercion이 발생한다. 즉 하나의 타입으로 다 바뀌게 된다. 이 경우에는 직접 타입을 지정하는게 아닌 R에 의해 (implicitly) 변환 되는 것이므로 implict coercion이라고 부른다.


이와는 다르게 이미 있는 벡터의 타입을 명시적으로 바꾸는것도 가능하다. 예를 들어, a라는 정수형의 벡터가 있을 때, 다음과 같이 실수 형태의 벡터로 타입 캐스팅이 가능하다. (숫자 옆에 있는 L은 integer를 명시적으로 나타내는 것이다. 기본적으로 숫자는 numeric으로 취급된다)

> a <- c(1L, 2L, 3L)

> num.a <- as.numeric(a)


4. 행렬 (Matrices)

R에서 행렬은 특수한 타입의 벡터이다. 행렬도 기본적으로는 벡터이지만 벡터의 특성 (attributes)로 차원 (dimension)을 가진다. matrix() 함수를 이용해 생성이 가능하며, 기존의 vector에 특성으로 차원을 부여하여 만들 수도 있다.


혹은 cbind(), rbind() 를 써서 행렬을 만들 수 도 있는데, 벡터를 행 (r)이나 열 (c) 기준으로 붙인다고 (bind) 생각하면 된다.

이 함수들은 데이터 프레임을 이용할 때에도 자주 사용하게 되는 함수들이니 사용법을 익혀두면 좋다.


5. 리스트 (Lists)

리스트는 다른 클래스의 벡터들을 가지고 있을 수 있는 벡터이다. 앞에서 언급한 것 처럼, 활용도가 높은 자료구조이다. 키 (key)값에 따라 하위 자료구조를 접근할 수도 있어 여러모로 편리하며 행렬 형태의 데이터 프레임이 있을 때, split()이라는 함수를 이용하여 만들어낼 수도 있다.

쉽게 생각하면 파이썬의 사전 (dictionary), 혹은 자바의 맵 (Map)을 생각하면 되는데 R의 리스트는 키값들이 해싱되어 있지 않아 파이썬의 딕셔너리나 맵처럼 사용하면 극악의 퍼포먼스를 보인다. 즉, 키 값을 하나씩 접근하면서 비교하며 확인하게 된다. 이를 보완하기 위한 hash라는 자료구조가 있으며, 외부 패키지에 의해 사용이 가능하다 (이후 사용법을 정리해 보겠다).


6. 팩터 (Factors)

팩터는 카테고리 데이터를 나타낼때 사용할 수 있는 벡터인데, 기본적인 통계모델인 linear model 같은 것을 만들 때 카테고리 데이터를 넣을 수 있다. 예를 들어서 어떤 사람의 성별에 관한 값이 있을 것인데 (남자/여자) 그런것들을 나타낼 때는 Factor를 사용하면 된다.

아래 함수들은 factor에 관련된 함수들이다.


*table(factor): 각 level의 frequency를 준다. 즉, 각 카테고리 값들이 데이터 내에 얼마나 있는지를 보여주게 된다.

*unclass(factor): factor를 integer vector로 만든다. 팩터도 결국 벡터이기 때문에 같은 카테고리의 데이터는 같은 정수값을 가지게 된다.


7. Data frames

데이터 프레임은 아주 많이 사용되는 자료구조인데, 모든 벡터의 길이가 다 같은 list라고 보면 된다. 즉 행렬 형태의 자료구조라고 생각하면 되나 행렬은 한 타입의 값만을 가진다는 점에서 차이점이 있다.

이 자료구조를 많이 사용하는 이유는, 통계 데이터를 다루게 되면 각 데이터가 가지는 특성들 (예> 나이, 키, 몸무게 등등) 이 데이터 개수 만큼 있게 되는데 그것은 자연스럽게 테이블 구조를 띈다. RDBMS에서 많이 사용하는 릴레이션, 혹은 테이블과 같은 형태의 구조라고 생각하면 편할 수도 있겠다.


* data.matrix(data frame): 행렬로 데이터 타입을 바꿔주지만, 데이터 타입의 변경 (coercion)이 발생한다.


댓글