1. Hello, R > 1-2. R 데이터 타입 학습

R 데이터 타입 학습


🧭 목차

  1. 변수
  2. 데이터형
  3. 연산자
  4. 벡터
  5. 배열(행렬)
  6. 데이터 프레임

R에서 사용되는 다양한 데이터형(data type)과 연산 방법에 대해 학습해 보겠습니다. 해당 장의 내용들은 하나하나 세세하게 외우기보다는, "아, 이런 데이터형이 있구나" 정도로 훑어보고 필요할 때마다 다시 찾아보는 것을 추천합니다.

본 커리큘럼은 각각의 데이터형에 대해 간단히 짚고 넘어갑니다. 추가적인 내용(예: 리스트 등)은 다른 자료를 참고하시길 바랍니다.


1) 변수

  • 변수(variable): 데이터를 저장하는 공간

(1) 변수 사용법

  • 대입 연산자(할당 연산자) 이용

    • 예: =, <-, ->
    • <-=보다 우선적으로 실행된다.
    # =: 우변 계산 후 좌변에 대입
    x = 5252
    y = 8282
    
    z = x + y   # z에 13534을 할당
    x + y = z   # Error 발생
    
    # <- / ->
    z <- x + y
    x + y -> z
    

(2) 변수 이름 규칙

  • 영어, 숫자, 밑줄(_), 마침표(.) 사용 가능
    • 숫자, 밑줄은 첫 글자로 사용 불가능하다.
  • 빈칸 사용 불가능
  • 정해진 명령어(예약어)인 if, while, for 등은 사용 불가

2) 데이터형

C와 같은 프로그래밍 언어는 변수 선언 시 데이터형(data type)을 함께 지정해야 됩니다. 그러나 R은 변수에 저장되는 값에 따라 데이터형이 자동으로 결정됩니다.

R에서 사용하는 기본 데이터형은 다음과 같습니다.

(1) 기본 데이터형

데이터형종류
숫자형int(정수), num(실수), cplx(복소수)
문자형chr: 따옴표로 묶어 표기
범주형factor: 레벨에 따라 분류된 형태
(내부적으로 범주는 숫자로 관리됨)
논리형TRUE(T), FALSE(F)
: 반드시 대문자를 입력할 것
특수 상수- NULL: 정의되지 않은 값
- NA: 결측값
- (-)Inf: (음)양의 무한대
- NaN(Not a Number): 0÷0 혹은 Inf÷Inf 등과 같이 연산이 불가능한 값 표기

선언된 변수의 데이터형을 확인하는 함수는 다음과 같습니다.

(2) 데이터형 확인 함수

함수설명
class(x)R 객체지향 관점에서 x의 데이터형
(추상적인 데이터형)
typeof(x)R 언어 자체 관점에서 x 의 데이터형
(메모리에서 다루는 형식)
is.integer(x)x가 정수형이면 TRUE, 아니면 FALSE
is.numeric(x)x가 실수형이면 TRUE, 아니면 FALSE
is.complex(x)x가 복소수형이면 TRUE, 아니면 FALSE
is.character(x)x가 문자형이면 TRUE, 아니면 FALSE
is.na(x)x가 NA이면 TRUE, 아니면 FALSE
: 결측치 확인용으로 자주 쓰인다!

💡 class(x)typeof(x)의 차이점

blood.type1 = c('A', 'B', 'O', 'AB') # c() 함수: 여러 개를 묶어 변수에 저장할 때 사용 
blood.type2 = factor(blood.type1)

# 1. class(x): R 객체지향 관점에서 x의 데이터형 (추상적인 데이터형)
class(blood.type1)
> "character"
class(blood.type2)
> "factor"

# 2. typeof(x): R 언어 자체 관점에서 x의 데이터형 (메모리에서 다루는 형식)
typeof(blood.type1)
> "character"
typeof(blood.type2)
> "integer"

데이터형을 변환해주는 함수는 다음과 같습니다.

(3) 데이터형 변환 함수

함수설명
as.facotr(x)범주형 변환
as.integer(x)정수형 변환
as.numeric(x)숫자형 변환
as.character(x)문자형 변환
as.matrix(x)행렬 변환
as.array(x)배열 변환

