9 분 소요

r

1. 변수

1) 명명 규칙

R에서의 변수명은 알파벳, 숫자, _ (언더스코어), .(마침표)만 사용할 수 있다. - (하이픈)은 사용불가하며, 첫 글자는 반드시 알파벨 또는 .(마침표)로 시작해야한다.

2) 변수에 값 할당하기

생성한 변수에는 값을 저장할 수 있으며, 프로그래밍에서는 이를 “변수에 값을 할당한다” 라고 표현한다. 또한 값을 할당할 때에도 연산자를 사용하는데, <- , «- , = 를 사용한다. 일반적으로는 <- 과 = 를 많이 사용하는데, = 는 명령의 최상위 수준에서만 사용할 수 있는 반면, <- 는 어느 곳에서든 사용할 수 있다. 따라서, 함수를 호출하고, 동시에 변수에 값을 할당하는 목적으로는 <- 만 사용가능하기 때문에, = 보다는 <- 연산자를 많이 사용하는 것이다.

2. 스칼라

단일 차원의 값을 의미하며, 길이가 1인 벡터라고 할 수 있다. 벡터에 대한 자세한 내용은 뒤에서 살펴보기로 하자. 스칼라에 해당하는 데이터 타입은 숫자형, 문자열, 불리언, NA, NULL이 있으며, 각 데이터 타입별 설명은 아래와 같다.

1) 숫자형

R에서는 정수형, 부동소수 등의 숫자형 타입을 지원한다. 간단하게 아래의 예제를 실행해보자.

[R Code]

a <- 3
b <- 4.5

print(a);print(b)

위의 예제에서 print() 는 값을 출력해주는 함수이고 중간에 ; 연산자는 여러 개의 코드를 한 줄에서 한번에 실행시켜주는 연산자이다. 숫자형이기 때문에 사칙연산 및 기타 수치 연산자들도 사용이 가능하다. 아래 예제를 통해서 살펴보자.

[R Code]

# 사칙 연산
a <- 1
b <- 2
c <- 3

print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(c %/% b) # 몫
print(c %% b)  # 나머지
print(b ** c)  # 거듭제곱
[실행 결과]

> print(a + b)
[1] 3
> print(a - b)
[1] -1
> print(a * b)
[1] 2
> print(a / b)
[1] 0.5
> print(c %/% b) # 몫
[1] 1
> print(c %% b)  # 나머지
[1] 1
> print(b ** c)  # 거듭제곱
[1] 8

2) 문자열

R 에서는 다른 프로그래밍 언어와 달리 문자 1개에 해당하는 데이터 타입은 존재하지 않는다, 따라서 문자열 형식으로 모든 문자를 표현한다고 할 수 있으며, 문자열을 사용할 때는 반드시 ‘’ 또는 “” 로 문자를 묶어서 사용해야 한다.

[R Code]

str1 <- "hello"
str2 <- 'world'

print(str1);print(str2)
[실행 결과]

[1] "hello"
[1] "world"

문자열과 관련된 연산을 이후에 다시 다룰 예정이기 때문에 이번 장에서는 어떻게 선언하는 지만 살펴보도록 하자.

3) 불리언

불리언 값은 참/거짓을 표시하는 값을 의미하며, R 에서는 T(TRUE) , F(FALSE)로 사용할 수 있다.

[R Code]

bool1 <- T
bool2 <- TRUE
bool3 <- F
bool4 <- FALSE

print(bool1); print(bool2)
print(bool3); print(bool4)
[실행 결과]
> print(bool1); print(bool2)
[1] TRUE
[1] TRUE

> print(bool3); print(bool4)
[1] FALSE
[1] FALSE
불리언 값은 수학에서의 부울 대수 연산과 관련이 있기 때문에, & (AND), (OR), !(NOT) 과 같이 불리언 연산자를 사용하여 부울 연산을 수행할 수 있다.
[R Code]

print(bool1 & bool2)
print(bool2 | bool3)
print(!bool4)
[실행 결과]

[1] TRUE
[1] TRUE
[1] TRUE

4) NA & NULL

R이 다른 언어와 가장 큰 차이점을 보이는 것이 바로 NA 형의 유무이다. NA는 Not Available 의 약어로 상수이며, 데이터 값이 없음을 의미한다. 만약, 특정 객체에 NA 값이 있는지를 확인하는 방법은 is.na() 함수를 사용하여 확인할 수 있다.

[R Code]

var_na <- NA
is.na(var_na)
[실행 결과]

[1] TRUE

