Data Type and Structure

R Programming Basis

Description R Data Type and Structure

Yeongeun Jeon
06-20-2022

1. 데이터 유형


1-1. 숫자형(Numeric)

# 정수(Integer)
x <- c(1, 2, 3, 4)
x
[1] 1 2 3 4
# 데이터 유형 확인NAclass(x)
[1] "numeric"

Caution! 함수 class()로 데이터의 유형을 확인할 수 있으며, 그 외에도 함수 typeof(), 함수 mode()를 사용할 수 있다.


# 실수(Double)
x <- c(0.1, 0.5, 0.8, 1.0)
x
[1] 0.1 0.5 0.8 1.0
# 데이터 유형 확인NAclass(x)
[1] "numeric"

Result! 실수형은 함수 class()를 사용하면 numeric으로 출력한다.


# 복소수(Complex))
x <- c(1+1i, 2+2i, 3+4i, 5+2i)
x
[1] 1+1i 2+2i 3+4i 5+2i
# 데이터 유형 확인NAclass(x)
[1] "complex"

1-2. 문자형(Character)

x <- c("가"","나"나""다")")
x
[1] "가" "나" "다"
# 데이터 유형 확인NAclass(x)
[1] "character"

x <- c("1", "20", "30")
x
[1] "1"  "20" "30"
# 데이터 유형 확인NAclass(x)
[1] "character"

Result! 숫자도 ‘10’ 또는 “10”처럼 따옴표로 묶여 있으면 문자형이 된다.


1-3. 논리형(Logical)


x <- c(TRUE, FALSE)
x
[1]  TRUE FALSE
# 데이터 유형 확인NAclass(x)
[1] "logical"

x <- c(T, F)
x
[1]  TRUE FALSE
# 데이터 유형 확인NAclass(x)
[1] "logical"

x <- 3 > 2
x
[1] TRUE
# 데이터 유형 확인NAclass(x)
[1] "logical"

# 산술 연산x <- TRUE
y <- FALSE
z <- TRUE

sum(c(x, y, z))
[1] 2

Caution! R에서 TRUE는 숫자 1을 나타내고 FALSE는 숫자 0으로 인식한다.
Result! \(x+y+z=1+0+1=2\)를 출력한다.


1-4. 범주형(Categorical)

# 명목척도x <- factor(c("F", "M", "F"))
x
[1] F M F
Levels: F M
# 데이터 유형 확인NAclass(x)
[1] "factor"

# 범주 순서 바꾸기
x <- factor(c("F", "M", "F"), levels = c("M", "F"))
x
[1] F M F
Levels: M F
# 데이터 유형 확인NAclass(x)
[1] "factor"

# 순서척도 Ver.1.1
x <- factor(c("1", "2", "3"), ordered = TRUE)
x
[1] 1 2 3
Levels: 1 < 2 < 3
# 데이터 유형 확인NAclass(x)
[1] "ordered" "factor" 

# 순서척도 Ver.2.2
x <- ordered(c("1", "2", "3"), levels = c("1", "2", "3"))
x
[1] 1 2 3
Levels: 1 < 2 < 3
class(x)
[1] "ordered" "factor" 

Caution! 순서척도는 함수 ordered()를 사용하여 생성할 수도 있다.


1-5. 특수한 상태를 나타내는 형태

NULL 존재하지 않는 객체를 지정할 때 사용
NA Not Available의 약자로 결측치(Missing Value)를 의미
NaN Not a Number의 약자로 수학적으로 연산이 불가능한 경우를 의미
Inf Infinite의 약자로 양의 무한대를 의미
-Inf 음의 무한대를 의미
# NULL
x <- c(90, 80, 75, 60, NULL)
x
[1] 90 80 75 60
length(x)
[1] 4

Result! R에서 NULL은 값이 없다고 생각하기 때문에 출력되지 않으며 x의 길이는 4가 된다.


# NA
x<- c(90, 80, 75, 60, NA)
x
[1] 90 80 75 60 NA
length(x)
[1] 5

Result! R에서 NANULL과 다르게 값이 출력되며 x의 길이는 5가 된다.


# NaN
0/0
[1] NaN

# Inf
1/0
[1] Inf

# -Inf
-1/0
[1] -Inf

1-6. 데이터 유형 확인


x <- c(1, 3, 5)
is.double(x)
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] FALSE

x <- c("1", "3", "5")
is.numeric(x)
[1] FALSE
[1] TRUE

