library(dplyr)
starwars
R에서 가장 인기가 많은 패키지 중 하나를 꼽으라고 한다면 바로 dplyr
일 것입니다.
dplyr
는 데이터 핸들링 패키지 중 하나로, 아래의 작업을 빠르고 쉽게 도와줄 수 있습니다.
데이터를 다루는 흐름을 그대로 코드에 나타냄으로써, 분석 흐름을 이해하기 쉽습니다.
단순한 영어 동사로 이루어진 함수들을 제공하여, 작성하는 코드를 이해하기 쉽습니다.
dplyr
패키지에 대해 설명하기 위해 starwars
데이터를 사용하도록 하겠습니다. 자세한 사항은 ?starwars
를 통해 확인할 수 있습니다.
starwars
는 tibble
데이터 구조를 갖습니다. 이는 dplyr
로 데이터를 불러올 때의 데이터 구조입니다. tibble
은 data.frame
과 동일한 구조이지만 다른 점이 존재합니다.
tibble
은 달리 행의 일부분만 보여줍니다.tibble
은 column의 데이터 유형(type)도 확인할 수 있습니다.
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인 경우를 찾을 때는
|> filter(skin_color=='light',
starwars =='brown') eye_color
이는 기본 R 코드에서 다음과 같이 구현할 수 있습니다.
$skin_color=='light' & starwars$eye_color=='brown',] starwars[starwars
dplyr
를 이용하면, 불필요하게 데이터$변수
를 반복해서 사용할 필요가 없겠죠.
4. arrange()
: 행 순서 정렬하기
arrange()
는 filter()
와 동일하게 행을 다루는 함수입니다. 다만 arrange()
는 다루는 데이터의 행을 정렬합니다.
만약 두 가지 이상의 열 이름을 제공하는 경우, 첫 번째 열에서 같은 값이 나왔을 때, 추가적으로 행을 정렬하는 기준이 정해지게 됩니다.
|> arrange(height) starwars
위의 정렬된 결과를 보면 R2-D2와 R4-P17의 키가 동일한 것을 알 수 있습니다. 이처럼 동일한 값이 오는 경우, arrange()
에 하나의 값을 더 추가함으로써 추가적인 정렬 기준을 세우는 것입니다.
|> arrange(height, mass) starwars
height
를 기준으로 오름차순이 되었고, height
가 같은 경우, mass
가 작은 값부터 오게끔 정렬되었습니다.
만약 내림차순으로 데이터를 정렬하고 싶은 경우는 desc()
를 함께 사용하면 됩니다.
|> arrange(desc(height)) starwars
5. slice()
: 행의 위치를 통한 행 선택
slice()
는 행의 번호(index)를 통해 행들을 선택합니다.
|> slice(5:10) starwars
slice()
계열의 함수들은 다음과 같습니다.
slice_head()
,slice_tail()
: 각각 데이터의 첫 ~행, 마지막 ~행을 선택할 수 있습니다.|> slice_head(n=5) starwars
|> slice_tail(n=3) starwars
slice_sample()
: 무작위로 행을 선택합니다.n
을 통해 행의 개수를 선택하거나,prop
옵션을 통해 특정 비율만큼 행을 선택할 수 있습니다.|> slice_sample(n=10) starwars
|> slice_sample(prop = 0.1) starwars
replace=T
를 통해 복원추출을 수행할 수 있습니다.slice_min()
,slice_max()
를 통해 특정 열의 가장 높거나 가장 낮은 값을 갖는 행을 선택할 수 있습니다.|> slice_max(height,n=3) starwars
6. select()
: 열 선택하기
큰 데이터를 다루게 될 경우, 많은 열이 존재하기 마련입니다. 이 중 분석하고자 하는 일부의 열만 선택할 수 있도록 도와주는 함수가 바로 select()
입니다.
|> select(hair_color, skin_color, eye_color) starwars
만약 열들이 붙어 있다면 :
을 이용해 한번에 출력할 수도 있습니다.
|> select(hair_color:eye_color) starwars
또한 select()
안에서 열 이름이 갖는 규칙을 활용하여, 특정 규칙만을 갖는 열만 선택할 수 있습니다.
starts_with()
: 특정한 값으로 시작하는 열 이름 찾기|> select(starts_with('hair')) starwars
ends_with()
: 특정한 값으로 끝나는 열 이름 찾기|> select(ends_with('hair')) starwars
matches()
: 정규 표현식을 통한 열 이름 찾기|> select(matches('^[a-z]{4}_')) starwars
contains()
:특정한 문자가 포함된 열 이름 찾기|> select(contains('_')) starwars
num_range()
: 특정 숫자범위를 갖는 열 이름 찾기num_range()
함수를 설명하기 위해tidyr
패키지에 있는billboard
데이터를 사용하겠습니다.library(tidyr) |> select(num_range('wk',1:10)) billboard
7. rename()
: 열 이름 변경
select()
문을 이용해 원하는 이름으로 열을 출력할 수도 있습니다.
|> select(home_world=homeworld) starwars
그러나 select()
는 선택된 열 이외에 다른 열들은 모두 버리기 때문에, rename()
을 이용해 열 이름을 변경해줄 수 있습니다.
# rename(new = old)
|> rename(home_world = homeworld) starwars
8. mutate()
: 새로운 열 추가하기
|> mutate(height_m = height / 100) starwars
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
|> relocate(sex:homeworld, # 옮길 열들
starwars .before = height # 옮길 위치
)
10. summarise(), summarize()
: 요약
summarise()
는 하나의 열에 대해 평균, 표준편차, 중앙값 등으로 요약하기 위해 함께 사용되는 함수입니다.
|> summarise(height = mean(height, na.rm = TRUE)) starwars
dplyr
와 %>%
(또는 |>
)를 사용하여 출력했을 때, 출력된 값이 저장되지 않습니다. 즉 분석하는 데이터에는 변경사항이 없습니다. 만약 새로운 열을 추가하거나 이름을 변경할 때, 또는 계산한 값을 저장하기 위해서는 <-
를 이용해 데이터에 저장하거나 새로운 값으로 선언해야 합니다.
<- starwars %>%
starwars2 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