한 가지 주의할 점은, 해당 함수들이 데이터형을 바꾸어 출력만 해준다는 것입니다. 겉모습만 바꿔주는 것이죠. 변수의 데이터형을 변환하고 싶다면 아래처럼 명령어를 입력해야 됩니다.

as.character(blood.type1)                 # 범주형을 정수형으로 변환하여 출력
class(blood.type1)
> "factor"

blood.type1 = as.character(blood.type1)   # 변환된 데이터형으로 저장
class(blood.type1)
> "character"

3) 연산자

선언한 변수에 산술, 비교, 논리 등의 다양한 연산자를 사용하면 원하는 데이터를 얻을 수 있습니다. 각각의 연산자를 살펴보겠습니다.

(1) 산술연산자

연산자설명
+덧셈
1 + 1 → 2
-뺄셈
*곱셈
9 * 9 → 81
/나눗셈
^ or **지수승
3^3 → 27
x %% yx를 y로 나눈 나머지
2 %% 81 → 2
x %/% yx를 y로 나눈 몫
2 %/% 81 → 0

(2) 비교연산자

연산자설명
<미만
<=이하
>초과
>=이상

(3) 논리연산자

연산자설명
==좌변과 우변이 같다
!=좌변과 우변이 다르다
!x부정(not)
!TRUE → FALSE
x | y or x || yx or y(또는, 합집합)
TRUE | FALSE → TRUE
x & y or x && yx and y(그리고, 교집합)
TRUE & FALSE → FALSE
isTRUE(x)x의 TRUE 여부 판단isTRUE(TRUE) → TRUE
isTRUE(FALSE) → FALSE

4) 벡터

지금부터는 하나의 변수가 아닌 여러 개의 변수를 다루는 방법에 대해 살펴보겠습니다.

  • 벡터(vecotr): 단일값(scalar)들의 모임
    • 여러 단일값을 하나의 변수명으로 저장할 수 있다.
    • 단, 단일값들이 모두 동일한 데이터형이어야 된다.

(1) 벡터 생성

  • 생성 연산자 사용: 시작값:종료값

    # 증가하는 벡터
    1:10
    > 1 2 3 4 5 6 7 8 9 10
    
    # 감소하는 벡터
    10:1
    > 10 9 8 7 6 5 4 3 2 1
    
  • c() 함수: 일반 벡터 생성

    c(5:8)
    > 5 6 7 8
    
    c(1, 2, c(5:8))
    > 1 2 5 6 7 8
    
    v = c(2, 4, 6)   # 변수 v에 저장
    > 2 4 6
    
  • seq() 함수: 순열 벡터 생성

    • from: 초깃값
    • to: 종료값
    • by: 증가값
    seq(from=3, to=10, by=3)     # 숫자만 써도 ok
    seq(3, 10 ,3)
    > 3 6 9
    
    seq(0.1, 1, length.out=10)   # length.out: 요소 개수
    > 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
    
  • rep() 함수: 반복 벡터 생성

    • times: 벡터 반복 횟수
    • each: 요소 반복 횟수
    rep(c(2:4), times=2)   # 벡터 전체를 반복
    > 2 3 4 2 3 4
    
    rep(c(2:4), each=3)    # 개별 요소를 반복
    > 2 2 2 3 3 3 4 4 4
    

(2) 벡터 연산

벡터의 개별 요소 값에 접근하거나 출력하는 방법에 대해 살펴보겠습니다. 주의할 점은 다른 프로그래밍 언어와 달리, R의 요소 값 접근은 1부터 시작된다는 것입니다. 잊지 마세요 😉

x = c(1, 2, 3, 4, 5)
length(x)
> 5
  • 단일값 접근

    x[1]
    > 1   # 다른 프로그래밍 언어와 다르다!
    
  • 복수 개의 값 접근

    x[1, 2, 3]
    > Error in x[1, 2, 3] : incorrect number of dimensions
    
    x[c(1, 2, 3)]
    > 1 2 3
    x[c(1:3)]
    > 1 2 3
    
    x[-c(1, 2, 3)]   # -: 해당되는 값을 제외한 결과 출력
    > 4 5
    

추가로 벡터의 연산은 다음 경우에만 가능합니다.

  • 벡터의 길이가 동일
  • 벡터 요소 개수가 배수 관계