x <- c(TRUE, FALSE)
is.numeric(x)
[1] FALSE
[1] TRUE

x <- factor(c("사과", "포도", "수박"))
is.character(x)
[1] FALSE
[1] TRUE

1-7. 데이터 유형 변환


x <- c(1, 0, 3, 5)
is.integer(x)
[1] FALSE
# 정수형 변환
y <- as.integer(x)
y
[1] 1 0 3 5
[1] TRUE
# 문자형 변환
z <- as.character(x)
z
[1] "1" "0" "3" "5"
[1] TRUE
# 범주형 변환xx <- as.factor(x)
xx
[1] 1 0 3 5
Levels: 0 1 3 5
is.factor(xx)
[1] TRUE
# 논리형 변환yy <- as.logical(x)
yy
[1]  TRUE FALSE  TRUE  TRUE

Result! 0 이외의 숫자는 TRUE, 0은 FALSE로 변환한다.

[1] TRUE

2. 데이터 구조

출처 : https://ryuhyun.tistory.com/14



2-1. 벡터(Vector)

2-1-1. 벡터 생성

x <- 3
x
[1] 3

Caution! 원소가 하나인 벡터를 스칼라(Scalar)라고 하며, 스칼라를 만들 때에는 함수 c()를 사용하지 않아도 된다.


x <- c(1, 2, 6, 10, 11, 103)
x
[1]   1   2   6  10  11 103

x <- c(TRUE, FALSE, TRUE, TRUE)
x
[1]  TRUE FALSE  TRUE  TRUE

x <- c("가"","나"나""다"다""라")")
x
[1] "가" "나" "다" "라"

Caution! 다른 유형의 데이터가 벡터에 뒤섞여 있다면 더 복잡한 형태의 유형으로 강제 변환되며, 복잡한 유형은 문자형(Character) \(>\) 복소수형(Complex) \(>\) 숫자형(Numeric) \(>\) 논리형(Logical)이다.

# 다른 유형으로 구성된 벡터벡터
x <- c(1, 3, "가"))
x
[1] "1"  "3"  "가"
# 데이터 유형 확인NAclass(x)
[1] "character"

Result! 숫자형과 문자형으로 구성된 벡터는 문자형 데이터로 통일된다.


