[R 기초] 8. 데이터 전처리

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

실제 분석 데이터를 불러와서 R에서 확인하고, 필터링하고, 저장하는 전처리 흐름을 정리합니다.


데이터 불러오기

read.csv()

쉼표로 구분된 CSV 파일을 읽습니다.

df <- read.csv("data.csv")

# 주요 옵션
df <- read.csv("data.csv",
               header      = TRUE,     # 첫 줄을 열 이름으로 사용 (기본값)
               stringsAsFactors = FALSE, # 문자열을 팩터로 변환하지 않음
               na.strings  = c("", "NA", "N/A"),  # NA로 처리할 값 지정
               encoding    = "UTF-8")  # 인코딩 지정

read.table()

구분자를 직접 지정할 수 있는 범용 함수입니다.

read.csv()도 내부적으로 read.table()을 사용합니다.

df <- read.table("data.txt", header = TRUE, sep = "\t")
df <- read.table("data.csv", header = TRUE, sep = ",")

read.delim()

탭으로 구분된 파일을 읽는 데 특화된 함수입니다.

df <- read.delim("data.tsv")              # 기본 구분자: 탭
df <- read.delim("data.tsv", dec = ",")   # 소수점 구분자 지정

세 함수의 차이는 기본 구분자와 기본 옵션 값의 차이입니다.

보통 CSV는 read.csv(), TSV는 read.delim(), 그 외는 read.table()로 구분해서 씁니다.


데이터 확인

일부 확인

head(df)        # 상위 6행 (기본값)
head(df, 10)    # 상위 10행
tail(df, 3)     # 하위 3행
View(df)        # RStudio에서 스프레드시트 형태로 보기

 

View()는 RStudio에서만 동작합니다.

스크립트에 넣어두면 실행 시마다 창이 열리므로 주로 대화형으로 탐색할 때만 사용합니다.

구조와 개요 확인

str(df)        # 각 열의 타입과 첫 몇 개 값
summary(df)    # 수치형: 최솟값/최댓값/평균/분위수, 문자형: 빈도
dim(df)        # c(행 수, 열 수)
nrow(df)       # 행 수
ncol(df)       # 열 수

데이터를 처음 받았을 때 str()과 summary()를 같이 실행해보는 것이 기본 습관입니다. str()은 각 열의 타입이 예상과 다르게 읽힌 경우를 찾는 데 유용하고, summary()는 이상값이나 결측값을 빠르게 파악하는 데 유용합니다.


칼럼명 확인/변경

colnames(df)           # 열 이름 확인
names(df)              # 동일

colnames(df)[2] <- "coverage"               # 특정 열 이름 변경
names(df)[names(df) == "old_name"] <- "new_name"   # 이름으로 지정해서 변경
colnames(df) <- c("id", "cov", "gc")       # 전체 이름 변경

 


기본 시각화 실습

base R의 시각화 함수입니다.

ggplot2보다 간단하고 빠르게 데이터를 훑어볼 때 유용합니다.

plot(): 산점도

x <- c(1, 2, 3, 4, 5)
y <- c(2, 4, 3, 5, 4)

plot(x, y)
plot(x, y,
     main = "제목",
     xlab = "x축 이름",
     ylab = "y축 이름",
     col  = "blue",
     pch  = 16)    # pch: 점 모양 (16 = 채워진 원)

 

데이터프레임의 열을 직접 지정할 수 있습니다.

plot(df$coverage, df$gc)

hist(): 히스토그램

hist(df$coverage)
hist(df$coverage,
     breaks = 20,       # 구간 수
     main   = "Coverage Distribution",
     xlab   = "Coverage",
     col    = "steelblue")

boxplot(): 박스플롯

boxplot(df$coverage)

# 그룹별 비교
boxplot(coverage ~ group, data = df,
        main = "Coverage by Group",
        xlab = "Group",
        ylab = "Coverage")

 

formula 형태(열 ~ 그룹)로 그룹별 비교를 간단하게 그릴 수 있습니다.


조건으로 필터링

[] 조건 인덱싱

df <- data.frame(
    id       = c("s01", "s02", "s03", "s04"),
    coverage = c(30.5, 18.2, 45.8, 22.1),
    gc       = c(0.51, 0.49, 0.52, 0.48)
)

df[df$coverage >= 30, ]              # coverage 30 이상인 행
df[df$gc > 0.5 & df$coverage >= 20, ]   # 두 조건 동시 적용
df[df$id %in% c("s01", "s03"), ]    # 특정 ID만

subset()

조건 필터링과 열 선택을 함께 할 수 있어 코드가 좀 더 읽기 쉽습니다.

subset(df, coverage >= 30)                      # coverage 30 이상
subset(df, coverage >= 20 & gc > 0.5)          # 두 조건
subset(df, coverage >= 20, select = c(id, gc)) # 조건 + 열 선택
subset(df, coverage >= 20, select = -gc)        # gc 열 제외

 

