As.factor 함수 - as.factor hamsu

문자형 벡터의 원소가 국가명처럼 같은 것을 의미하는 문자열이 반복되고 있다면 문자열 벡터를 범주형 벡터로 변환하는 것이 좋다. 

nat <- c('KOREA','JAPAN','CHINA','USA','CHINA','KOREA','USA','JAPAN')
print(x=nat)

[1] "KOREA" "JAPAN" "CHINA" "USA"   "CHINA" "KOREA"  "USA"   "JAPAN"

# 문자형 벡터는 따옴표로 감싼 문자열로 출력됨

fct <- as.factor(x=nat)
print(x=fct)

[1] KOREA JAPAN CHINA USA   CHINA KOREA USA   JAPAN
Levels: CHINA JAPAN KOREA USA

# 레벨은 중복된 원소를 제거 후 오름차순으로 자동 설정됨

# 범주형 벡터 출력 시 따옴표 없는 문자열과 함께 맨 아래에 레벨이 추가됨

as.integer(x=fct)

[1] 3 2 1 4 1 3 4 2


범주형 벡터 레벨 순서 지정 시에는 factor( ) 함수를 사용한다. 

fct <- factor(x=nat, levels=c('KOREA','USA','CHINA','JAPAN'))
print(x=fct)

[1] KOREA JAPAN CHINA USA   CHINA KOREA USA   JAPAN
Levels: KOREA USA CHINA JAPAN

# levels에 지정된 문자형 벡터의 원소 순으로 레벨 설정 

as.integer(x=fct)

[1] 1 4 3 2 3 1 2 4

# levels의 순서가 바뀌었으니 범주형 벡터 원소도 그에 맞게 변경됨

R은 처음에 통계학의 도구로 쓰이기 시작했다. 통계학에서도 데이터 타입은 매우 중요하다. 통계학에서 카테고리형 변수를 표현하는 것이 '팩터(factor)'라는 데이터 구조이다. 이를테면 성별과 같은 것을 표현한다고 했을 때 성별에는 "M" 또는 "F"등과 같이 정해진 값들 가운데 하나가 선택된다. R에서는 이런 값들을 '팩터의 레벨(Levels) 이라고 부른다.

다음과 같은 문자형(character) 벡터로 시작해보자.

> gender <- c("M","F","F","M","F",NA)
> gender
[1] "M" "F" "F" "M" "F" NA 

이 벡터를 팩터로 바꾸려면 factor() 또는 as.factor() 함수를 사용한다.

> factor(gender)  //gender를 factor로 변환하여 출력함.
[1] M    F    F    M    F    <NA>
Levels: F M

> gender  //factor() 사용시 gender 값은 변하지 않음.
[1] "M" "F" "F" "M" "F" NA 


> gender <- as.factor(gender)  //factor 값을 gender에 적용함
> gender
[1] M    F    F    M    F    <NA>
Levels: F M

이런 팩터를 출력하게 되면 레벨 속성도 같이 출력된다. factor()함수는 주어진 벡터의 요소 값들을 같은 종류별로 묶은 다음 알파벳 순서로 레벨을 정하고, 그 레벨에 해당되는 값들을 다시 부여한다. 이런 팩터는 문자열이 아니기 때문에 출력된 모양을 보면 큰 따옴표가 없다는 것을 알 수 있다.

앞에서 ddf 라는 데이터 프레임을 만들 때 pt_name, categogo 백터가 팩터로 자동으로 바뀐 것은 data.frame () 이라는 함수의 stringAsFactors 라는 인자 때문이다. 이 것은 문자열 벡터를 자동으로 팩터로 변환하도록 기본 값이 설정되어 있다.

As.factor 함수 - as.factor hamsu
stringsAsFactors 기본값 설정.

이번에는 이 값을 FALSE로 줘보자. 보는 바와 같이 문자열이 그대로 유지되고 있음을 알 수 있다. 엑셀 등과 같이 사각형 모양의데이터가 들어 있는 파일을 R로  읽어올 때 read, csv(), read.table() 등과 같은 함수를 쓰게 된다. 이때 stringAsFactors 라는 옵션이 data.frame()함수의 기본 값과 같이 팩터로 전환되도록 되어 있는 경우가 많은데, 때에 따라서 필요한 방법을 선택하는 것이 좋다.

> id <- 1:10
> pt_name <- letters[1:10]
> categogo <- rep(c("Treat","Control"),5)
> scores <- sample(30:50,replace = TRUE,10)
> scores
 [1] 33 36 30 31 40 43 47 48 30 50
 
