변수와 데이터 타입
R을 처음 열었을 때 가장 먼저 마주치는 것이 <-입니다. 다른 언어에서 =로 값을 저장하던 것과 달리, R은 화살표로 값을 "담는다"는 느낌을 줍니다. 작은 차이지만, R이 어떤 사고방식을 가진 언어인지 처음부터 보여주는 상징 같습니다.
할당 연산자
R에서 변수에 값을 저장할 때는 <-를 씁니다.
# 파일: 01_basics.R
x <- 42
name <- "Alice"
is_student <- TRUE
=도 동작하지만, R 커뮤니티의 관례는 <-입니다. 코드를 공유하거나 패키지를 만들 때 <-를 쓰는 것이 자연스럽게 받아들여집니다.
변수 이름은 점(.)과 언더스코어(_) 모두 쓸 수 있습니다. my.data나 my_data 모두 유효한 이름입니다. 단, 숫자로 시작할 수는 없습니다.
my.data <- 100 # 점 사용 가능
my_data <- 200 # 언더스코어 사용 가능
.hidden <- 300 # 점으로 시작 가능 (숨김 변수)
numeric — 숫자
R에서 숫자는 기본적으로 실수(double)로 저장됩니다. 정수임을 명시하려면 뒤에 L을 붙입니다.
height <- 175.5 # 실수 (double)
age <- 30L # 정수 (integer)
big_num <- 1e6 # 100만 (과학적 표기)
class(height) # "numeric"
class(age) # "integer"
is.numeric(height) # TRUE
is.integer(age) # TRUE
class() 함수는 변수의 타입을 알려줍니다. is.numeric()은 정수와 실수를 모두 TRUE로 반환합니다. 정수만 확인하고 싶다면 is.integer()를 씁니다.
character — 문자열
큰따옴표나 작은따옴표로 감쌉니다. 두 방식 모두 동일하게 동작합니다.
city <- "서울"
greeting <- '안녕하세요'
class(city) # "character"
nchar(city) # 2 (글자 수)
toupper("hello") # "HELLO"
paste("Hello", "R") # "Hello R"
paste0("R", "4.4") # "R4.4"
paste()는 여러 문자열을 이어 붙입니다. 기본적으로 공백으로 구분하며, paste0()은 구분자 없이 붙입니다.
logical — 논리값
TRUE와 FALSE입니다. 대소문자를 정확히 써야 합니다. T와 F도 동작하지만, 누군가 T <- 0처럼 덮어쓸 수 있어 권장하지 않습니다.
is_pass <- TRUE
is_fail <- FALSE
class(is_pass) # "logical"
is.logical(is_pass) # TRUE
# 비교 결과도 logical
10 > 5 # TRUE
"a" == "b" # FALSE
논리값은 숫자처럼 쓸 수도 있습니다. TRUE는 1, FALSE는 0으로 처리됩니다. 이 특성은 데이터 분석에서 자주 활용됩니다.
sum(c(TRUE, FALSE, TRUE, TRUE)) # 3 — TRUE 개수를 셀 수 있음
mean(c(TRUE, FALSE, TRUE, TRUE)) # 0.75 — TRUE 비율
factor — 범주형 데이터
factor는 R만의 독특한 데이터 타입입니다. 성별, 학년, 지역처럼 정해진 범주 안에서만 값을 가지는 데이터를 표현할 때 씁니다.
gender <- factor(c("남", "여", "남", "남", "여"))
grade <- factor(c("A", "B", "C", "A"), levels = c("A", "B", "C", "D", "F"))
class(gender) # "factor"
levels(gender) # "남" "여"
nlevels(gender) # 2
table(gender) # 빈도표
# gender
# 남 여
# 3 2
levels 인자로 가능한 값을 미리 지정할 수 있습니다. 이렇게 하면 데이터에 없는 범주도 레벨로 유지됩니다.
순서가 있는 범주라면 ordered = TRUE를 씁니다.
satisfaction <- factor(
c("보통", "만족", "불만족", "매우 만족"),
levels = c("불만족", "보통", "만족", "매우 만족"),
ordered = TRUE
)
satisfaction[1] < satisfaction[2] # TRUE — 순서 비교 가능
특수값 — NA, NULL, NaN, Inf
R은 결측값과 특수 상황을 나타내는 값을 따로 가집니다.
# NA — 결측값 (Not Available)
score <- NA
is.na(score) # TRUE
# NULL — 빈 객체
empty <- NULL
is.null(empty) # TRUE
length(empty) # 0
# NaN — 숫자가 아님 (Not a Number)
result <- 0 / 0 # NaN
is.nan(result) # TRUE
# Inf — 무한대
big <- 1 / 0 # Inf
is.infinite(big) # TRUE
데이터 분석에서 NA는 자주 만나게 됩니다. NA가 포함된 계산은 대부분 NA를 반환하므로, 제거하거나 따로 처리하는 방법을 알아야 합니다.
scores <- c(85, NA, 92, NA, 78)
mean(scores) # NA — NA 때문에 계산 불가
mean(scores, na.rm = TRUE) # 85 — NA를 제외하고 계산
타입 변환
타입 간 변환은 as.*() 함수를 씁니다.
as.numeric("3.14") # 3.14
as.integer(3.7) # 3 — 소수점 버림
as.character(100) # "100"
as.logical(0) # FALSE
as.logical(1) # TRUE
# 변환 불가 시 NA 반환 + 경고
as.numeric("hello") # NA
typeof()와 class()의 차이
class()는 R이 객체를 어떻게 다루는지 알려주고, typeof()는 실제 저장 방식을 알려줍니다.
x <- 42L
class(x) # "integer"
typeof(x) # "integer"
y <- 42.0
class(y) # "numeric"
typeof(y) # "double"
z <- TRUE
class(z) # "logical"
typeof(z) # "logical"
일상적인 분석에서는 class()를 더 많이 씁니다. 타입이 헷갈릴 때 class()를 먼저 확인하는 것이 좋습니다.