아래 벡터들의 연산을 통해 직접 확인해 보시길 바랍니다.

a = c(2, 4, 6, 8)
b = c(1, 3, 5, 7)
p = c(5, 10)
q = c(3, 6, 9)

(3) 벡터 연산에 유용한 함수

  • 요소들의 조건 검토

    • all: 벡터 내 모든 요소가 조건을 만족하는가
    • any: 벡터 내 일부 요소가 조건을 만족하는가
    x = 2:8
    
    all(x>5)   # 벡터 내 모든 요소 값이 5보다 큰가?
    > FALSE
    
    any(x>5)   # 벡터 내 일부 요소 값이 5보다 큰가?
    > TRUE
    
  • 데이터의 일부 요소 추출

    데이터 개수를 입력하지 않는 경우, 기본적으로 6개가 추출된다.

    • head(벡터, 데이터 개수): 데이터의 앞부분 일부
    • tail(벡터, 데이터 개수): 데이터의 뒷부분 일부
    x = 2:8
    
    head(x)
    > 2 3 4 5 6 7
    
    tail(x)
    > 3 4 5 6 7 8 
    
  • 벡터 간 집합 연산

    • union: 합집합
    • intersect: 교집합
    • setdiff: 차집합
    • setequal: 두 벡터의 요소가 동일한지 비교한 뒤, T or F로 표시
    x = c(1, 2, 3)
    y = c(2, 4 ,6)
    z = c(6, 4, 2)
    
    # 합집합
    union(x, y)
    > 1 2 3 4 6
    
    # 교집합
    intersect(x, y)
    > 2
    
    # 차집합
    setdiff(x, y)
    > 1 3
    setdiff(y ,x)
    > 4 6
    
    # 요소 비교
    setequal(x, y)
    > FALSE
    setequal(x, z)
    > TRUE
    

5) 배열(행렬)

벡터를 좀 더 확장해 보겠습니다. 1차원의 벡터를 '행(row)'과 '열(column)'로 구성된 2차원으로 확장시킨 것이 행렬(matrix)이고, n차원으로 확장한 것을 배열(array)이라고 합니다.

행렬과 배열은 엄연히 다르나, 표현의 어색함(행렬식 → 배열식 등)을 피하기 위해 본 교안에서는 둘을 혼용하여 사용하겠습니다.

  • 벡터 ▶ 행렬(2차원 배열) ▶ 배열(N차원 배열)

(1) 배열 생성

배열은 기본적으로 열 방향으로 채워집니다.

  • 2차원 배열(행렬) 생성: matrix

    x = 1:10
    
    # 행/열 수 지정
    matrix(x, nrow = 5)   # 행 수 지정: 5x2 행렬
    matirx(x, ncol = 5)   # 열 수 지정: 2x5 행렬
    
    # 행 단위 데이터 배치여부 결정 → T/F로 표시
    matrix(x, nrow = 5, byrow = T)   # default: F
    
    # 행/열 이름 목록 추가(list 사용)
    matrix(1:12, nrow = 3, byrow = T,
           dimnames = list(c('행1', '행2', '행3'), c('열1', '열2', '열3', '열4')))
    
  • n차원 배열 생성: array

    x = array(1:5, c(2, 4))
    # 1:5 → 벡터 데이터
    # c(2, 4) → 차원 정의(2x4 행렬)
    
    생성된 배열[,1][,2][,3][,4]
    [1,]1352
    [2,]2413
  • 배열 요소 접근

    # 1행 요소 값 출력
    x[1, ]
    > 1 3 5 2
    
    # 3열 요소 값 출력
    x[, 3]
    > 5 1
    
    # 특정 위치 요소 값 출력
    x[2, 3]
    > 1
    
    x[1, 2:4]
    > 3 5 2
    
  • 행/열 단위로 묶어 배열 생성

    • 사용된 벡터명은 행/열 이름이 된다.
    v1 = c(1, 3, 5, 7)
    v2 = c(2, 4, 6, 8)
    v3 = c(3, 6, 9, 12)
    
    • rbind(벡터1, 벡터2, ...): 행 단위로 묶어 배열 생성

      [,1][,2][,3][,4]
      v11357
      v22468
      v336912
    • cbind(벡터1, 벡터2, ...): 열 단위로 묶어 배열 생성

      v1v2v3
      [1,]123
      [2,]346
      [3,]569
      [4,]7812