> df1 <- data.frame(id,pt_name,categogo,scores,stringsAsFactors = FALSE)

> str(df1) //pt_name과 categogo가 Factor 값으로 변환되지 않고 char 값을 유지한다.
'data.frame':   10 obs. of  4 variables:
 $ id      : int  1 2 3 4 5 6 7 8 9 10
 $ pt_name : chr  "a" "b" "c" "d" ...
 $ categogo: chr  "Treat" "Control" "Treat" "Control" ...
 $ scores  : int  33 36 30 31 40 43 47 48 30 50

■ 행렬과 배열

다음은 데이터 프레임과 같이 사각형 모양을 가진 행렬(matrix)에 대해서 알아보자. 행렬은 데이터 프레임과 같은 점도 있지만 다른 점이 많다. 행렬은 기본적으로 벡터를 가지고 만든다. 벡터에 디멘션(dim)속성이 부여된 것이기 때문에 데이터 프레임과 본질적으로 다르다. 벡터는 같은 데이터 타입을 가진 요소로 구성되고, 이것을 2차원적으로 배열한 행렬 역시 그 구성요소들은 모두 같은 데이터 타입을 가진다. 그러나 앞에서 본 데이터 프레임의 경우 그것을 구성하는 열들은 서로 다른 데이터 타입이 가능했다.

> j <- 1:35
> attr(j,"dim") <- c(5,7)
> j
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    6   11   16   21   26   31
[2,]    2    7   12   17   22   27   32
[3,]    3    8   13   18   23   28   33
[4,]    4    9   14   19   24   29   34
[5,]    5   10   15   20   25   30   35
> class(j)
[1] "matrix"

행렬은 벡터를 matrix()함수로 넘겨서 만들 수도 있다. nrow는 행의 수, ncol에는 열의 수를 부여한다.

> matrix(k,nrow=5,ncol=7)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    6   11   16   21   26   31
[2,]    2    7   12   17   22   27   32
[3,]    3    8   13   18   23   28   33
[4,]    4    9   14   19   24   29   34
[5,]    5   10   15   20   25   30   35

벡터를 2차원으로 배열하여 행렬을 만들 때 열 방향으로 값들을 재배열한다. 만약 행을 기준으로 값을 재배열하고자 한다면 byrow = TRUE 라는 옵션을 사용한다.

> l<- 1:35
> matrix(l,nrow=5,ncol=7,byrow=TRUE)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    2    3    4    5    6    7
[2,]    8    9   10   11   12   13   14
[3,]   15   16   17   18   19   20   21
[4,]   22   23   24   25   26   27   28
[5,]   29   30   31   32   33   34   35

행렬의 합은 +, 곱은 %*% 연산자를 사용한다. t()는 행렬을 전치(transpose)한다. 수학적으로 행렬의 곱이 성사되려면 앞의 행렬의 열의 개수와 두의 행렬의 개수가 같아야 한다.

> a <- matrix(1:6,nrow=2)
> b <- matrix(3:8,nrow=2)
> a
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
> b
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]    4    6    8
> a+b
     [,1] [,2] [,3]
[1,]    4    8   12
[2,]    6   10   14
> a%*%t(b)
     [,1] [,2]
[1,]   53   62
[2,]   68   80

R에는 행렬의 연산과 관련된 다양한 함수들이 준비되어 있다. 다음 rbind() 는 행으로 두 행렬을 합치고, cbind()는 열로 두 행렬을 합친다. 이런 행렬은 2차원적인 디멘션을 가지는 것으로, 배열(array)의 특수한 경우이다.

> rbind(a,b)
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
[3,]    3    5    7
[4,]    4    6    8
> cbind(a,b)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    3    5    7
[2,]    2    4    6    4    6    8

다음은 벡터 a를 2행,5열로 된 것을 5층으로 쌓아 올린 배열이다. 3차원 이상의 구조를 지닌 데이터는 쉽게 와닿지 않기 때문에 이런 배열은 자주 사용하지 않는다.

> a <- 1:50
> dim(a) <- c(2,5,5)
> a
, , 1

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10

, , 2

     [,1] [,2] [,3] [,4] [,5]
[1,]   11   13   15   17   19
[2,]   12   14   16   18   20

, , 3

     [,1] [,2] [,3] [,4] [,5]
[1,]   21   23   25   27   29
[2,]   22   24   26   28   30

, , 4

     [,1] [,2] [,3] [,4] [,5]
[1,]   31   33   35   37   39
[2,]   32   34   36   38   40

, , 5

     [,1] [,2] [,3] [,4] [,5]
[1,]   41   43   45   47   49
[2,]   42   44   46   48   50