Learning & Reasoning/R

R datatype 간단 정리

이현봉 2013. 2. 20. 16:39

R 에서 쓰이는 데이터 타입들이 조금씩 헷갈린다.  다시 vector 부터 bottom-up 으로 정리해 보자.

1. vector

일련의 연속된 순서를 갖는 element 들로 만들어진 데이터 구조. 다른 언어에서 1차원 array를 연상하면 됨. 역시 마찬가지로 vector 내의 element들은 모두 같은 mode(data type) 이어야 함.

R은 scalar 타입이 없으므로 R에서 scalar 같이 쓰인 것은 실제로 one-element 벡터임.

> v <- 1:12
> str(v)
 int [1:12] 1 2 3 4 5 6 7 8 9 10 ...

위의 벡터 v의 모드는 integer이다. 벡터는 그 element들의 모드에 따라 integer, numeric(실수), character(string), logical(Boolean), complex 종류가 있다.

2. array

array는 실제 vector이다. 다만 다른 언어에서와 같이 dimension을 갖고 있다. 단순히 생각해 array는 vector 데이터 구조에 추가로 "dim" attribute를 갖고 있다고 생각하면 됨.  array는 벡터이므로 그 element들이 같은 mode이어야 함.  따라서 array는 vector와 같이 integer, numeric, character, logical, complex 모드 타입 array 종류들이 있다.

3-dimensional array a[3,2,2]를 vector로 간주하면 그 순서가 a[1,1,1], a[2,1,1], a[3,1,1], a[1,2,1], a[2,2,1] ,,, a[2,2,2], a[3,2,2] 형태로 대응된다.

> dim(v) <- c(3,2,2)
> v
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8   11
[3,]    9   12

> str(v) int [1:3, 1:2, 1:2] 1 2 3 4 5 6 7 8 9 10 ... # v가 3-D array이며 그 index range를 표시

위와 같이 기존 vector에 "dim" attribute를 주어서 array로 만들 수 있고 또는 array() 를 써서 만들수도 있다. array()를 써서 만들 때 좋은 점은 array를 만들 때 recycling rule이 적용되는 것이다. 이는 위에서 단순히 기존 벡터에 "dim" attribute만 추가/변경했을 때 element 숫자가 맞지 않으면 에러를 발생하는 것과 차별된다.

> vv = 1:10
> vv = 1:10 ; vva = array(vv, dim=c(3,2,2))
> vva
, , 1

     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

, , 2

     [,1] [,2]
[1,]    7   10
[2,]    8    1    # vv[1] 이 recycle
[3,]    9    2    # vv[2] 이 recycle



3. matrix

matrix는 단순히 2-차원 array이다. 그러니 array의 모든 특성이 그대로 따라온다. 당연히 vector의 특성도. matrix 데이터타입이 두루두루 편리하게 많이 쓰이기에 R은 array의 한 형태인 matrix를 별도로 사용할 수 있게 해 주었다. matrix는 모든 vector로부터 만들 수 있다.

> vm <- matrix(v, nrow=4) # 앞의 [3,2,2] array를 matrix로. array도 벡터이니까 가능. > vm [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12

* matrix가 많이 쓰이는 데이터구조인데 비해 external file(소스)로 부터 직접 marix로 불러드리는 함수가 없다. 물론 matrix로 읽어드리면 내부의 element들은 모두 같은 mode이게 된다. 따라서 column들의 타입들이 서로 다를 때 어찌 어찌해서 matrix로 읽어드렸다면 모두 하나의 mode로 coerce(casting)이 될 수 밖에 없다. 즉, 개별 variable들의 모드를 잃는다. 아래와 같이 data frame으로 읽어드리는 read.table() 또는 scan()을 써서 일단 읽은 후에 이를 다시 as.matrix()를 써서 matrix로 만들 수는 있다.

일반적으로 matrix가 data.frame보다 메모리 사이즈가 작다. matrix 계산은 당연히 matrix 타입으로 해야 하고. matrix 타입으로 할 수 있는 것을 data frame으로 할 필요 없다. 단, matrix는 row name, col name을 달 수 없기에 이 점이 꼭 필요하면 data frame을 써야 하고.

read.matrix <- function(filename, mode_wanted) {
as.matrix(read.table(filename), mode=mode_wanted) # mode argument가 작동않고. vector의 일반 coerce가 작동??
}

* factor들로 만들어진 data.frame을 해당 level에 대응되는 numeric 으로 된 matrix로 만들려면 data.matrix() 사용.

4. List
An R list is an object consisting of an ordered collection of objects known as its components. 즉, List는 component들로 구성되었는데, component들은 리스트내에서 순서를 갖고 있고 각자 다른 object 타입일 수 있다. 그러니, List는 어떤 mode를 갖고 있다고 할 수 없다.

리스트내의 component들은 이름(name)을 갖을 수 있기에 리스트의 특정 component에 접근할 때 그 이름을 쓸 수 있다 (ie. listname$component_name 또는 listname[["component_name"]]). 만약 listname 리스트에서 component_name 이 3번째 component라면 listname[[3]]도 같은 component를 access한다.


5. Data frame

data frame은 (기본적으로) 리스트이며 "data.frame" 이라는 class attribute를 갖는다. data frame은 list와 똑 같지는 않고 data frame만의 몇 가지 독특한 특성을 갖는다;

*The components must be vectors (numeric, character, or logical), factors, numeric, matrices, lists, or other data frames. component들의 타입이 자유롭다

* Matrices, lists, and data frames provide as many variables to the new data frame as they have columns, elements, or variables, respectively.

* Numeric vectors, logicals and factors are included as is, and character vectors are coerced to be factors, whose levels are the unique values appearing in the vector.

* Vector structures appearing as variables of the data frame must all have the same length, and matrix structures must all have the same row size. 즉, 기존 4x3 data frame m에 cbind(m, foo=c(2,3,3)) 하여 row 개수가 맞지 않으면 에러 발생. recycle이 되지 않는다. 만약 data frame의 variable들이 matrix라면, 그 matrix들의 row 개수가 모두 같아야 한다.

많은 경우 data frame을 제각각의 mode와 attribute를 갖는 column들로 이루어진 matrix라고 간주하면 편리하다. data frame may be displayed in matrix form, and its rows and columns extracted using matrix indexing conventions.

data frame은 observation/row 명과 variable/column명이 있다.만약 data frame을 만들면서 이 명칭들을 제공하지 않으면 R이 대신 만들어준다.

data frame을 만들 때 보통 기존의 파일이나 다른 출처로 부터 import해 만든다 ;

1. read.table()

왜 이것을 read.dataframe이라 하지 않았는지 궁금하다. 그리고 R도 다른 객체지향 언어와 같이 dataframe.read() 식으로 해도 되었을 터인데 왜 이런 식으로 했는지?

read.table()은 external data file의 첫째 줄이 variable(component, column) 명을 갖고 있다고 간주하고, 또한 둘째줄 부터 observation을 표시하며 각 row/observation의 첫째 item은 row label일 것이라 간주함. 이럴 경우 둘째 줄부터의 item 갯수는 첫째 줄의 item 개수보다 하나 더 많게되며 (첫째 줄은 row label이 없을 것이므로), read.table()이 이런 패턴을 확인하고 데이터를 로드함.

만약 데이터파일이 row label을 갖고 있지 않다면 read.table("파일명", header=TRUE) 라는 형태로 해 read.table()에게 알려주어야 함. (R-intro, pp 32-33)

2. scan()