(2) 배열 연산

연산자설명
+, -행렬의 덧셈, 뺄셈
*R의 행렬 곱셈(각 열별 곱셈)
%*%수학적 행렬 곱셈(내적)
t(), aperm()전치 행렬
solve()역행렬
det()행렬식

(3) 배열에 유용한 함수

  • apply(행렬 데이터, 1 혹은 2, 연산 함수): 배열의 행/열별로 함수 적용

    x = array(1:10, c(2,5))
    > 1 3 5 7 9
      2 4 6 8 10
    
    # 1: 행별로 함수 적용
    apply(x, 1, mean)
    > 5 6
    
    # 2: 열별로 함수 적용
    apply(x, 2, mean)
    > 1.5 3.5 5.5 7.5 9.5
    
  • dim(배열): 배열의 크기(차원의 수) 출력

    x = array(1:10, c(2,5))
    > 1 3 5 7 9
      2 4 6 8 10
    
    dim(x)
    > 2 5
    

6) 데이터 프레임

R에서 가장 많이 사용되는 구조인 데이터 프레임(data frame)에 대해 살펴보겠습니다.

  • 데이터 프레임(data frame): 가장 흔하게 사용되는, 표 형태의 데이터 구조
    • 행렬과 유사하지만, 행렬과 달리 여러 데이터형을 혼합하여 저장할 수 있다.
    • (row): 가로 방향 줄 = 샘플(sample), 관측(observation)
    • (column): 세로 방향 줄 = 속성(attribute), 특징(feature), 변수(variable)

(1) 데이터 프레임 생성

  • data.frame

    • 각 속성 벡터(열 벡터)의 길이가 동일해야 된다.
    name = c('코', '사', '다', '마')
    age = c(10, 20, 30, 40)
    gender = factor(c('M', 'F', 'F', 'M'))
    blood.type = factor(c('A', 'B', 'O', 'AB'))
    
    # 데이터 프레임 생성
    cosadama = data.frame(name, age, gender, blood.type)
    
    nameagegenderblood.type
    110MA
    220FB
    330FO
    440MAB

📖 참고하기: 데이터 프레임 간단하게 만드는 방법

  • edit

    테이블 형태의 입력 창에 값을 입력하고 닫으면, 해당 값이 데이터 프레임에 저장된다.

    # 직접 확인해보세요 :)
    cosadama = edit(cosadama)
          
    test = data.frame()   # 빈 데이터 프레임으로 실습
    test = edit(test)
    

(2) 데이터 프레임 요소에 접근

  • $: 특정 속성 변수에 접근

  • 각 요소에 접근할 경우, 배열과 마찬가지로 [ ]를 이용한다.

    • 2차원 이상의 데이터의 경우 인덱스 사용 시 ,(반점)을 잊지 말 것!
    cosadama$name
    > '코' '사' '다' '마'
    
    # 특정 조건을 충족하는 데이터 추출
    cosadama[cosadama$name == '코',]   # ,(반점) 잊지 않기
    >10 M A
    
    # '코'의 나이와 혈액형만 추출
    cosadama[cosadama$name == '코', c('age', 'blood.type')]
    > 10 A
    

(3) 데이터 프레임에 유용한 함수

본 커리큘럼에서는 na.omit을 제외한 함수들을 자세히 다루지 않습니다. 가볍게 훑어보시길 바랍니다.

  • attach(속성명): 데이터 프레임의 속성명을 변수로 사용

  • detach(속성명): 변수 사용 해제

  • subset(데이터 프레임, 조건, select=c('열1, ...')): 데이터 프레임에서 일부 데이터만 추출


  • na.omit: 결측값(NA)을 가진 행 제외 추출

    head(airquality)
    
    head(na.omit(airquality$Ozone))   # Ozone 속성만 결측값 제거
    head(na.omit(airquality)$Ozone)   # 모든 속성의 결측값 제거
    

  • is.data.frame(데이터 프레임): 어떤 변수가 데이터 프레임인지 확인 → TRUE, FALSE로 표시
  • as.data.frame(데이터 프레임): 어떤 변수를 데이터 프레임으로 변환
마지막으로 업데이트 된 날짜:
2022년 9월 24일