2024 여름 SWLUG/개인정보보호 프로젝트

R프로그래밍 기초 1 - R 소개와 데이터 구조

un_plugged 2024. 7. 21. 11:06

R 소개 및 변수 선언

R이란?

데이터의 처리, 통계 계산 및 분석, 그래픽스를 위한 프로그래밍 언어

파이썬,C 등과는 다르게 한 줄 한 줄 실행하는 언어라 직관적이고, 에러가 어디서 났는지 쉽게 파악할 수 있다.

 

R 스튜디오

  • 실행 단축키: Ctrl+Enter(tools에서 단축키 확인 가능)
  • 주석: ##

변수 선언

위의 그림에서 a=1과 a <- 1 모두 컴퓨터에게 a에 1을 넣으라는 명령을 내리므로 똑같은 의미이다.

하지만 a = 1과 a ==1과 헷갈릴 수 있으니 a <- 1로 강의에선 사용한다.

또한, R은 한 줄씩 실행하므로 현재 a에는 2가 들어있다.

 

이번엔 대소 비교를 하는 문장이다. 반환값은 True나 false가 나온다.

 

숫자형과 문자형

위의 사진처럼 변수에 문자열을 넣을 수 있다. 문자열을 대입할 때에는 꼭 큰 따옴표로 문자열을 처리해준다.

만약 10번 문장처럼 문자열을 따옴표 처리하지 않는 경우 abc라는 변수를 a에 대입하는 것으로 인식하여 에러가 발생한다.

그러나 위와 같이 abc라는 변수에 값을 대입 후 abc를 a에 대입하는건 가능하다. 

 

※만약 문자형을 큰 따옴표로 지정하는 것을 까먹었다면 드래그로 블록 지정 후 "shift+큰따옴표"를 하면 그 블록이 문자열 처리된다. 

 

참고로 R언어는 숫자, 문자열, 논리값의 3개의 데이터 형식을 가진다. 

 

변수에 저장된 데이터 타입 확인 - numeric, character

class(변수)

 

class를 통해 데이터 타입을 확인할 수 있다. 

위의 그림에서 a는 숫자 3이 들어있고 b는 문자가 들어있다. 

따라서 class(a)를 실행하면 "numeric"이 나오고 class(b)를 실행하면 "character"이 출력된다.

 

타입 변환

만약 데이터 타입을 변환하고 싶다면 as.을 사용하면 된다.

as. 원하는자료형

 

예를 들어 위의 코드에서 a를 문자 3으로 바꾸고 싶다면 다음과 같이 작성하면 된다. 

as.character(a)
class(a) ##a 타입 확인. character로 출력

타입 변환 코드로는 아래와 같이 있다.

as.character()
as.complex()
as.numeric() / as.double() / as.integer()
as.logical()

 

 

 

R 데이터 구조 - Vector

벡터는 R의 통계 분석에서 가장 중요한 데이터 형식이다.  벡터 단위의 연산 및 조작을 지원한다.

  • 동일한 형식의 데이터를 나열
  •  숫자 벡터에는 숫자 데이터만 나열되고, 문자열 벡터나 논리값 벡터에는 각각 문자열과 논리값만이 나열
  • 벡터가 포함하고 있는 데이터의 개수: 벡터의 길이 또는 크기

사실 R은 벡터가 아닌 숫자, 문자, 논리값은 없다. 10이라는 숫자 하나도 사실은 길이가 1인 숫자 벡터이고, 문자열도 논리값도 길이가 1인 문자 벡터와 논리 벡터일 뿐이다.

 

벡터 생성 방법

1. c() 함수를 이용한 벡터의 생성

벡터는 하나의 열(column)이므로 앞글자를 딴 c() 함수를 이용한다.

x <- c(1,3,5)
y <- c("a", "b", "c")
z <- c("true", "false", "true")

 

c() 함수는 요소를 하나씩 연결하는 것뿐만 아니라 여러 개의 요소를 가진 벡터들을 연결하여 더 큰 벡터를 만들 수도 있다.

w <- c(7,9)
c(x,w)

이 경우 벡터 x와 w를 연결한 1,3,5,7,9가 출력된다. 

사실 앞서 본 숫자 1, 3, 5도 요소가 하나인 벡터이고, 요소가 하나짜리 벡터를 연결하여 x라는 벡터를 만든 것으로 볼 수 있다!

 

