[R 기초] 7. 제어문과 함수

2026. 6. 29. 18:00·BI&Programming-Tools/R

조건문

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
'BI&Programming-Tools/R' 카테고리의 다른 글
  • [R 기초] 9. Tidyverse
  • [R 기초] 8. 데이터 전처리
  • [R 기초] 6. 데이터 구조 (행렬, 데이터프레임)
  • [R 기초] 5. 데이터 구조 (벡터, 팩터, 리스트)
데이터로 읽는 생명
데이터로 읽는 생명
is-note 님의 블로그 입니다.
  • 데이터로 읽는 생명
    In Silico Note
    데이터로 읽는 생명
  • 전체
    오늘
    어제
    • 분류 전체보기 (190)
      • Bio-Knowledge (16)
        • 분자생물학 & 유전학 기초 (0)
        • 전사체학 & 유전자 발현 (0)
        • 구조생물학 & 단백질 (0)
        • 싱글셀 & 다중오믹스 (0)
        • 임상유전학 & 질환 데이터 (0)
      • Programming (4)
        • API (4)
      • BI&Programming-Tools (111)
        • File Formats (14)
        • Linux & Bash Script (38)
        • Python (35)
        • R (11)
        • 통계 (8)
        • Pipeline Manager (0)
        • Etc (5)
      • Bio Data Analysis (28)
        • 서열분석개론 (6)
        • WGS(Whole Genome Seq) (11)
        • WES(Whole Exome Seq) (2)
        • RNA-Seq (4)
        • Metagenome (2)
        • Non-human Resequencing (1)
        • 임상유전체 분석 (1)
        • Multi-Omics (1)
      • Bio-Trends & Tech (1)
      • 코딩테스트 연습 (30)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    통계
    유전체분석
    ngs
    FASTQ
    파일포맷
    GATK
    코딩테스트
    데이터분석
    리눅스기초
    fasta
    파이썬기초
    생물정보학
    R
    R기초
    wgs
    리눅스
    bioinformatics
    분자생물학
    파이썬연습
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
데이터로 읽는 생명
[R 기초] 7. 제어문과 함수
상단으로

티스토리툴바