본문 바로가기
R

R 데이터 구조와 색인(Indexing)/ scalar, vector, factor, matrix, array, data frame, list

by jangpiano 2021. 5. 16.
반응형

<R 데이터 구조> 

 

R의 데이터 구조는 7개의 형태로 구분이 됩니다. 7개의 구조를 사용하기에 적절한 상황이 모두 다르기 때문에, 각각의 구조에 대한 특징과 필요성을 정확하게 이해하는것이 중요하겠죠?  데이터를 준비하고 가공할때, 가지고 있는 데이터에 대해 정확한 소통을 하기 위해서는, 각각의 데이터에 대한 목적과 구조, 명칭을 정확하게 이해하고 사용하는것은 필수!!

Scalar 하나의 원소값만 포함하는 가장 기본적이고 간단한 데이터 구조
Vector 동일한 형태의 구성인자를 포함하는 1차원의 데이터 구조
Factor  범주형(categorical)의 데이터 구조
Matrix 동일한 형태의 구성인자를 포함하고 있는 2차원의 데이터 구조
Array 동일한 형태의 구성인자를 포함하는 2차원 이상의 데이터 구조.
Data Frame 데이터 유형에 상관없는 2차원 형태의 데이터 구조
List 서로 다른 구조의 데이터를 모두 묶은 데이터 구조 

지금부터 R의 7개로 나뉘는 데이터 구조들, 각각의 구조들에서 요소를 indexing(색인) 하는 방법까지 설명해보도록 할게요:) 

 

<스칼라 - Scalar>

스칼라는 하나의 원소값만 포함하는 가장 기본적이고 간단한 자료형입니다. 즉, 구성인자가 한개인 벡터라고도 말할 수 있죠. 

스칼라는 numeric, character, logical 이라는 세가지의 형태로 구분되고, 이는 class() 함수를 사용하여 확인할 수 있습니다. 

s1 = 2.3          #numeric 숫자형
s2 = "Piano"      #character 문자형
s3 = TRUE         #logical 논리형

class(s1)        #[1] "numeric"
class(s2)        #[1] "character"
class(s3).       #[1] "logical" 

<벡터 - Vector> 

벡터는 동일한 형태의 구성인자를 한개 이상 포함하고 있는 1차원의 데이터 구조입니다. 즉, 동일한 구조의 스칼라의 모임이라고 할 수 있겠죠? 

동일하지 않은 유형, 예를 들면 숫자형과 문자형을 함께 포함한 벡터는 존재할 수 없습니다.

 

만일, 숫자형과 문자형을 포함한 벡터를 만들고자 한다면, 벡터는 숫자형을 문자형으로 인지해 문자형 구성인자로 이루어진 벡터를 생성하게 됩니다. 

V <- c("P", "I", "A", "N", "O", 7, 5 )
V              # [1] "P" "I" "A" "N" "O" "7" "5"
class(V)       # "character"

스칼라가 세가지 형태로 구분되듯이, 동일한 스칼라의 1차원적 집합 형태라고 할 수 있는 벡터 역시 세가지 형태로 구분됩니다. 이또한, class() R 내장 함수를 사용해 확인 하실 수 있습니다. 

V1 <- c(1, 2, 3)              #numeric 숫자형 벡터 
V1 <- c("A", "B", "C")        #character 문자형 벡터 
V3 <- c(TRUE, TRUE, FALSE)    #factor 요인형 벡터 

<벡터 색인>

#색인 

X<- c("a", "b", "c", "d", "e")

> X[1]           #첫번째 요소 
[1] "a"

> X[-1]          #첫번째 요소 빼고 나머지 
[1] "b" "c" "d" "e"

> X[c(1, 3, 5)]  #첫번째, 세번째, 다섯번째 요소 
[1] "a" "c" "e"

> X[1:3]         #첫번째부처 세번째까지 요소
[1] "a" "b" "c"

> X[c(TRUE, TRUE, TRUE, FALSE, FALSE)]   #첫번째 두번째, 세번째 요소 
[1] "a" "b" "c"

 

<요인 - Factor> 