나열 순서에 따라 만들어지는 벡터의 요소들의 위치가 다르다.

만약 c(w,x)를 할 경우 7,9,1,3,5가 출력된다.

 

2. 수열 패턴을 이용한 숫자 벡터의 생성

1에서부터 10까지의 자연수로 이루어진 벡터를 c() 함수를 이용하여 만드려면 10개의 요소를 일일이 나열하여야 하므로 매우 번거롭다.

-> : 연산자를 이용하면 하나씩 증가하거나 감소하는 수열 패턴으로 벡터를 만들 수 있다. 

-> : 연산자 앞에 기술된 숫자를 시작으로 하여 뒤에 기술된 숫자가 앞에 기술된 숫자보다 크면 하나씩 증가하는, 작으면 감소하는 패턴을 만든다.

1:10

위의 경우 1에서 시작하여 10과 비교하여 벡터를 만든다. 

 1  2  3  4  5  6  7  8  9 10

10까지 갔다가 다시 감소하므로 1~10까지 숫자가 나열된 벡터가 완성된다. 

 

※seq()함수

수열의 시작점(from)과 종료점(to), 그리고 수열이 얼만큼 증가 또는 감소될 지(by)를 지정할 수 있다.

(파이썬의 range 함수와 비슷하다...)

 seq(from=1, to=10, by=2)

이 경우 1부터 10까지 2씩 증가하므로 1 3 5 7 9가 출력된다. 

seq(from=100, to=0, by=-15)

감소하는 벡터를 만들고 싶다면 by를 음수로 지정해줘야 한다.

이 경우 100부터 0까지 15씩 감소한 100 85 70 55 40 25 10이 출력된다. 

 

3. 비교 연산을 이용한 논리값 벡터 만들기

논리값 벡터는 주로 비교 연산(<, >)을 이용하여 만들어진다.

scores <- c(75, 92, 88, 60, 80)

예를 들어 위와 같이 scores라는 변수에 벡터가 들어가 있다. 아래와 같이 비교 연산자를 작성하여 논리값 벡터를 만들 수 있다. 

 scores >= 80
 [1] FALSE  TRUE  TRUE FALSE  TRUE
scores >= 80 &  scores < 90
[1] FALSE FALSE  TRUE FALSE  TRUE

 

벡터의 연산

R에서 벡터에 대한 연산은 대부분 "동일 위치의 요소끼리" 그리고 "요소의 재활용"이라는 두 가지 원칙에 따라 수행된다.

1. 동일 위치의 요소끼리: 동일한 길이의 두 벡터가 연산이 이루어지면 같은 위치의 요소끼리 연산 수행

a <- c(1,2,3)
b <- c(10,20,30)
a+b
[1] 11,22,33

숫자 벡터뿐 아니라 문자열, 논리값 벡터도 같은 원칙에 의해서 연산이 이루어진다.

x <- c(1,3,5)
y <- c("빨강", "노랑", "초록")
paste(y, x, sep="-")
[1] "빨강-1" "노랑-3" "초록-5"

참고로 paste() 함수는 각 벡터를 하나의 문자열로 연결한다. 이때 sep 매개변수는 두 문자열 사이에 삽입될 구분자를 지정하는데 여기서는 "-"가 구분자로 사용되고 있다.

> c(TRUE, FALSE, TRUE) & c(FALSE, FALSE, TRUE)
[1] FALSE FALSE  TRUE

 

벡터의 필터링/인덱싱

1. 필터링

데이터에서 특정 부분만 추출하여 새로운 데이터를 만드는 작업

즉, 벡터 필터링은 특정 벡터에서 특정 요소만을 추출하는 것이다. 

-> 인덱스 벡터 활용!

-> 단, 인덱스는 1부터 시작

vector[index_vector]
  • 인덱스 벡터는 자연수 벡터, 음의 정수 벡터, 논리값 벡터, 이름 벡터의 네 가지 형태
  • 자연수 벡터: 벡터에서 뽑아내고자 하는 요소의 위치를 자연수로 기술하는 인덱스 벡터
scores <- c(75, 92, 88, 60, 80)
scores[2]
[1] 92
scores[2:4]
[1] 92 88 60
scores[c(1, 4)]
[1] 75 60
  • 음의 정수 벡터: 벡터에서 어떤 위치의 요소만 제외하고 뽑을 때 사용하는 인덱스 벡터
