iBetter Books
수정

R 기초 복습

통계 분석을 본격적으로 시작하기 전에, R의 핵심 개념을 빠르게 훑어봅니다. 1권을 읽었다면 익숙한 내용이겠지만, 처음 이 책을 펼친 독자도 이 챕터만으로 충분히 따라올 수 있도록 정리했습니다.

변수와 기본 자료형

R에서 변수에 값을 저장할 때는 <- 연산자를 씁니다. =도 되지만 R 생태계에서는 <-를 표준으로 씁니다.

# 숫자
age <- 28
height <- 172.5

# 문자
name <- "홍길동"

# 논리값
is_student <- TRUE

# 자료형 확인
class(age)      # "numeric"
class(name)     # "character"
class(is_student) # "logical"

벡터

R의 가장 기본적인 데이터 구조입니다. 같은 자료형의 값 여러 개를 하나로 묶습니다.

# 벡터 생성
scores <- c(85, 92, 78, 95, 88)

# 기본 연산 — 벡터 전체에 한 번에 적용됩니다
scores + 5        # 각 값에 5를 더함
scores * 2        # 각 값에 2를 곱함
scores > 80       # 각 값이 80보다 큰지 논리값으로 반환

# 인덱싱 — R은 1부터 시작합니다
scores[1]         # 첫 번째 값: 85
scores[2:4]       # 두 번째부터 네 번째: 92, 78, 95
scores[scores > 80] # 80보다 큰 값만 추출

# 벡터 길이
length(scores)    # 5

벡터에는 이름을 붙일 수도 있습니다.

grades <- c(국어=90, 영어=85, 수학=92)
grades["영어"]    # 85

데이터프레임

실제 분석에서 가장 많이 쓰는 구조입니다. 엑셀 시트처럼 행과 열로 이루어진 표입니다.

# 데이터프레임 생성
students <- data.frame(
  name   = c("김민준", "이서연", "박지호", "최수아"),
  score  = c(85, 92, 78, 95),
  grade  = c("B", "A", "C", "A"),
  passed = c(TRUE, TRUE, FALSE, TRUE)
)

# 구조 확인
str(students)
head(students)     # 처음 6행
nrow(students)     # 행 수: 4
ncol(students)     # 열 수: 4

# 열 접근
students$name      # name 열 전체
students[, "score"] # score 열 전체

# 행 접근
students[1, ]      # 첫 번째 행
students[students$passed == TRUE, ]  # passed가 TRUE인 행만

파이프 연산자

tidyverse에서 쓰는 %>%(magrittr 파이프)와 R 4.1부터 내장된 |>(네이티브 파이프)가 있습니다. 이 책에서는 두 가지를 모두 씁니다.

library(dplyr)

# 파이프 없이
result <- filter(students, passed == TRUE)
result <- select(result, name, score)

# 파이프 사용 — 왼쪽 결과를 오른쪽 함수의 첫 번째 인자로 넘깁니다
result <- students %>%
  filter(passed == TRUE) %>%
  select(name, score)

# 네이티브 파이프 (R 4.1+)
result <- students |>
  filter(passed == TRUE) |>
  select(name, score)

파이프는 "그러고 나서"라고 읽으면 됩니다. students %>% filter(...) %>% select(...) 는 "students를 받아서, 필터링하고, 열을 선택한다"입니다.

함수 작성

반복되는 작업은 함수로 만듭니다.

# 함수 정의
bmi <- function(weight, height_cm) {
  height_m <- height_cm / 100
  weight / height_m^2
}

# 호출
bmi(70, 175)   # 22.86

# 기본값 설정
greet <- function(name, greeting = "안녕하세요") {
  paste(greeting, name)
}

greet("홍길동")              # "안녕하세요 홍길동"
greet("홍길동", "반갑습니다") # "반갑습니다 홍길동"

조건문과 반복문

# if-else
x <- 75
if (x >= 90) {
  "A"
} else if (x >= 80) {
  "B"
} else {
  "C"
}

# ifelse — 벡터에 한 번에 적용할 수 있어 자주 씁니다
scores <- c(85, 92, 78, 95, 68)
ifelse(scores >= 80, "합격", "불합격")

# for 루프
total <- 0
for (i in 1:5) {
  total <- total + i
}
total  # 15

# while 루프
count <- 1
while (count <= 3) {
  cat(count, "번째\n")
  count <- count + 1
}

자주 쓰는 내장 함수

통계 분석에서 반복해서 만날 함수들입니다.

x <- c(3, 7, 2, 9, 4, 6, 1, 8, 5)

sum(x)       # 합계: 45
mean(x)      # 평균: 5
median(x)    # 중앙값: 5
min(x)       # 최솟값: 1
max(x)       # 최댓값: 9
range(x)     # 범위: 1 9
var(x)       # 분산
sd(x)        # 표준편차
sort(x)      # 정렬 (오름차순)
rev(sort(x)) # 정렬 (내림차순)

# 결측값 처리
y <- c(1, NA, 3, NA, 5)
mean(y)                # NA — 결측값이 있으면 결과도 NA
mean(y, na.rm = TRUE)  # 4 — na.rm=TRUE로 결측값 제외
is.na(y)               # FALSE TRUE FALSE TRUE FALSE
sum(is.na(y))          # 결측값 개수: 2

tidyverse 핵심 함수 미리보기

다음 챕터에서 자세히 다루지만, 자주 등장하는 dplyr 함수를 미리 훑어봅니다.

library(tidyverse)

# 예제 데이터
df <- data.frame(
  name  = c("김민준", "이서연", "박지호", "최수아", "정태양"),
  dept  = c("이공", "인문", "이공", "인문", "이공"),
  score = c(85, 92, 78, 95, 88),
  age   = c(20, 22, 21, 20, 23)
)

# filter — 행 조건 필터링
df %>% filter(dept == "이공")
df %>% filter(score >= 85, age < 22)

# select — 열 선택
df %>% select(name, score)
df %>% select(-age)           # age 열 제외

# mutate — 열 추가/변경
df %>% mutate(grade = ifelse(score >= 90, "A", "B"))

# arrange — 정렬
df %>% arrange(score)          # 오름차순
df %>% arrange(desc(score))    # 내림차순

# group_by + summarise — 그룹별 집계
df %>%
  group_by(dept) %>%
  summarise(
    mean_score = mean(score),
    count      = n()
  )

이 정도면 이 책을 따라가는 데 충분합니다. 모르는 함수가 나오면 ?함수명으로 도움말을 확인하세요. R의 도움말은 꽤 잘 정리되어 있습니다.