요인은 범주형(categorical)의 데이터 구조입니다.

범주형 자료에 쓰이는 만큼, 카테고리별로 나누어 분석을 시행하고자 할때 쓰인다. 

범주형 자료란, 몇개의 범주(category)로 나누어진 자료로서 명목형 자료(nominal)와 순서형(ordinal) 자료로 구분됩니다.

범주형(categorical) 데이터 
명목형 - nominal  순서형 - ordinal
각각의 범주에 순서가 지정되지 않고, 오로지 분류를 목적으로 함  순서가 지정됨 
ex) sex - Male, Female  ex) Income - low, middle, high 

우선, 우리가 가지고 있는 벡터를 요인형 데이터로 만들기 위해서는 factor() 함수를 사용해야 합니다.

요인형 데이터는, 각각의 범주를 정의하는 고유값을 수준(level)이라고 합니다.  요인형으로 데이터 형태를 바꾸는 동시에, 각각의 범주에 수준이 부여되는것을 볼 수 있죠. 

V1 <- c("High", "Low", "Middle", "Low", "High", "High", "Middle")
V2 <- c(1, 2, 3, 2, 3, 3, 3, 2, 1, 2)
F1 <- factor(V1)
F2 <- factor(V2)

>F1  
#[1] High   Low    Middle Low    High   High   Middle
#Levels: High Low Middle

>F2
#[1] 1 2 3 2 3 3 3 2 1 2
#Levels: 1 2 3

>levels(F1)
#[1] "High"   "Low"    "Middle"

>nlevels(F1)
#[1] 3

 

여기에, 요인형 데이터가 순서형인 경우 우리는 각각의 수준(level)이 언급되는 순서를 직접 levels() 지정할수가 있습니다.

levels()함수로 수준의 순서를 지정하기 이전에는 levels : "High", "Low", "Middle" 순으로 언급이 됩니다. 이는, 수준이 직접 설정되지 않았기 때문에 알파벳 순으로 순서가 자동지정된것입니다. 

levels 함수를 이용해,  Low, Middle, High 순으로 수준을 설정해봅시다. 

F2 <- factor(V1) 
>F2
#[1] High   Low    Middle Low    High   High   Middle
# Levels: High Low Middle

F3 <- factor(V1, levels = c("Low", "Middle", "High"))
>F3
#[1] High   Low    Middle   Low   High   High   Middle
#Levels: Low Middle High

요인형 데이터에 수준을 부여한 이후에는, order을 지정해주면 우리가 지정한 levels 를 순서로 인지하게 됩니다. 

F4 <- factor(V1, levels = c("Low", "Middle", "High"), ordered = TRUE)  
>F4
#[1] High   Low    Middle Low    High   High   Middle
#Levels: Low < Middle < High

>min(F4) 
#[1] Low
#Levels: Low < Middle < High

> max(F4)
#[1] High
#Levels: Low < Middle < High

<행렬 - Matrix>

벡터는 동일한 형태의 구성인자를 한개 이상 포함하고 있는 1차원의 데이터 구조입니다.

행렬은 동일한 형태의 구성인자를 한개 이상 포함하고 있는 2차원의 m*n표 형태의 데이터 구조입니다. 

nrow 또는 ncol 중 하나를 지정해줌으로써, 행렬이 몇개의 행과 몇개의 열로 이루어지는지 결정 할 수 있습니다. 

1부터 8까지의 정수를 행렬의 형태로 나열한다고 할때, 열의 개수를 2개로 설정하다면, 행의 개수는 저절로 4가 되겠죠?

M <- matrix(1:8, nrow = 2)
> M
#     [,1] [,2] [,3] [,4]
#[1,]    1    3    5    7
#[2,]    2    4    6    8

 

행렬에서 각각의 열과 행에 이름을 지정해주는 방법은 다양합니다. 그중에서도 가장 간단한 방법은, 밑에서 설명드린 방법 3이라고 할 수 있죠.  

행렬을 만드는 동시에 dimnames 라는 argument를 채워줌으로써, 열과 행 이름을 지정해주는 방법입니다. 

