조건문
if / else if / else
x <- 25
if (x >= 30) {
print("high coverage")
} else if (x >= 20) {
print("moderate coverage")
} else {
print("low coverage")
}
# "moderate coverage"
조건식은 반드시 단일 논리값이어야 합니다.
벡터를 조건에 넣으면 첫 번째 원소만 사용되고 경고가 발생합니다.
x <- c(10, 30)
if (x > 20) print("ok") # 경고: x[1]만 사용됨
R에서 if 블록은 값을 반환합니다.
변수에 바로 할당할 수 있습니다.
status <- if (x >= 30) "high" else "low"
ifelse()
벡터 단위로 조건을 처리할 때 사용합니다.
x <- c(30.5, 18.2, 45.8, 22.1)
ifelse(x >= 30, "high", "low")
# "high" "low" "high" "low"
if/else는 단일 조건, ifelse()는 벡터 조건으로 구분해서 사용합니다.
for 반복문
for (i in 1:5) {
print(i)
}
# 1 2 3 4 5
in 뒤에는 벡터, 리스트 등 반복 가능한 객체가 올 수 있습니다.
genes <- c("BRCA1", "TP53", "EGFR")
for (gene in genes) {
print(paste("Processing:", gene))
}
next, break
for (i in 1:10) {
if (i %% 2 == 0) next # 짝수면 건너뜀
if (i > 7) break # 7 초과면 종료
print(i)
}
# 1 3 5 7
next는 파이썬의 continue, break는 동일하게 break에 해당합니다.
결과를 저장하는 패턴
반복문에서 결과를 모을 때는 미리 빈 벡터를 만들어두고 채워나가는 방식이 일반적입니다.
result <- c()
for (i in 1:5) {
result <- c(result, i^2)
}
result # 1 4 9 16 25
다만 이 방식은 반복마다 벡터를 새로 생성해서 느립니다.
크기를 미리 지정한 벡터에 값을 채우는 방식이 더 효율적입니다.
result <- numeric(5) # 길이 5의 빈 수치 벡터
for (i in 1:5) {
result[i] <- i^2
}
result # 1 4 9 16 25
while 반복문
조건이 TRUE인 동안 반복합니다.
x <- 1
while (x <= 5) {
print(x)
x <- x + 1
}
# 1 2 3 4 5
repeat
조건 없이 무한 반복합니다.
반드시 내부에 break 조건이 있어야 합니다.
x <- 1
repeat {
print(x)
x <- x + 1
if (x > 5) break
}
# 1 2 3 4 5
while (TRUE) 와 동일한 효과이지만, 루프를 최소 한 번은 실행하고 조건을 나중에 확인하는 구조가 필요할 때 repeat을 사용하기도 합니다.
함수 정의
함수명 <- function(인자1, 인자2) {
# 실행할 코드
return(결과)
}
calc_gc <- function(seq) {
g <- nchar(gsub("[^G]", "", seq))
c <- nchar(gsub("[^C]", "", seq))
return((g + c) / nchar(seq))
}
calc_gc("ATCGATCGGGCC") # 0.5833...
기본값 인자
filter_coverage <- function(x, threshold = 20) {
x[x >= threshold]
}
filter_coverage(c(15, 30, 22, 10, 45)) # 30 22 45 (기본값 사용)
filter_coverage(c(15, 30, 22, 10, 45), threshold = 25) # 30 45
return()
R에서 return()을 명시하지 않으면 마지막으로 평가된 값이 자동으로 반환됩니다.
add <- function(a, b) {
a + b # return() 없이도 반환됨
}
add(3, 5) # 8
return()은 함수 중간에 조기 반환할 때 명시적으로 사용합니다.
safe_log <- function(x) {
if (x <= 0) return(NA)
log(x)
}
safe_log(-1) # NA
safe_log(10) # 2.302...
여러 값 반환
R의 함수는 하나의 객체만 반환합니다.
여러 값을 반환하려면 리스트로 묶어서 반환합니다.
get_stats <- function(x) {
list(
mean = mean(x),
sd = sd(x),
median = median(x)
)
}
result <- get_stats(c(3, 7, 1, 9, 4))
result$mean # 4.8
result$sd # 3.03...
적용 함수 (apply 계열)
R에서 반복 처리를 할 때 for 대신 apply 계열 함수를 사용하는 경우가 많습니다.
apply(): 행렬이나 데이터프레임에 함수 적용
m <- matrix(1:12, nrow = 3)
apply(m, 1, sum) # 각 행의 합: 22 26 30
apply(m, 2, sum) # 각 열의 합: 6 15 24 33
apply(m, 1, mean) # 각 행의 평균
apply(m, 2, max) # 각 열의 최댓값
1은 행 방향, 2는 열 방향으로 함수를 적용합니다.
lapply(): 리스트나 벡터에 함수 적용 → 리스트 반환
x <- list(a = 1:5, b = 6:10, c = 11:15)
lapply(x, mean)
# $a: 3
# $b: 8
# $c: 13
항상 리스트를 반환합니다.
sapply(): lapply()와 동일하지만 가능하면 벡터/행렬로 단순화
sapply(x, mean)
# a b c
# 3 8 13
결과가 모두 길이 1인 값이면 벡터로, 모두 같은 길이의 벡터면 행렬로 반환합니다.
결과 타입이 달라지거나 불확실할 때는 lapply()를 사용하는 것이 더 안전합니다.
익명 함수와 함께 사용
# 각 원소를 제곱한 뒤 합산
sapply(1:5, function(x) x^2)
# 1 4 9 16 25
# 데이터프레임의 수치형 열에 적용
df <- data.frame(a = 1:5, b = 6:10, c = 11:15)
sapply(df, mean)
# a b c
# 3 8 13
sapply(1:5, \(x) x^2) # R 4.1 이상
apply 계열 비교
| 함수 | 입력 | 반환 | 주요 용도 |
| apply() | 행렬, 데이터프레임 | 벡터, 행렬 | 행/열 단위 연산 |
| lapply() | 리스트, 벡터 | 리스트 | 원소별 함수 적용 |
| sapply() | 리스트, 벡터 | 벡터, 행렬 | lapply() + 단순화 |
'BI&Programming-Tools > R' 카테고리의 다른 글
| [R 기초] 9. Tidyverse (0) | 2026.06.29 |
|---|---|
| [R 기초] 8. 데이터 전처리 (0) | 2026.06.29 |
| [R 기초] 6. 데이터 구조 (행렬, 데이터프레임) (0) | 2026.06.28 |
| [R 기초] 5. 데이터 구조 (벡터, 팩터, 리스트) (0) | 2026.06.28 |
| [R 기초] 4. 논리형과 결측값 (0) | 2026.06.28 |
