iBetter Books
수정

Ch 03. 행 필터링과 열 선택 (filter, select)

데이터를 분석할 때 전체를 한꺼번에 다루는 경우는 많지 않습니다. 특정 조건에 맞는 행만 골라내거나, 필요한 열만 추려서 작업합니다. dplyr는 이 두 가지 작업에 filter()select()를 제공합니다.

ggplot2에 내장된 mpg 데이터셋으로 실습합니다. 자동차 연비 데이터입니다.

library(tidyverse)

mpg
# A tibble: 234 × 11
   manufacturer model      displ  year   cyl trans      drv     cty   hwy fl    class  
   <chr>        <chr>      <dbl> <int> <int> <chr>      <chr> <int> <int> <chr> <chr>  
 1 audi         a4           1.8  1999     4 auto(l5)   f        18    29 p     compact
 2 audi         a4           1.8  1999     4 manual(m5) f        21    29 p     compact
...

234행 11열입니다. manufacturer(제조사), model(모델명), displ(배기량), cty(시내 연비), hwy(고속도로 연비), class(차종) 등의 열이 있습니다.

filter()로 행 골라내기

특정 조건에 맞는 행만 남기려면 filter()를 사용합니다.

# 제조사가 "toyota"인 차량만
filter(mpg, manufacturer == "toyota")
# A tibble: 34 × 11
   manufacturer model      displ  year   cyl trans      drv     cty   hwy fl    class  
   <chr>        <chr>      <dbl> <int> <int> <chr>      <chr> <int> <int> <chr> <chr>  
 1 toyota       4runner 4wd  2.7  1999     4 manual(m5) 4        15    20 r     suv    
...

파이프 연산자 %>%

dplyr 함수들은 파이프 연산자 %>%와 함께 쓸 때 더욱 강력합니다. %>%는 왼쪽 결과를 오른쪽 함수의 첫 번째 인수로 넘깁니다.

mpg %>% filter(manufacturer == "toyota")

결과는 동일합니다. 그런데 여러 단계를 연결할 때 코드가 훨씬 읽기 쉬워집니다. R 4.1부터는 기본 파이프 |>도 사용할 수 있습니다. 이 교재에서는 tidyverse의 %>%를 기준으로 설명합니다.

비교 연산자

filter() 안에서 사용할 수 있는 비교 연산자입니다.

연산자 의미
== 같다
!= 같지 않다
>, >= 크다, 크거나 같다
<, <= 작다, 작거나 같다
%in% 벡터 안에 포함된다
# 고속도로 연비가 30 이상인 차량
mpg %>% filter(hwy >= 30)

# 2008년식 차량
mpg %>% filter(year == 2008)

# SUV가 아닌 차량
mpg %>% filter(class != "suv")

조건 조합: & 와 |

두 가지 이상의 조건을 조합합니다. &는 AND(모두 만족), |는 OR(하나라도 만족)입니다.

# toyota이면서 고속도로 연비 30 이상
mpg %>% filter(manufacturer == "toyota" & hwy >= 30)
# A tibble: 7 × 11
  manufacturer model  displ  year   cyl trans      drv     cty   hwy fl    class  
  <chr>        <chr>  <dbl> <int> <int> <chr>      <chr> <int> <int> <chr> <chr>  
1 toyota       camry    2.2  1999     4 manual(m5) f        21    29 r     midsize
...
# honda 또는 toyota
mpg %>% filter(manufacturer == "honda" | manufacturer == "toyota")

# %in%으로 같은 표현
mpg %>% filter(manufacturer %in% c("honda", "toyota"))

%in%은 여러 값 중 하나라도 일치하면 선택합니다. 같은 열에 대한 OR 조건을 간결하게 씁니다.

# compact, subcompact, midsize 차량
mpg %>% filter(class %in% c("compact", "subcompact", "midsize"))

filter() 안에 여러 조건 나열

filter() 안에 조건을 쉼표로 나열하면 AND로 처리됩니다.

# 아래 두 코드는 동일
mpg %>% filter(manufacturer == "toyota", hwy >= 30)
mpg %>% filter(manufacturer == "toyota" & hwy >= 30)

select()로 열 선택하기

필요한 열만 남기려면 select()를 사용합니다.

# 세 개 열만 선택
mpg %>% select(manufacturer, model, hwy)
# A tibble: 234 × 3
   manufacturer model      hwy
   <chr>        <chr>    <int>
 1 audi         a4          29
 2 audi         a4          29
...

열을 제외할 때는 앞에 -를 붙입니다.

# fl 열 제외
mpg %>% select(-fl)

# 여러 열 제외
mpg %>% select(-fl, -trans)

열 이름 규칙으로 선택하기

열이 많을 때는 이름 패턴으로 선택합니다.

# "m"으로 시작하는 열
mpg %>% select(starts_with("m"))

# "l"로 끝나는 열
mpg %>% select(ends_with("l"))

# 이름에 "a"가 포함된 열
mpg %>% select(contains("a"))

# 특정 범위의 열 (manufacturer부터 cyl까지)
mpg %>% select(manufacturer:cyl)

열 이름 바꾸기

select() 안에서 새이름 = 기존이름 형식으로 이름을 바꿀 수 있습니다.

mpg %>% select(제조사 = manufacturer, 모델 = model, 고속연비 = hwy)

이름만 바꾸고 나머지 열은 그대로 유지하려면 rename()을 씁니다.

mpg %>% rename(제조사 = manufacturer, 모델 = model)

slice()로 행 번호 선택하기

특정 행 번호로 선택할 때는 slice()를 사용합니다.

# 1~5번째 행
mpg %>% slice(1:5)

# 마지막 3행
mpg %>% slice_tail(n = 3)

# 처음 5행
mpg %>% slice_head(n = 5)

# 무작위 5행 추출
mpg %>% slice_sample(n = 5)

# hwy 기준 상위 5개
mpg %>% slice_max(hwy, n = 5)

# hwy 기준 하위 5개
mpg %>% slice_min(hwy, n = 5)

filter와 select 함께 쓰기

파이프로 연결하면 원하는 데이터를 정확히 추출합니다.

mpg %>%
  filter(class == "compact", year == 2008) %>%
  select(manufacturer, model, cty, hwy)
# A tibble: 20 × 4
   manufacturer model       cty   hwy
   <chr>        <chr>     <int> <int>
 1 audi         a4           18    29
 2 audi         a4           21    30
...

2008년식 소형차의 제조사, 모델, 연비만 한눈에 볼 수 있습니다. 파이프로 이어진 코드는 "compact이고 2008년식인 데이터에서 제조사, 모델, 도심·고속 연비를 골라낸다"고 읽히듯이 자연스럽습니다.

이제 데이터에서 원하는 부분을 자유롭게 꺼낼 수 있게 되었습니다. 다음은 결측치와 이상치를 처리하는 방법입니다. 실무 데이터에서 피할 수 없는 문제입니다.