dplyr 기초 문법 이해하기

dplyr 필수함수 및 문법 익히기
dplyr
R
Published

February 1, 2023

R에서 가장 인기가 많은 패키지 중 하나를 꼽으라고 한다면 바로 dplyr 일 것입니다.

dplyr 는 데이터 핸들링 패키지 중 하나로, 아래의 작업을 빠르고 쉽게 도와줄 수 있습니다.

dplyr 패키지에 대해 설명하기 위해 starwars 데이터를 사용하도록 하겠습니다. 자세한 사항은 ?starwars 를 통해 확인할 수 있습니다.

library(dplyr)

starwars

starwarstibble 데이터 구조를 갖습니다. 이는 dplyr 로 데이터를 불러올 때의 데이터 구조입니다. tibbledata.frame과 동일한 구조이지만 다른 점이 존재합니다.

1. dplyr의 동사들

dplyr는 영어 단어 동사를 함수로 사용하여 데이터를 다루게 됩니다. 이 함수들은 크게 세 가지로 나누어 볼 수 있습니다.

  • 행 (Rows)

    • filter() : 열을 기준으로 조건에 맞는 행들을 선택합니다.
    • slice() : 위치를 기준으로 행들을 선택합니다.
    • arrange() : 행의 순서를 변경합니다.
  • 열 (Columns)

    • select() : 특정 열을 선택합니다.
    • rename() : 열의 이름을 변경합니다.
    • mutate() : 새로운 열을 추가합니다.
    • relocate() : 열의 순서를 변경합니다.
  • 행 요약

    • summarise() : 여러 행을 계산합니다.

2. Pipe 구조

모든 dplyr의 함수는 분석하고자 하는 데이터(tibble)을 첫 번째 인자로 받습니다. dplyr에서는 f(x,y) 구조 보다는 x %>% f(y) 형태로 입력합니다. 이 때 %>% 또는|>파이프(pipe) 연산자라고 합니다. 파이프 연산자를 여러 번 사용하여 여러 함수를 이어서 실행할 수 있습니다.


3. filter() 행 선택하기

filter()는 데이터에서 일부 행들을 선택하는 함수입니다. filter() 안에는 찾고자 하는 조건이 TRUE인 행들만 선택이 되게 됩니다.

예를 들어, starwars 데이터에서 skin_color가 light이고 eye_color가 brown인 경우를 찾을 때는

starwars |> filter(skin_color=='light',
                   eye_color=='brown')

이는 기본 R 코드에서 다음과 같이 구현할 수 있습니다.

starwars[starwars$skin_color=='light' & starwars$eye_color=='brown',]

dplyr 를 이용하면, 불필요하게 데이터$변수 를 반복해서 사용할 필요가 없겠죠.

4. arrange(): 행 순서 정렬하기

arrange()filter()와 동일하게 행을 다루는 함수입니다. 다만 arrange()는 다루는 데이터의 행을 정렬합니다.

만약 두 가지 이상의 열 이름을 제공하는 경우, 첫 번째 열에서 같은 값이 나왔을 때, 추가적으로 행을 정렬하는 기준이 정해지게 됩니다.

starwars |> arrange(height)

위의 정렬된 결과를 보면 R2-D2와 R4-P17의 키가 동일한 것을 알 수 있습니다. 이처럼 동일한 값이 오는 경우, arrange()에 하나의 값을 더 추가함으로써 추가적인 정렬 기준을 세우는 것입니다.

starwars |> arrange(height, mass)

height를 기준으로 오름차순이 되었고, height가 같은 경우, mass가 작은 값부터 오게끔 정렬되었습니다.

만약 내림차순으로 데이터를 정렬하고 싶은 경우는 desc() 를 함께 사용하면 됩니다.

starwars |> arrange(desc(height))

5. slice(): 행의 위치를 통한 행 선택

slice()는 행의 번호(index)를 통해 행들을 선택합니다.

starwars |> slice(5:10)