# 다른 유형으로 구성된 벡터벡터
x <- c(TRUE, "가"","다"))
x
[1] "TRUE" "가"   "다"  
# 데이터 유형 확인NAclass(x)
[1] "character"

Result! 논리형과 문자형으로 구성된 벡터는 문자형 데이터로 통일된다.


# 다른 유형으로 구성된 벡터벡터
x <- c(1, 3, TRUE)
x
[1] 1 3 1
# 데이터 유형 확인NAclass(x)
[1] "numeric"

Result! 논리형과 숫자형으로 구성된 벡터는 숫자형 데이터로 통일된다.


2-1-2. 벡터에 데이터 추가 및 벡터들의 결합

# 데이터 추가x <- c(1, 3, 5)
y <- c(x, 10)
y
[1]  1  3  5 10

# 벡터들의 결합NAx <- c(11, 12, 14)
y <- c(2, 3, 1)
z <- c(x, y)
z
[1] 11 12 14  2  3  1

2-1-3. 일정한 구조를 갖는 벡터의 생성

# 콜론 연산자1:5
[1] 1 2 3 4 5
-3:3
[1] -3 -2 -1  0  1  2  3
1.5:5.4
[1] 1.5 2.5 3.5 4.5
5:-3
[1]  5  4  3  2  1  0 -1 -2 -3

# seq
seq(from = 1, to = 10, by = 3)
[1]  1  4  7 10
seq(from = 6, to = 0, by = -2)
[1] 6 4 2 0
seq(from = 1, to = 6, by = 1.8)
[1] 1.0 2.8 4.6

# rep
rep(1, times = 2)
[1] 1 1
rep(1:5, times = 5)
 [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
rep(c("M", "F"), times = 3)
[1] "M" "F" "M" "F" "M" "F"
rep(c("M", "F"), times = c(5, 8))
 [1] "M" "M" "M" "M" "M" "F" "F" "F" "F" "F" "F" "F" "F"
rep(1:5, each = 5)
 [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5
rep(1:5, each = c(4, 10, 2, 3, 6))
 [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5
rep(c("M", "F"), each = 3)
[1] "M" "M" "M" "F" "F" "F"

2-1-4. 벡터의 연산

# 벡터와 스칼라의 연산x <- c(1, 10, 3, 4, 6)

x+3
[1]  4 13  6  7  9
x-3
[1] -2  7  0  1  3
x*3
[1]  3 30  9 12 18
x/3
[1] 0.3333333 3.3333333 1.0000000 1.3333333 2.0000000
x^3
[1]    1 1000   27   64  216

# 벡터와 벡터의 연산
x <- c(1, 10, 3, 4, 6)
y <- c(9, 3, 2, 11, 4)

x+y
[1] 10 13  5 15 10
x-y
[1] -8  7  1 -7  2
x*y
[1]  9 30  6 44 24
x/y
[1] 0.1111111 3.3333333 1.5000000 0.3636364 1.5000000
x^y
[1]       1    1000       9 4194304    1296

2-1-5. 벡터의 인덱싱

x <- c(5, 9, 10, 3, 1, 8)
x[c(1, 4, 3)]
[1]  5  3 10

Result! 벡터 x의 1, 4, 3번째 자리의 원소만 출력한다.


x[-c(1, 4, 3)]
[1] 9 1 8

Result! 벡터 x의 1, 4, 3번째 자리의 원소를 제외한 원소들을 출력한다.


x[10]
[1] NA

Result! 지정한 위치가 벡터의 길이보다 크기 때문에 결측값인 NA를 출력한다.


x[x>3]
[1]  5  9 10  8

Result! 논리형 벡터에 의한 인덱싱의 경우에는 TRUE인 자료가 선택된다.


2-2. 행렬(Matrix)과 배열(Array)


2-2-1. 행렬 생성

x <- matrix(c(1, 3, 10, 5, 3, 9, 6, 7), nrow = 4)
x
     [,1] [,2]
[1,]    1    3
[2,]    3    9
[3,]   10    6
[4,]    5    7

x <- matrix(c(1, 3, 10, 5, 3, 9, 6, 7), nrow = 4, byrow = TRUE)
x
     [,1] [,2]
[1,]    1    3
[2,]   10    5
[3,]    3    9
[4,]    6    7

Caution! 행렬 생성에 유용하게 사용되는 또 다른 함수로 함수 cbind()rbind()가 있다. 함수 cbind()는 기존의 벡터들을 열 단위로 묶어서 행렬을 만들 때 사용할 수 있고, 함수 rbind()는 벡터들을 행 단위로 묶어서 행렬을 구성할 때 사용할 수 있다. 또한, 두 함수는 기존의 행렬에 열 또는 행을 추가하는 경우에도 사용할 수 있다.

# 행렬 생성
x <- c(1, 4, 6)
y <- c(10, 8, 7)

cbind(x, y)
     x  y
[1,] 1 10
[2,] 4  8
[3,] 6  7
rbind(x, y)
  [,1] [,2] [,3]
x    1    4    6
y   10    8    7

# 기존의 행렬에 열 또는 행 추가x <- c(1, 4, 6)
y <- c(10, 8, 7)

z <- cbind(x, y)

cbind(z, u = 1:3)
     x  y u
[1,] 1 10 1
[2,] 4  8 2
[3,] 6  7 3
rbind(z, 5:6)
     x  y
[1,] 1 10
[2,] 4  8
[3,] 6  7
[4,] 5  6

Caution! 함수 cbind()rbind()를 사용할 때 결합 대상이 되는 벡터들의 길이가 서로 다르면 순환법칙이 적용된다.

x <- c(1, 4, 6, 5, 2)
y <- c(10, 8)
z <- 10

cbind(x, y, z)
     x  y  z
[1,] 1 10 10
[2,] 4  8 10
[3,] 6 10 10
[4,] 5  8 10
[5,] 2 10 10

Result! y와 z의 원소들이 x의 원소 길이에 맞추어 반복되었다.


Caution! 함수 rownames()colnames()로 행렬의 행과 열에 이름을 붙일 수 있다.

x <- c(1, 4, 6)
y <- c(10, 8, 7)

z <- cbind(x, y)
rownames(z) <- c("a", "b", "c")
colnames(z) <- c("one", "two")
z
  one two
a   1  10
b   4   8
c   6   7

Caution! 함수 nrow(), ncol(), dim()으로 행렬의 행, 열, 차원을 확인할 수 있다.

x <- c(1, 4, 6)
y <- c(10, 8, 7)

z <- cbind(x, y)

nrow(z)
[1] 3
ncol(z)
[1] 2
dim(z)
[1] 3 2

2-2-2. 행렬의 연산


x <- matrix(1:4, nrow = 2, byrow = TRUE)
y <- matrix(c(5, 10, 8, 3), nrow = 2, byrow = TRUE)

x
     [,1] [,2]
[1,]    1    2
[2,]    3    4
y
     [,1] [,2]
[1,]    5   10
[2,]    8    3
x+y
     [,1] [,2]
[1,]    6   12
[2,]   11    7
x-y
     [,1] [,2]
[1,]   -4   -8
[2,]   -5    1
x/y
      [,1]     [,2]
[1,] 0.200 0.200000
[2,] 0.375 1.333333
x*y
     [,1] [,2]
[1,]    5   20
[2,]   24   12
# 행렬곱x%*%y
     [,1] [,2]
[1,]   21   16
[2,]   47   42
# 각 열의 평균
colMeans(x)
[1] 2 3
# 각 열의 합
colSums(x)
[1] 4 6
# 각 행의 평균NArowMeans(x)
[1] 1.5 3.5
# 각 행의 합NArowSums(x)
[1] 3 7
# 행렬의 대각원소diag(x)
[1] 1 4
# 대각행렬
diag(1:4)
     [,1] [,2] [,3] [,4]
[1,]    1    0    0    0
[2,]    0    2    0    0
[3,]    0    0    3    0
[4,]    0    0    0    4
# 항등행렬NAdiag(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    1    0
[5,]    0    0    0    0    1
# 고유값과 고유벡터eigen(x)
eigen() decomposition
$values
[1]  5.3722813 -0.3722813

$vectors
           [,1]       [,2]
[1,] -0.4159736 -0.8245648
[2,] -0.9093767  0.5657675
# 역행렬
solve(x)
     [,1] [,2]
[1,] -2.0  1.0
[2,]  1.5 -0.5
# 전치행렬NAt(x)
     [,1] [,2]
[1,]    1    3
[2,]    2    4

2-2-3. 배열 생성

x <- array(1:4, c(2, 3, 3))
x
, , 1

     [,1] [,2] [,3]
[1,]    1    3    1
[2,]    2    4    2

, , 2

     [,1] [,2] [,3]
[1,]    3    1    3
[2,]    4    2    4

, , 3

     [,1] [,2] [,3]
[1,]    1    3    1
[2,]    2    4    2

Result! 벡터 1, 2, 3, 4를 이용하여 행의 개수가 2이고, 열의 개수가 3인 행렬이 3개 생성되었다.


x <- array(1:24, c(4, 3, 2))
x
, , 1

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

, , 2

     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24

Result! 벡터 1~24를 이용하여 행의 개수가 4이고, 열의 개수가 3인 행렬이 2개 생성되었다.


Caution! 각 차원에 대한 이름은 함수 dimnames()로 붙일 수 있으며, 문자형 벡터들도 이루어진 리스트를 할당해야 한다.

dimnames(x) <- list(X = c("x1", "x2", "x3", "x4"), Y = c("y1", "y2", "y3"), Z = c("z1", "z2"))
x
, , Z = z1

    Y
X    y1 y2 y3
  x1  1  5  9
  x2  2  6 10
  x3  3  7 11
  x4  4  8 12

, , Z = z2

    Y
X    y1 y2 y3
  x1 13 17 21
  x2 14 18 22
  x3 15 19 23
  x4 16 20 24

2-2-4. 행렬과 배열의 인덱싱

# 행렬x <- matrix(1:10, nrow = 5, byrow = TRUE)
x
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10
x[3, 2] 
[1] 6

Result! 행렬 x의 3번째 행 2번째 열 원소가 선택되었다.


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

Result! 행렬 x의 2번째와 3번째 행의 원소들이 선택되었다.


x[ ,1]
[1] 1 3 5 7 9

Result! 행렬 x의 1번째 열의 원소들이 선택되었다.


# 배열y <- array(1:24, c(4, 3, 2))
y
, , 1

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

, , 2

     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24
y[1, 3, 1]
[1] 9

Result! 배열 y의 1번째 행렬의 1번째 행 3번째 열의 원소가 선택되었다.


y[1, , 1]
[1] 1 5 9

Result! 배열 y의 1번째 행렬의 1번째 행의 원소들이 선택되었다.


y[, , 2]
     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24

Result! 배열 y의 2번째 행렬의 원소들이 선택되었다.


2-3. 데이터 프레임(Data Frame)


2-3-1. 데이터 프레임 생성

df <- data.frame(x = c(1, 3, 10), y = c("가"","나"나""다"))))
df
   x  y
1  1 가
2  3 나
3 10 다

df <- data.frame(x = c(1, 3), y = c("가"","나"나""다"다""라")"), = 6)6)
df
  x  y z
1 1 가 6
2 3 나 6
3 1 다 6
4 3 라 6

Caution! 데이터 프레임은 행렬과 같이 2차원 구조여서 함수 rownames()colnames()의 역할이 행렬과 동일하다. 하지만, 데이터 프레임에서는 함수 names()가 함수 colnames()와 같은 역할을 하고 있다.

# 행 이름rownames(df)
[1] "1" "2" "3" "4"
# 행 이름 수정rownames(df) <- c("a", "b", "c", "d")
df
  x  y z
a 1 가 6
b 3 나 6
c 1 다 6
d 3 라 6

# 열 이름names(df)
[1] "x" "y" "z"
# 열 이름 수정names(df) <- c("one", "two", "three")
df
  one two three
a   1  가     6
b   3  나     6
c   1  다     6
d   3  라     6

Caution! 데이터 프레임은 함수 nrow(), ncol(), dim()으로 행렬의 행, 열, 차원을 확인할 수 있다.

nrow(df)
[1] 4
ncol(df)
[1] 3
dim(df)
[1] 4 3

Caution! 함수 str()를 이용하여 데이터 프레임의 특성을 살펴볼 수 있다.

str(df)
'data.frame':   4 obs. of  3 variables:
 $ one  : num  1 3 1 3
 $ two  : Factor w/ 4 levels "가","나","다",..: 1 2 3 4
 $ three: num  6 6 6 6

2-3-2. 데이터 프레임의 인덱싱

df <- data.frame(x = c(1, 3), y = c("가"","나"나""다"다""라")"), = 6)6)
df
  x  y z