NA의 경우 데이터 전처리에서 어떻게 처리할 지에 따라 여러 가지의 함수를 사용하기 때문에, 자세한 처리 방법은 추후에 데이터 전처리에 대한 내용에서 다루기로 하자. NA와 비슷한 의미인 NULL 도 R에서 사용할 수 있는데, 변수가 초기화 되지 않았을 경우에 사용한다.

[R Code]

var_null <- NULL
is.null(var_null)

[실행 결과]

[1] TRUE

반드시 알아두어야 될 것은 NA 와 NULL 서로 다른 값이기 때문에 is.na 혹은 is.null 함수에 각각 NA 혹은 NULL 이 아닌 값이 들어오면, 모두 FALSE를 반환하게 되니, 연산 시에 참고해서 사용하는 것이 좋다.

3. 펙터(Factor)

범주형 데이터를 표현하기 위한 데이터 타입으로 사전에 정해진 특정 유형으로만 분류되는 데이터에 대해 관측값과 레벨로 나열되는 벡터이다. 아래의 내용은 펙터를 생성하는 factor() 함수의 구성이다.

[R Code]

factor(data, level=c(1,2) , ordered=False)

다음으로 펙터형과 관련된 데이터를 확인해보자.

[R Code]

nlevels(x)  # 펙터의 레벨 개수 확인
levels(x)   # 펙터의 레벨 목록 확인
is.factor(x)  # 주어진 값이 펙터형인지 확인
ordered(x)    # 펙터의 내용을 정렬시킴
is.ordered(x) # 펙터의 내용이 정렬됬는지 확인

4. 벡터

벡터란 종류가 같은 기본 값을 모아 놓은 그룹이다. 1차원 형태이며, 구성 요소는 숫자일수도 있고, 참/거짓과 같은 불리언형, 문자형 등 다양한 종류가 들어갈 수 있지만, 모든 요소는 하나의 데이터 형으로 들어가야한다.

1) 수치형 벡터

숫자값으로 구성된 벡터이며, 스칼라 역시 길이가 1인 특수한 수치형 벡터라고 할 수 있다. 수치형 벡터를 만드는 방법은 아래 예시와 같다.

(1) numeric()

원하는 길이의 영벡터를 생성할 수 있다.

[R Code]

numeric(10)
[실행 결과]

[1] 0 0 0 0 0 0 0 0 0 0

(2) c()

스칼라를 포함한 여러가지 벡터를 하나로 합칠 수 있다.

[R Code]

c(1, 2, c(3, 4, 5))
[실행 결과]

[1] 1 2 3 4 5

(3) :, seq()

:, seq() 모두 연속적인 정수 벡터를 생성해 주는 함수이다. 차이점은 seq() 함수의 경우, step 옵션값을 사용해 원하는 숫자 만큼씩 증가하는 벡터를 생성할 수 있다. 또한 length.out 옵션에 숫자 값을 주면, 시작 숫자 부터 length.out 의 길이만큼 벡터를 생성한다.

[R Code]

1:5
seq(1, 10, 2)
seq(3, length.out=10)
[실행 결과]

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

(4) 수치형 벡터의 산술 연산

수치형 벡터의 경우, 사칙 연산 역시 가능하다. 사칙 연산을 할 때는 다음 2가지 규칙을 따른다. 하나는 요소별 방식으로 연산을 수행한다는 점이고, 다른 하나는 벡터간의 연산은 반드시 길이가 같아야 한다. 어떻게 동작하는 지 아래의 코드를 살펴보자.

[R code]

c(1, 2, 3, 4) + 2
c(1, 2, 3) - c(3, 4, 5)
[실행 결과]

3 4 5 6
-2 -2 -2

위의 코드 및 실행 결과를 살펴보면 알 수 있듯이, 벡터와 스칼라 연산의 경우 각 요소별로 스칼라 값에 대한 연산이 발생하였고, 벡터와 벡터의 연산에서는 동일한 인덱스를 갖는 요소들 끼리 산술 연산되었다는 것을 알 수 있다.

2) 논리형 벡터

수치형과 달리 논리형 벡터는 TRUE 와 FALSE 값의 벡터라고 할 수 있다. 가장 간단한 논리형 벡터는 TRUE/FALSE 값 그 자체이다.

[R Code]

TRUE

만약 TRUE, FALSE를 모두 쓰는게 별로라면, 벡터 자체에 조건식을 걸 수도 있다.

[R Code]

c(1, 2) > 3
[실행 결과]

[1] FALSE FALSE

위의 코드는 벡터의 모든 요소에 조건식을 계산한 건데, 각 요소별로 조건을 따로 주고 싶다면 아래와 같이 사용할 수 있다.

[R Code]

c(1, 2) > c(2, 1)
[실행 결과]

[1] FALSE TRUE