slice() 계열의 함수들은 다음과 같습니다.

  • slice_head(), slice_tail(): 각각 데이터의 첫 ~행, 마지막 ~행을 선택할 수 있습니다.

    starwars |> slice_head(n=5)
    starwars |> slice_tail(n=3)
  • slice_sample(): 무작위로 행을 선택합니다. n을 통해 행의 개수를 선택하거나, prop 옵션을 통해 특정 비율만큼 행을 선택할 수 있습니다.

    starwars |> slice_sample(n=10)
    starwars |> slice_sample(prop = 0.1)

    replace=T를 통해 복원추출을 수행할 수 있습니다.

  • slice_min(), slice_max()를 통해 특정 열의 가장 높거나 가장 낮은 값을 갖는 행을 선택할 수 있습니다.

    starwars |> slice_max(height,n=3)

6. select(): 열 선택하기

큰 데이터를 다루게 될 경우, 많은 열이 존재하기 마련입니다. 이 중 분석하고자 하는 일부의 열만 선택할 수 있도록 도와주는 함수가 바로 select()입니다.

starwars |> select(hair_color, skin_color, eye_color)

만약 열들이 붙어 있다면 :을 이용해 한번에 출력할 수도 있습니다.

starwars |> select(hair_color:eye_color)

또한 select() 안에서 열 이름이 갖는 규칙을 활용하여, 특정 규칙만을 갖는 열만 선택할 수 있습니다.

  • starts_with() : 특정한 값으로 시작하는 열 이름 찾기

    starwars |> select(starts_with('hair'))
  • ends_with() : 특정한 값으로 끝나는 열 이름 찾기

    starwars |> select(ends_with('hair'))
  • matches() : 정규 표현식을 통한 열 이름 찾기

    starwars |> select(matches('^[a-z]{4}_'))
  • contains() :특정한 문자가 포함된 열 이름 찾기

    starwars |> select(contains('_'))
  • num_range() : 특정 숫자범위를 갖는 열 이름 찾기

    num_range() 함수를 설명하기 위해 tidyr 패키지에 있는 billboard 데이터를 사용하겠습니다.

    library(tidyr)
    billboard |> select(num_range('wk',1:10))

7. rename(): 열 이름 변경

select()문을 이용해 원하는 이름으로 열을 출력할 수도 있습니다.

starwars |> select(home_world=homeworld)

그러나 select()는 선택된 열 이외에 다른 열들은 모두 버리기 때문에, rename()을 이용해 열 이름을 변경해줄 수 있습니다.

# rename(new = old)
starwars |> rename(home_world = homeworld)

8. mutate(): 새로운 열 추가하기

starwars |> mutate(height_m = height / 100)

tibble 특성 상 새롭게 만든 열이 바로 보이지 않지만, select()를 이용해 출력할 수 있습니다.

starwars |>
  mutate(height_m = height / 100) %>%
  select(height_m, height, everything())

mutate() 안에서 새롭게 만든 열도 접근이 가능합니다.

starwars |> 
  mutate(
    height_m = height / 100,
    BMI = mass / (height_m^2)
  ) %>%
  select(BMI, everything())

만약 기존의 열은 없애고 새로운 열만 남기고 싶다면, transmute() 를 이용할 수 있습니다.

starwars |>
  transmute(
    height_m = height / 100,
    BMI = mass / (height_m^2)
  )

9. relocate(): 순서 변경

relocate()는 옮길 열들과, 옮길 위치를 지정해주면 됩니다.

# .before or .after
starwars |> relocate(sex:homeworld, # 옮길 열들
                    .before = height # 옮길 위치
                    )

10. summarise(), summarize(): 요약

summarise() 는 하나의 열에 대해 평균, 표준편차, 중앙값 등으로 요약하기 위해 함께 사용되는 함수입니다.

starwars |> summarise(height = mean(height, na.rm = TRUE))

dplyr%>%(또는 |>)를 사용하여 출력했을 때, 출력된 값이 저장되지 않습니다. 즉 분석하는 데이터에는 변경사항이 없습니다. 만약 새로운 열을 추가하거나 이름을 변경할 때, 또는 계산한 값을 저장하기 위해서는 <- 를 이용해 데이터에 저장하거나 새로운 값으로 선언해야 합니다.

starwars2 <- starwars %>%
  group_by(species, sex) %>%
  select(height, mass) %>%
  summarise(
    height = mean(height, na.rm = TRUE),
    mass = mean(mass, na.rm = TRUE)
  )

# starwars2에는 group_by 후 summarise한 값만 존재
starwars2

Reference

  • https://dplyr.tidyverse.org/articles/dplyr.html
Back to top