library(dplyr)
starwarsR에서 가장 인기가 많은 패키지 중 하나를 꼽으라고 한다면 바로 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인 경우를 찾을 때는
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한 값만 존재
starwars2Reference
- https://dplyr.tidyverse.org/articles/dplyr.html