1 1 가 6
2 3 나 6
3 1 다 6
4 3 라 6
df[2, 3]
[1] 6

Result! 데이터 프레임 df의 2번째 행 3번째 열 원소가 선택되었다.


df[, c(1,3)]
  x z
1 1 6
2 3 6
3 1 6
4 3 6

Result! 데이터 프레임 df의 1번째, 3번째 열 원소들이 선택되었다.


df$y
[1] 가 나 다 라
Levels: 가 나 다 라

Caution! 데이터 프레임은 $ 기호를 이용하여 원하는 이름의 열을 한꺼번에 선택할 수 있다.
Result! 데이터 프레임 df의 변수 “y” 원소들이 선택되었다.


df[x<2,]
  x  y z
1 1 가 6

Result! 데이터 프레임 df의 변수 “x” 값이 2보다 작은 행만 선택되었다.


2-4. 리스트(List)


2-4-1. 리스트 생성

x <- list(a = c(1, 3, 10), b = c("가"","나"나""다"다""라")"), = data.frame(e(x= 1:9:9, x= 2:10)0), = list(1(13))))
x
$a
[1]  1  3 10

$b
[1] "가" "나" "다" "라"

$d
  x1 x2
1  1  2
2  2  3
3  3  4
4  4  5
5  5  6
6  6  7
7  7  8
8  8  9
9  9 10

$e
$e[[1]]
[1] 1

$e[[2]]
[1] 3

2-4-2. 리스트 인덱싱

x[3]
$d
  x1 x2
1  1  2
2  2  3
3  3  4
4  4  5
5  5  6
6  6  7
7  7  8
8  8  9
9  9 10

class(x[3])
[1] "list"

Result! 리스트 x의 3번째 구성요소인 데이터 프레임으로 이루어진 리스트가 된다.


x[[3]]
  x1 x2
1  1  2
2  2  3
3  3  4
4  4  5
5  5  6
6  6  7
7  7  8
8  8  9
9  9 10
class(x[[3]])
[1] "data.frame"

Result! 리스트 x의 3번째 구성요소인 데이터 프레임이 된다.


Caution! 리스트도 데이터 프레임과 같이 $ 기호를 사용하여 인덱싱 할 수 있다.

x$b
[1] "가" "나" "다" "라"
x[["b"]]
[1] "가" "나" "다" "라"
class(x[["b"]])
[1] "character"
class(x$b)
[1] "character"

Result! 리스트 x$b는 x[[“b”]]와 동일한 결과를 출력한다.

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".