scores[-2]
[1] 75 88 60 80
scores[-c(1, 4)]
[1] 92 88 80
  • 논리값 벡터: 인덱스 벡터에서 가장 자주 사용됨. 뽑아내고자 하는 위치의 요소에는 TRUE, 뽑지 않은 위치의 요소에는 FALSE를 기술(T,F로 줄일 수 있음)
scores[c(TRUE, FALSE, TRUE, TRUE, FALSE)]
[1] 75 88 60

자연수 인덱스 벡터 음의 정수 인덱스 벡터와는 달리 논리값 인덱스 벡터는 벡터의 모든 요소에 TRUE나 FALSE가 기술되어야 한다. 만약 논리 인덱스 벡터의 길이가 원래 벡터보다 짧으면 벡터의 요소의 재활용이 인덱스 벡터에 적용된다.

scores[c(TRUE, FALSE)]
[1] 75 88 80

데이터가 무수히 많을 때 아주 유용하게 사용 가능하다. 

scores[scores >= 80]

위와 같이 다양한 조건식을 써서 특정 요소만 추출할 수 있다.

 

R 데이터 구조 - 행렬(Matrix)

  • 벡터처럼 모든 요소가 동일한 데이터의 타입
  •  다차원적인 데이터 구조
matrix(행렬로 바꿀 벡터, nrow, ncol)

여기서 nrow는 행 수, ncol은 열 수이다. 

n <- 1:10
m <- matrix(n, nrow=2, ncol=5)
m <- matrix(n, nrow=2)

위의 2가지 식은 같다. 행만 보고 열의 개수 또는 열만 보고 행의 개를 알 수 있다. 여기서는 총 10개의 데이터에서 행이 2개면 열이 5개로 정해지기 때문이다.

 

한편, matrix()는 열을 순서대로 채워나간다. 즉, 1열의 1행,2행...순으로 채우고 1열의 모든 행을 다 채웠다면 2열로 넘어간다. 만약 열이 아니라 행을 차례대로 채워나가면서 행렬을 만드고 싶으면 byrow=TRUE(T) 인수를 사용하면 된다.

(byrow=F가 기본값(열 순서대로))

 

참고로 "? matrix"를 입력하면 help에 matrix에 대한 설명이 나온다. 

 

인덱스로 접근

m[행,열]

마찬가지로 인덱스는 1부터이다.

만약 어떤 행 전체를 뽑고 싶다면 행만 쓰고 열은 생략하면 된다. 반대로 어떤 열 전체를 뽑고 싶다면 열만 쓰고 행은 생략하면 된다. 

m[1, ]
m[ ,1]

 

 

위와 마찬가지로 어떤 행 또는 열을 빼고 출력하고 싶다면 음의 정수 인덱스 벡터를 사용하면 된다. 

m[-c(1,3), ] ##1행과 3행 빼고 가져옴

 

$로 접근 - 열 추출 

matrix$

위와 같이 행렬에 &를 붙이면 자동으로 열이 나온다. 그 중 출력하고 싶은 열을 선택하면 그 열이 전체 출력된다. 

 

 

 

데이터 프레임

거의 R에서만 존재하는 행렬을 일반화한 것으로 각 열마다 각기 다른 타입의 데이터를 가질 수 있다.

예를 들어 데이터의 형태는 다르지만 한 학생에 대한 정보를 얻기 위해서는 숫자, 문자, 논리 값을 포함한 데이터를 다룰 수 있어야 한다. 

 

즉, 기본적으로  우리가 사용하는 데이터 형태가 데이터 프레임이기 때문에 데이터 프레임으로 바꾸는 것이 좋다. 

data.frame()

 

cbind() 함수

두 개 이상의 벡터/행렬/데이터프레임을 열(column) 방향으로 결합. 즉, 옆+옆으로 결합한다. 새로운 데이터를 추가할 때 주로 사용한다. 

 

rbind() 함수

두 개 이상의 벡터/행렬/데이터프레임을 방향으로 결합. 즉, 위+아래로 결합한다. 

rbind할 경우 새로운 matrix 변수가 필요하다. 

즉, m2 <- rbind(m2,m2)가 아닌 m3 <- rbind(m2,m2)와 같이 작성한다.