subset()은 대화형으로 탐색할 때 편하지만, 함수 내부에서 사용하면 예상치 못한 동작이 생길 수 있습니다.

함수 안에서는 [] 인덱싱을 사용하는 것이 더 안전합니다.


결측값 처리

결측값 확인

df <- data.frame(
    id  = c("s01", "s02", "s03", "s04"),
    cov = c(30.5, NA, 45.8, 22.1),
    gc  = c(0.51, 0.49, NA, 0.48)
)

is.na(df)              # 각 셀의 결측 여부
colSums(is.na(df))     # 열별 결측값 수
sum(is.na(df))         # 전체 결측값 수

na.omit()

결측값이 하나라도 있는 행을 모두 제거합니다.

df_clean <- na.omit(df)

complete.cases()

각 행이 완전한지(결측값 없는지) 논리 벡터로 반환합니다.

complete.cases(df)    # TRUE FALSE FALSE TRUE

df[complete.cases(df), ]    # 결측값 없는 행만 추출
df[!complete.cases(df), ]   # 결측값 있는 행만 추출

na.omit(df)와 df[complete.cases(df), ]는 동일한 결과를 냅니다.

어떤 행에 결측값이 있는지 먼저 확인하고 싶을 때는 complete.cases()를 사용합니다.

결측값 대체

df$cov[is.na(df$cov)] <- mean(df$cov, na.rm = TRUE)  # 평균으로 대체
df$cov[is.na(df$cov)] <- 0                             # 0으로 대체

데이터 정렬

sort(): 벡터 정렬

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

sort(x)                  # 오름차순: 1 1 2 3 4 5 9
sort(x, decreasing = TRUE)  # 내림차순: 9 5 4 3 2 1 1

order(): 정렬 인덱스 반환

데이터프레임 행 정렬에 사용합니다.

sort()와 달리 값이 아닌 인덱스를 반환합니다.

x <- c(30.5, 18.2, 45.8, 22.1)
order(x)                    # 2 4 1 3  (값이 작은 순서의 인덱스)
order(x, decreasing = TRUE) # 3 1 4 2

# 데이터프레임 행 정렬
df[order(df$coverage), ]              # coverage 오름차순
df[order(df$coverage, decreasing = TRUE), ]  # 내림차순

# 여러 열 기준 정렬
df[order(df$gc, df$coverage), ]      # gc 먼저, 같으면 coverage 기준

데이터 저장

write.csv()

write.csv(df, "output.csv")                         # 행 번호 포함
write.csv(df, "output.csv", row.names = FALSE)      # 행 번호 제외 (권장)
write.csv(df, "output.csv", row.names = FALSE, fileEncoding = "UTF-8")

row.names = FALSE를 지정하지 않으면 첫 번째 열에 행 번호(1, 2, 3, ...)가 추가됩니다.

대부분의 경우 필요 없으므로 FALSE로 지정하는 것이 일반적입니다.

write.table()

구분자를 직접 지정할 수 있습니다.

TSV로 저장할 때 사용합니다.

write.table(df, "output.tsv",
            sep       = "\t",
            row.names = FALSE,
            quote     = FALSE)     # 문자열에 따옴표 추가하지 않음

quote = FALSE를 지정하지 않으면 문자열 열에 큰따옴표가 붙어서 저장됩니다.

다른 도구로 읽을 때 문제가 생길 수 있어서 TSV 저장 시 보통 FALSE로 지정합니다.

'BI&Programming-Tools > R' 카테고리의 다른 글

[R 기초] 10. ggplot2 시각화 기초  (0) 2026.06.30
[R 기초] 9. Tidyverse  (0) 2026.06.29
[R 기초] 7. 제어문과 함수  (0) 2026.06.29
[R 기초] 6. 데이터 구조 (행렬, 데이터프레임)  (0) 2026.06.28
[R 기초] 5. 데이터 구조 (벡터, 팩터, 리스트)  (0) 2026.06.28
'BI&Programming-Tools/R' 카테고리의 다른 글
  • [R 기초] 10. ggplot2 시각화 기초
  • [R 기초] 9. Tidyverse
  • [R 기초] 7. 제어문과 함수
  • [R 기초] 6. 데이터 구조 (행렬, 데이터프레임)
데이터로 읽는 생명
데이터로 읽는 생명
is-note 님의 블로그 입니다.
  • 데이터로 읽는 생명
    In Silico Note
    데이터로 읽는 생명
  • 전체
    오늘
    어제
    • 분류 전체보기 (190) N
      • 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) N
        • 서열분석개론 (6)
        • WGS(Whole Genome Seq) (11)
        • WES(Whole Exome Seq) (2)
        • RNA-Seq (4) N
        • Metagenome (2)
        • Non-human Resequencing (1)
        • 임상유전체 분석 (1)
        • Multi-Omics (1)
      • Bio-Trends & Tech (1)
      • 코딩테스트 연습 (30)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
데이터로 읽는 생명
[R 기초] 8. 데이터 전처리
상단으로

티스토리툴바