dimnames를 직접 지정해주기 전에는, 디폴트가(기본 설정값)이 None 이기 때문에 직접 설정을 해주어야 행과 열의 이름을 가질 수 있어요. 

# 행과 열 이름 지정 

#방법 1
colnames(M) <- c("A", "B", "C", "F")
rownames(M) <- c("Male", "Female")

#방법 2
dimnames(M) <- list(c("Male", "Female"), c("A", "B", "C", "F"))

#방법 3
M <- matrix(1:8, nrow =2, dimnames = list(c("Male", "Female") ,c("A", "B", "C", "F"))

>M
#        A B C F
# Male   1 3 5 7
# Female 2 4 6 8

<행렬 색인>

M <- matrix(1:8, nrow = 2, dimnames = list(c("Male", "Female") ,c("A", "B", "C", "D")))

#INDEXING 
> M[2, 4]         #2번째 행, 4번째 열  
#[1] 8

> M[2,]           #2번째 행 
#A B C D 
#2 4 6 8 

> M[,4]           #4번째 열 
#Male Female 
#   7      8 

> M[1, c(2, 3) ]  #1번째 행, 2번째 3번째 열 
#B C 
#3 5 

> M[1, c(1,4)]  #1번째 행, 1,4번째 열 
#A D 
#1 7

 

<배열 - Array> 

배열은, 동일한 형태의 구성인자를 한개 이상 포함하는 2차원 이상의 데이터 구조입니다. 즉, 행렬이 층층이 쌓여있는 구조를 생각하시면 됩니다. 

배열을 만들때는, 각 행렬의 열의 개수(m), 행의 개수(n) 그리고 배열을 구성하는 행렬의 개수를 지정해주어야 합니다.

A <- array(1:24, c(2, 4, 3))  #2*4 행렬로 3층을 이루는 데이터 구조 
>A
'''
, , 1

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

, , 2

     [,1] [,2] [,3] [,4]
[1,]    9   11   13   15
[2,]   10   12   14   16

, , 3

     [,1] [,2] [,3] [,4]
[1,]   17   19   21   23
[2,]   18   20   22   24
'''

<배열 색인>

A <- array(1:24, c(2, 4, 3))  #2*4 행렬로 3층을 이루는 데이터 구조 
>A
, , 1

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

, , 2

     [,1] [,2] [,3] [,4]
[1,]    9   11   13   15
[2,]   10   12   14   16

, , 3

     [,1] [,2] [,3] [,4]
[1,]   17   19   21   23
[2,]   18   20   22   24

#INDEXING 
> A[2, ,3]           #2번째 row, 3번째 matrix(3층)
#[1] 18 20 22 24

> A[2, 1, 3]         #2번째 row, 1번째 column, 3번째 matrix(3층)
#[1] 18

> A[,,2]             #2번째 matrix(2층)
'''
     [,1] [,2] [,3] [,4]
[1,]    9   11   13   15
[2,]   10   12   14   16
'''
#행과 열, 행렬의 이름 정해주기 

#방법 1 
A <- array(1:24, c(2, 4, 3)) 
dimnames(A) = list(c("row1", "row2"), c("col1", "col2", "col3", "col4"), c("matrix1", "matrix2", "matrix3"))

#방법 2 
A <- array(1:24, c(2, 4, 3), dimnames = list(c("row1", "row2"), c("col1", "col2", "col3", "col4"), c("matrix1", "matrix2", "matrix3")))

> A
'''
, , matrix1

     col1 col2 col3 col4
row1    1    3    5    7
row2    2    4    6    8

, , matrix2

     col1 col2 col3 col4
row1    9   11   13   15
row2   10   12   14   16

, , matrix3

     col1 col2 col3 col4
row1   17   19   21   23
row2   18   20   22   24
'''

 

 

<데이터 프레임 - Data Frame> 

데이터 프레임은 R에서 가장 많이 쓰이는 구조로, 데이터 유형에 상관없는 2차원 형태의 데이터 구조입니다. 

행렬과 다르게 데이터 유형에 상관없기 때문에, 데이터 프레임이라는 구조 안에는 문자형, 숫자형, 요소형이 모두 존재할 수 있는것이죠. 

name 은 문자형 벡터이고, grade 와 studying_hours는 숫자형 벡터임에도 불구하고 데이터 프레임 안에 함께 존재할 수 있는것을 볼수 있습니다. 

#방법1
name <- c("Jang", "Choi", "Oh", "Jhun")
grade<-c(1, 1, 2, 4)
studying_hours<-c(4, 3, 6, 5)

DF1<- data.frame(name, grade, studying_hours)

#방법2
DF1<- data.frame(name = c("Jang", "Choi", "Oh", "Jhun"), grade = c(1, 1, 2, 4), studying_hours = c(4, 3, 6, 5))

>DF1
'''
  name grade studying_hours
1 Jang     1              4
2 Choi     1              3
3   Oh     2              6
4 Jhun     4              5
'''

<데이터 프레임 색인>

> DF1
'''
  name grade studying_hours
1 Jang     1              4
2 Choi     1              3
3   Oh     2              6
4 Jhun     4              5
'''

> DF1[2, "name"]       #2번째 row, "name" column
#[1] "Choi"

> DF1[, "name"]        #"name" column 
#[1] "Jang" "Choi" "Oh"   "Jhun"

> DF1[, "grade"]       #'grade' column 
#[1] 1 1 2 4

> DF1[, 1]             #1번째 column 
#[1] "Jang" "Choi" "Oh"   "Jhun"

> DF1[c(1,2),]         #1,2번째 row 
'''
  name grade studying_hours
1 Jang     1              4
2 Choi     1              3
'''

<리스트 - List> 

리스트는 스칼라, 벡터, 요인, 행렬, 배열, 데이터 프레임 같은 서로 다른 구조의 데이터를 모두 하나로 묶어 존재할 수 있게하는 데이터 구조입니다. 

가장 복잡하면서도, 또 조건이 가장 적어 가장 간단한 구조라고도 할 수 있겟네요 ㅎㅎ

앞에서 만든 벡터, 요인, 행렬, 배열, 데이터 프레임을 모두 하나의 리스트 안에 합쳐봅시다. 

S1 <- "Jang"
V1 <- c(1, 2, 3) 
F1 <- factor(c("High", "Middle", "Low"), levels = c("Low", "Middle", "High"), ordered = TRUE)
M1 <- matrix(1:8, nrow = 2)
A1 <- array(1:24, c(2, 4, 3)) 
DF1<- data.frame(name = c("Jang", "Choi", "Oh", "Jhun"), grade = c(1, 1, 2, 4), studying_hours = c(4, 3, 6, 5))

L1 <- list(S1, V1, F1, M1, A1, DF1)
>L1
'''
[[1]]
[1] "Jang"

[[2]]
[1] 1 2 3

[[3]]
[1] High Middle Low
Levels: Low < Middle < High

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

[[5]]
, , 1

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

, , 2

     [,1] [,2] [,3] [,4]
[1,]    9   11   13   15
[2,]   10   12   14   16

, , 3

     [,1] [,2] [,3] [,4]
[1,]   17   19   21   23
[2,]   18   20   22   24


[[6]]
  name grade studying_hours
1 Jang     1              4
2 Choi     1              3
3   Oh     2              6
4 Jhun     4              5
'''

<리스트 색인>

> L1[[5]]                #L1의 5번째 층
'''
, , 1

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

, , 2

     [,1] [,2] [,3] [,4]
[1,]    9   11   13   15
[2,]   10   12   14   16

, , 3

     [,1] [,2] [,3] [,4]
[1,]   17   19   21   23
[2,]   18   20   22   24
'''

> L1[[5]][1,,3]                 #리스트의 5번째 층, 3번째 층의 1번째 행 
#[1] 17 19 21 23
 
> L1[[6]]                       #리스트의 6번째 층 
'''
  name grade studying_hours
1 Jang     1              4
2 Choi     1              3
3   Oh     2              6
4 Jhun     4              5
'''

> L1[[6]][2, "name"]             #리스트의 6번째 층, 2번째 행, "name" 열
#[1] "Choi"

 

반응형