1. R 이란?
- 전산통계학을 위한 프로그래밍 언어
- 데이터 통계처리 및 시각화에 특화되어 있음
1.1 R의 장단점
✅ 장점
언어적 측면
- 통계 계산용 패키지 매우 우수 → dplyr, tidyr, stringr, lubridate
- 강력한 시각화 패키지 제공 → ggplot2, rgl, htmlwidgets
- 뛰어난 확장성 → 웹기반 분석결과 리포팅 (ggvis, shiny), 인공지능 연구(lme4/nlme, randomForest, caret, deepnet)
사용자 측면
- 유저 커뮤니티 활성화 → 대부분의 유저들이 유사한 목표를 가짐, 디버깅 용이
- 상대적으로 학습 난이도 낮음
- 다양한 os 지원
- 무료
✅ 단점
- 느린 속도 : 범용 프로그래밍 언어보다 처리 속도 느림
- 한정된 사용성 : 대규모 IT 서비스 개발에 접목이 어려움
- 보안 기능 없음
1.2 데이터 마이닝이란?
- Data + Mining = '데이터'로부터 정보를 '채굴'
- 데이터 모집단의 패턴을 찾아 새로운 데이터를 예측, 군집화, 분류하기 위함
- R은 데이터 마이닝을 하기 위해 사용함
1.3 R 활용 가능 분야
- 텍스트 마이닝 : 방대한 텍스트 정보를 크롤링하고 단어 빈도순으로 가중치를 두어 시각화함
- 소셜 네트워크 분석 : 사람 간 관계 시각화 (SNS 팔로우, 친구 추가 데이터 사용)
- 지도 시각화
- 주식 분석 : 통계 패키지를 사용한 주가 예측
- 이미지 분석 : 이미지 라벨링, 이미지 구획 나누기
- 사운드 분석 : 아날로그 소리 데이터를 디지털 벡터 데이터로 변환
- 웹 애플리케이션 개발
1.4 데이터 처리 과정에서 R의 역할
2. R 기본 기능
2.1 데이터 타입 & 객체
- Object (객체) : R이 다루는 가장 기초적인 구조
- Class : 객체의 타입 (class() 함수 사용)
데이터 타입 | 설명 |
Numeric (수치형) | 숫자를 나타내는 데이터 타입 |
Integer (정수형) | 정수 값만 나타내는 데이터 타입 (메모리 관리에 효율적) |
Logical (논리형) | 참, 거짓을 나타내는 데이터 타입 (TRUE, FALSE, T, F) |
Character (문자형) | 문자 또는 문자열을 나타내는 데이터 타입 |
데이터 객체 | 설명 |
Inf (Infinity) | 무한히 큰 값을 나타내는 데이터 객체 |
NA (Not Available) | 결측치를 나타내는 데이터 객체 |
NaN (Not a Number) | 수치값으로 표현할 수 없는 값을 나타내는 데이터 객체 |
2.2 R 자료 구조
✅ 벡터 (Vector)
- 1차원 구조
- 데이터 타입이 동일한 값들의 모음
- 생성 방법 : c(데이터) / vector('데이터 타입', length = 벡터크기)
## 생성 방법 1
c(1, 2, 3)
# [OUT] 1 2 3
c('a', 'b', 'c')
# [OUT] "a" "b" "c"
c(T, T, F)
# [OUT] TRUE TRUE FALSE
## 생성 방법 2
# 생성 시 각 자료형 별 디폴트 값 : "", 0, FALSE
vector('character', length = 5)
# [OUT] "" "" "" "" ""
vector('numeric', length = 5)
# [OUT] 0 0 0 0 0
vector('logical', length = 5)
# [OUT] FALSE FALSE FALSE FALSE FALSE
- 벡터에 서로 다른 데이터 타입을 넣으면 자동 형 변환이 일어남
- 자동 형변환 우선 순위 : Character > Numeric > Logical
c(1.7, 'a') # 숫자형 → 문자형으로 변환
# [OUT] "1.7" "a"
c(TRUE, 2) # 논리형 → 숫자형으로 변환
# [OUT] 1, 2
c('a', TRUE) # 논리형 → 문자형으로 변환
# [OUT] "a" "TRUE"
✅ 행렬 (Matrix)
- vector의 집합
- 단일형, 2차원 데이터 자료 구조
- 생성 방법 : matrix(nrow = 행 크기, ncol = 열 크기)
# 2X3 크기의 행렬 생성
matrix(nrow = 2, ncol = 3)
# 데이터를 추가해서 행렬 생성
matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3) # 데이터 추가
# 데이터를 행부터 채우기 (기본값 F)
matrix(c(1, 2, 3, 4, 5, 6), nrow = 2, ncol = 3, byrow = T)
- 행렬의 데이터 타입
→ 행/열 크기를 담는 dim 속성을 추가로 가짐
→ Matrix == dim 크기가 2인 array
class(matrix(nrow = 2, ncol = 3))
# [OUT] "matrix" "array"
✅ 배열 (Array)
- dim 속성 크기가 2 이상인 자료 구조
- 단일형, 2차원 데이터 자료 구조
- 생성 방법 : array(dim = c(데이터))
# 2행 2열인 행렬의 3층짜리 배열 만들기
array(dim = c(2, 2, 3))
# 데이터 추가하여 배열 만들기
array(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), dim = c(2, 2, 3))
✅ 리스트 (List)
- 서로 다른 데이터 타입이 존재하는 값들의 모음 (다중형 데이터 자료 구조)
- 생성 방법 : list()
list(c(1,2,3), 2, T)
# 리스트 내 리스트 생성 (이중 리스트 생성)
list(list(1, T, 'a'), 1)
# 리스트 내 matrix도 가능
list(matrix(nrow = 2, ncol = 3), 'a', 5)
✅ 데이터 프레임
- list의 집합 (다중형, 2차원 구조)
- 열 별로 다른 데이터 타입 저장 가능
- 생성 방법 : data.frame(vector, vector, ...) → 각 vector는 컬럼 값으로 삽입됨
data.frame(c(1,2,3,4,5), c('a', 'b', 'c', 'd', 'e'), c(T, T, F, T, T))
# 변수로 데이터 프레임 생성
ID <- c(1,2,3,4,5)
Grade <- c('a', 'b', 'c', 'd', 'e')
Pass <- c(T, T, F, T, T)
data.frame(ID, Grade, Pass)
2.3 변수
- 데이터를 저장하기 위해 이름을 할당 받은 메모리 공간
- 객체(Object)를 저장해 놓는 보관함
✅ 변수 초기화
# 변수 선언만 하고 싶은 경우
a <- NULL
a # [OUT] NULL
# 변수에 값 할당
a <- 10
a # [OUT] 10
✅ 변수 할당
# 연산의 결과를 할당 가능
a <- 10 + 20 # [OUT] 30
b <- a - 5 # [OUT] 25
c <- c(1, 2, 3) + 5 # [OUT] 6, 7, 8
d <- (10 > 5) # [OUT] TRUE
e <- b + d # [OUT] 26
# 하나의 객체만 저장 가능
a <- 5, 10 # Error: unexpected ',' in "a <- 5,"
# 한 번에 여러 변수 선언 및 할당 불가
a, b <- 5, 10 # Error: unexpected ',' in "a,"
# 특별한 데이터 타입 할당 가능
a <- Inf # [OUT] Inf
b <- 2/0 # [OUT] Inf
c <- NA # [OUT] NA
d <- NaN # [OUT] NaN
e <- 0/0 # [OUT] NaN
✅ 변수 작명 규칙
- 첫글자 : 문자 또는 마침표(.)만 사용 가능 (숫자, 언더바로 변수명 시작 불가)
- 알파벳 대분자와 소문자는 별개의 문자 취급
- 변수명 중간에 빈 칸 넣을 수 없음
- 한국어 변수 사용가능하나 인코딩 이슈로 권장하지 않음
✅ 변수 보기 및 삭제
- ls() : 변수 보기
- rm(변수명) : 변수 삭제
- rm(list = ls()) : 변수 모두 삭제
2.4 함수
- 매개변수를 받아 정의된 내용을 실행하며, 결과 값을 리턴하는 장치
✅ 내장 함수
- 산술 함수 : min, max, sum, prod, factorial, abs
- 강제 형변환 함수 : as
vec <- c(T, F, FALSE)
vec2 <- as.numeric(vec)
vec3 <- as.logical(vec2)
vec4 <- as.character(vec3)
vec # [OUT] TRUE FALSE FALSE
vec2 # [OUT] 1 0 0
vec3 # [OUT] TRUE FALSE FALSE
vec4 # [OUT] "TRUE" "FALSE" "FALSE"
# 높은 우선 순위 → 낮은 우선 순위 형 변환
# character > numeric > logical
test <- c('char', '10', 'TRUE')
test_to_num <- as.numeric(test)
test_to_logic <- as.logical(test)
test_to_num # [OUT] NA 10 NA
test_to_logic # [OUT] NA NA TRUE
- 데이터 생성 함수 : seq, rnom, runif
# seq 함수 (from으로부터 by씩 증가하는 length개의 숫자로 이루어진 벡터 생성)
seq(length = 5, from = 3, by = 2) # [OUT] 3 5 7 9 11
# rnorm 함수 (평균이 mean, 분산이 sd인 정규분포를 따르는 n개의 숫자로 이루어진 벡터 생성)
rnorm(n = 4, mean = 0, sd = 1) # [OUT] -0.21253399 -0.03296793 0.07698710 0.48839667
# runif 함수 ([min, max] 범위 사이 n개의 난수로 이루어진 벡터 생성)
runif(n = 4, min = 1, max = 100) # [OUT] 11.33962 14.06943 94.06348 14.83108
✅ 사용자 정의 함수
- 사용자가 직접 정의하여 만들어내는 함수
myFunc <- function(x) {
return (2*x + 2)
}
a <- myFunc(2)
print(a) # [OUT] 6
print(myFunc(3)) # [OUT] 8
2.5 패키지
- 유사한 기능을 하는 함수들의 모음
✅ 패키지 관리 함수
- install.packages('패키지 이름') : 패키지 설치
- library(help = 패키지 이름) : 패키지에 대한 정보 출력
- update.packages('패키지 이름') : 패키지를 최신 버전으로 업데이트 (패키지 이름 기재하지 않으면 모든 패키지 업데이트)
- remove.packages('패키지 이름') : 패키지 삭제
2.6 [실습] 고객의 은행 대출 상품 신청 현황 데이터
첫번째 표와 같이 데이터프레임(result)을 생성하고, 두번째 표와 같이 수정(result_new)하세요.
[수정사항]
1. 문자 데이터 수정은 stringr 패키지의 함수 사용할 것
2. job 컬럼의 “은퇴” 값은 “무직”으로 대체 할 것
3. marital 컬럼은 logical 값으로 관리 할 것 (“결혼” 값은 T로, 나머지 값은 모두 F로 관리)
4. 수정된 결과물은 result_new 변수에 할당 후 출력 할 것
# Age : numeric (Integer) / 수치형/범주형
# Job : character / 범주형
# Marital : character / 범주형
# Balance : numeric / 수치형
# Campaign : character / 범주형
# Y : logical / 범주형
# 1. 컬럼 별 변수 생성
age <- c(30, 33, 35, 30, 68, 33)
job <- c('무직', '서비스', '관리직', '관리직', '은퇴', '관리직')
marital <- c('결혼', '결혼', '미혼', '결혼', '사별', '결혼')
balance <- c(1787, 4789, 1350, 1476, 4189, 3935)
campaign <- c('휴대폰', '휴대폰', '휴대폰', 'Unknown', '유선전화', '휴대폰')
Y <- c(F, F, F, F, T, T)
# 2. 데이터프레임 생성한 것을 result 변수에 할당
result <- data.frame(age, job, marital, balance, campaign, Y)
# 3. 결과 출력
print(result)
# 4. 평균 나이, 평균 은행 잔고 출력
age_mean <- mean(age)
age_mean # [OUT] 38.16667
balance_mean <- mean(balance)
balance_mean # [OUT] 2921
# 5. 대출을 신청한 사람 수 계산
yToNum <- as.numeric(Y) # [OUT] 0 0 0 0 1 1
yCount <- sum(yToNum)
print(yCount) # [OUT] 2
# 6. 데이터값 수정
# 1) stringr 패키지 사용
install.packages('stringr')
library(stringr)
# 2) job 컬럼의 '은퇴' → '무직'으로 대체
job_new <- str_replace(job, '은퇴', '무직')
print(job_new)
# 3) marital 컬럼의 형을 logical로 변환 ('결혼' : T, 그 외 : F)
# '결혼'값을 'T'로 변환
marital_new <- str_replace(marital, '결혼', 'T')
print(marital_new)
# 문자형을 논리형으로 강제 형변환
marital_logical <- as.logical(marital_new)
print(marital_logical)
# NA 값을 F로 변환
marital_logical[is.na(marital_logical)] = FALSE
print(marital_logical)
# 4) 수정된 결과물은 result_new 변수에 할당 후 출력
result_new <- data.frame(age, job_new, marital_logical, balance, campaign, Y)
print(result_new)
3. 멘토링
R의 기본 기능을 다시 복습하고 다같이 간단한 예제를 풀어보는 시간을 가졌다.
3.1 벡터 만들기
- c() 함수: 해당하는 숫자 모두 기재 or 슬라이싱으로 기재
- seq(시작, 끝, 간격) 함수
- rep(벡터, 반복횟수) 함수
# 1. 벡터 만들기
# 1) 1부터 10까지의 숫자로 이루어진 벡터 만들기
c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
c(1:10)
seq(1, 10, 1)
# 2) 1, 2, 3, 50, 51, 52, 53, 54, 55로 이루어진 벡터 만들기
c(1, 2, 3, 50, 51, 52, 53, 54, 55)
c(1:3, 50:55)
# 3) 1부터 100까지 3간격의 숫자로 이루어진 벡터 만들기
seq(1, 100, 3)
# 4) 0.1부터 1까지 0.1 간격의 숫자로 이루어진 벡터 만들기
seq(0.1, 1, 0.1)
# 5) 1, 1, 1, 1, 1로 이루어진 벡터 만들기
rep(1, 5)
# 6) 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3
rep(1:3, 5)
rep(c(1, 2, 3), 5)
3.2 벡터 슬라이싱 / 인덱싱
- 변수명[첫 숫자 : 끝 숫자]
- 변수명[-인덱스] : 해당 인덱스를 제외하고 출력
- 불린 인덱싱 : 출력하고자 하는 데이터의 인덱스에 T(TRUE) 기재
- 팬시 인덱싱 : 출력하고자 하는 데이터의 인덱스를 벡터로 기재
- names(변수명) <- 벡터
# 2. 벡터 인덱싱/슬라이싱
# 요일 별 결석자 데이터가 담긴 벡터 (absent)
absent <- c(3, 2, 0, 4, 1)
# 1) 인덱싱
# 월요일 결석자
absent[1] # [OUT] 3
# 수요일 제외 결석자
absent[-3] # [OUT] 3 2 4 1
# 2) 슬라이싱
# 월화수 결석자
absent[1:3] # [OUT] 3 2 0
absent[-4:-5] # [OUT] 3 2 0
absent[-c(4:5)] # [OUT] 3 2 0
# 3) 불린 인덱싱
# 1, 3, 5번째 요소만 인덱싱
absent[c(T, F, T, F, T)] # [OUT] 3 0 1
# 4) 팬시 인덱싱
# 1, 3, 5번째 요소만 인덱싱
absent[c(1, 3, 5)] # [OUT] 3 0 1
# 5) 벡터 absent 각 요소에 'Mon', 'Tue', 'Wed', 'Thu', 'Fri' 이름 붙이기
names(absent) <- c('Mon', 'Tue', 'Wed', 'Thu', 'Fri')
absent
# [OUT]
# Mon Tue Wed Thu Fri
# 3 2 0 4 1
# 6) 특정 요소 가져오기
absent['Mon']
absent[c('Mon', 'Wed')]
4. 회고
처음 R에 대해 배웠다. SQL, 파이썬과 비슷하긴 한데, 또 다른 문법과 함수들이 있어서 조금씩 헷갈렸다.
하지만 생각보다 파이썬보다 문법이 간단했다. 벡터, 리스트, 데이터프레임 등 다양한 데이터 자료를 간단한 명령어로 만들 수 있었다.
특히, R에서는 자료 구조가 중요해서 이에 대해 자세하게 배웠다. 다소 헷갈리긴 하지만 계속 공부하면 머릿속에 잘 입력이 될 듯하다.
R이 통계적인 분석을 할 때 유용하다고 했는데, 아직 R의 기본 기능과 문법을 익히는 중이라 와닿지는 않는다. 내일과 내일 모레에 R을 심층적으로 공부하면서 통계적인 부분을 다룰 수 있지 않을까 싶다.
R, SQL, 파이썬이 헷갈리지 않도록 잘 정리해두자.
'웅진X유데미 STARTERS > TIL (Today I Learned)' 카테고리의 다른 글
[스타터스 TIL] 13일차.기초부터 익히는 R (3) - ggplot2, 텍스트 마이닝, 단계 구분도, 통계분석 (0) | 2023.02.23 |
---|---|
[스타터스 TIL] 12일차.기초부터 익히는 R (2) - R 연산자, 조건문, 반복문, 함수, 시각화 (0) | 2023.02.21 |
[스타터스 TIL] 10일차.SQL을 통한 데이터활용과 분석 (3) - 집계함수, 순위함수, 실습 (0) | 2023.02.17 |
[스타터스 TIL] 9일차.SQL을 통한 데이터활용과 분석 (2) - 기본 문법 (0) | 2023.02.16 |
[스타터스 TIL] 8일차.SQL을 통한 데이터활용과 분석 (1) - DDL, DML, WHERE절 (0) | 2023.02.16 |