위의 코드는 c(1 > 2 , 2 > 1) 인 것과 결과는 동일하다. 하지만, 만약 길이가 다르다면 어떨까? 아래의 코드와 결과를 살펴보자.

[R Code]

c(2, 3) > c(1, 2, -1, 3)
[실행 결과]

[1] TRUE TREU TRUE FALSE

이 코드는 길이가 긴 벡터의 모든 요소들이 길이가 짧은 벡터 안의 요소들을 재활용해서 사용하는 구조이다. 그 외에 복합 논리 연산자, %in% 와 같은 연산자들도 존재한다.

3) 문자형 벡터

단어 그래도 문자형 데이터가 요소인 벡터이다.

[R Code]

c("Hello", "World")
[실행 결과]

[1] "Hello" "World

문자열의 비교는 == 연산자를 사용해서 비교가 가능하다. 사용법은 아래와 같다.

[R Code]

c("Hello", "World") == c('Hello', 'World')
[실행 결과]

[1] TRUE TRUE

위의 코드 실행 결과에서 나온 것처럼, 큰따옴표나 작은 따옴표 모두 사용가능하며, 비교는 따옴표 내부의 문자들 끼리 순서대로 비교하는 것을 확인할 수 있다. 만약 문자열 중 특수문자에 대한 비교를 할 경우 이스케이프 문자() 를 사용해서 비교가 가능하다.

[R Code]

cat("Is \"You\" a Chinese name?")
[실행 결과]

[1] Is "You" a Chinese name?

위의 예시와 같이 이스케이프 문자를 사용하면, 큰 따옴표와 같은 문자를 그대로 출력할 수 있다. 하지만 가독성이 떨어진다는 단점이 있기 때문에 아래와 같이 변경할 수 있다.

[R Code]

cat('Is "You" a Chinese name?')
[실행 결과]

[1] Is "You" a Chinese name?

결과는 위와 동일하지만 가독성을 비교해보자면 아래의 구문이 좀 더 읽기 쉽다. 이처럼 문자열 안에 따옴표를 쓸 경우 작은 따옴표를 사용해 주는 것도 방법이다.

4) 그 외의 벡터

가장 많이 쓰이는 벡터는 위의 3가지 지만, 복소수를 표현한 복소수 벡터, 16진수로 구성된 16진수 벡터 등도 존재한다. 자주 사용되는 것은 아니지만, 사용법은 기본적으로 앞서 배운 3가지와 유사하다.

5) 벡터의 연산

이번에는 벡터의 요소에 대한 연산과 접근방법을 알아보자.

(1) 서브세팅(Sub-Setting)

여기서의 서브세팅이란 벡터의 일부를 가져오는 것, 즉 해당 객체에 대한 부분집합을 의미한다. 다른 말로는 슬라이싱이라고 할 수 있다. 이는 벡터의 데이터를 접근할 때 반드시 인덱스를 사용해서 접근하는 것과 연관있다. 예를 들어, (1, 2,3, 4) 로 구성된 벡터가 있다고 가정해보자. 이 때 해당 벡터의 2번째 요소에 대한 접근은 다음과 같이 한다.

[R Code]

a <- c(1, 2, 3, 4)
a[2]
[실행 결과]

[1] 2

여기서 주의할 점은 다른 프로그래밍 언어와 달리, R 의 인덱스는 0 이 아닌 1부터 시작한다는 점이다.

다음으로 연속적으로 값을 추출하는 방법을 살펴보자. 예를 들어 앞의 벡터에서 2~4번째에 해당하는 요소를 추출한다고 할 때 아래와 같이 표현할 수 있다.

[R Code]

a[2:4]
[실행 결과]

[1] 2 3 4

부분집합을 추출하고자 한다면, 인덱스 값을 벡터로 넣어 주면 된다.

[R Code]

idx1 <- c(1, 3)
a[idx1]
[실행 결과]

[1] 1 3

만약 부분집합을 계산할 때 본래 벡터의 크기를 넘어가는 부분집합을 계산하게 되면, 부족한 부분만 NA 로 채워지게 된다. NA 의 의미는 사용불가능한, 결측값을 의미하며, 비교, 사칙연산등이 불가능한 값이다. 해당 내용은 추후에 다시 다룰 예정이다.

[R Code]

a[3:6]
[실행 결과]

[1] 3 4 NA NA

인덱스를 음수로 표시하게 되면 해당 위치의 요소를 제외한다는 의미로 사용된다. 단, 음수를 사용할 때는 양수와 섞어서 사용할 수는 없다.

[R Code]

a[c(1, 2, -3)]
[실행결과]

Error in a[c(1, 2, -3)] : only 0's may be mixed with negative subscripts

부분집합을 산출하는 또 다른 방법으로는 논리형 값을 사용하는 것이다. 사용법은 아래와 같다.

[R Code]

a[c(TRUE, FALSE, TRUE, FALSE)]
[실행 결과]

[1] 1 3

위의 예시와 같이 숫자 인덱스 대신 출력하고자 하는 인덱스에 TRUE 값을 넣어주면, 본래 벡터에서 해당 부분의 값만 출력해준다. 이를 조금 더 응용해보자면, 값을 할당하는 연산까지도 가능하다.

[R Code]

a[c(TRUE, FALSE, TRUE, FALSE)] <- c(3, 2)
[실행 결과]

[1] 3 2 2 4

실행결과를 통해서 알 수 있듯이. 논리형 벡터의 TRUE 로 설정된 부분과 대응되는 본래 벡터의 값에 각각 3 과 2를 할당해 준 것을 알 수 있다.
만약 존재하지 않는 값에 요소를 할당하게 되면, 본래의 벡터에서 입력 해준 인덱스까지 벡터를 늘이고, 해당 인덱스에 값을 할당한 뒤, 나머지 부분을 NA로 채워준다.

[R Code]

a[10] <- 8
[실행 결과]

[1] 3 2 2 4 NA NA NA NA NA 8

(2) 인덱스 명 변경하기

벡터의 각 원소별로 이름을 지정해 줄 수 있다. 지정하는 방법은 아래와 같이 벡터명[“인덱스명”] 과 같은 형식으로 사용할 수 있다.

[R Code]

x <- c(a=1, b=2, c=3)
print(x)
[실행 결과]

a b c
1 2 3

위와 같은 경우 요소의 인덱스 명으로 값을 얻을 수 있다. 아래의 예시처럼 인덱스의 위치에 인덱스 명을 넣어주면 되며, 인덱스의 위치에 문자열 벡터를 사용해 줌으로써, 여러 개의 값을 가져올 수도 있다.

[R code]

x[c("a","c")]
[실행 결과]

a c
1 3

인덱스 이름이 중복되는 경우에도 중복 허용으로 값을 출력할 수 있다.

[R code]

x[c("a","c", "c")]
[실행 결과]

a c c
1 3 3

설정한 인덱스 명은 names() 함수로 조회가 가능하다.

[R code]

names(x)
[실행 결과]

"a" "b" "c"

이미 설정된 인덱스 명을 변경하고자 하려면, names() 함수에 대해 문자열 벡터를 대입하면 된다.

[R code]

names(x) <- c("x", "y", "z")
names(x)
x["z"]
[실행 결과]

"x" "y" "z"

z
3

인덱스 명을 삭제하려는 경우에는 names() 함수에 NULL 을 대입하면 된다.

[R code]

names(x) <- NULL
print(x)
[실행 결과]

1 2 3

만약 존재하지 않은 인덱스 명으로 벡터의 요소를 검색하는 경우에는 NA 값이 출력된다.

[R code]

x["a"]
[실행 결과]
NA

(3) 요소의 클래스 확인하기

모든 R 객체는 각각 클래스가 존재하며, 확인을 하기 위해서는 class() 함수를 사용해서 어떤 클래스에 속하는지 확인할 수 있다.

[R code]

class(x)
[실행 결과]

"numeric"

벡터를 구성하는 요소들 역시, 클래스를 갖고 있으며, 벡터가 원하는 클래스인지를 확인하기 위해, R 에서는 is.numeric, is.character, is.logical 과 같은 함수를 제공한다.

[R code]

is.numeric(c(1,2,3))
is.numeric(c(T,F,T))
is.logical(c(T,F,T))
is.character(c("a", "b", "c"))
[실행 결과]

TRUE
FALSE
TRUE
TRUE

(4) 벡터 변환하기

앞서 언급한 것처럼 R에서 생성한 각 벡터는 클래스를 갖고 있다고 언급했다. 때문에 다른 프로그래밍 언어에서 등장하는 형변환도 R 에서 가능하다. 함수는 as.numeric(), as.logical(), as.character() 와 같은 함수를 사용해서 벡터의 형변환을 할 수 있다. 변환 시에는 반드시 변환했을 때의 요소가 해당 클래스의 형태와 같은 형식이어야 한다.

[R code]

as.character(c(1,2,3))
as.logical(c("T", "F", "F"))
as.numeric(c("T", "F", "F"))
[실행 결과]

"1" "2" "3"
TRUE FALSE FALSE
NA NA NA
경고메시지(들):
강제형변환에 의해 생성된 NA 입니다

태그: ,

카테고리:

업데이트:

댓글남기기