library(dplyr)
|>
starwars group_by(species, sex) |>
select(height, mass) |>
summarise(
height = mean(height, na.rm = TRUE),
mass = mean(mass, na.rm = TRUE)
)
group_by()
란?
group_by()
는 특정 집단의 범주별로 어떤 값들을 요약하거나 계산할 때 많이 활용되는 함수입니다.
<- starwars |> group_by(species)
by_species <- starwars |> group_by(sex,gender) by_sex_gender
출력했을 때, 데이터가 그룹으로 묶인 것을 알 수 있습니다.
by_species
by_sex_gender
tally()
또는 count()
를 이용해 그룹별 n수를 파악할 수도 있습니다.
sort
인자를 통해서 그룹 수가 많은 순서대로 정렬할 수 있습니다.
|> tally() by_species
|>
by_sex_gender tally(sort=T)
또한 group_by()
안에서 새로운 변수를 만들어 그 변수에 따른 계산을 할 수도 있습니다.
|>
starwars group_by(bmi_cat = cut(mass/(height/100)^2, breaks = c(0,18,23,25,30,Inf))) |>
tally()
그룹 변수 정보 확인
그룹 변수를 지정해준 경우, group_keys()
를 통해 그룹 변수의 범주(종류)를 확인할 수 있습니다.
|> group_keys() by_species
한편 group_vars()
는 group_by()
에 사용된 변수의 이름을 확인할 때 사용할 수 있습니다.
|> group_vars() by_sex_gender
[1] "sex" "gender"
그룹 변수 변경 및 추가
기존의 그룹처리 되어있는 데이터에 group_by()
를 진행할 시, 새로운 그룹 변수로 덮어씌워집니다.
by_species
는 앞서 group_by(species)
를 통해 species
별로 묶은 데이터죠. 여기서 group_by(homeworld)
를 추가한다면 기존의 species
에서 homeworld
를 기준으로 그룹이 묶이게 됩니다.
|>
by_species group_by(homeworld) |>
tally()
만약 기존의 그룹을 대체하는 것이 아니라 추가를 할 수도 있을텐데요. group_by()
에 .add=T
인자를 추가할 경우, 기존에 있던 그룹 변수에 새로운 그룹 변수를 추가할 수도 있습니다.
|>
by_species group_by(homeworld, .add=T) |>
tally()
그룹 변수 제거
그룹 처리된 데이터를 제거하고 싶은 경우, ungroup()
을 사용합니다.
|>
by_species ungroup() |>
tally()
물론 특정 그룹 변수만 제외할 수도 있습니다. by_sex_gender
에서 sex
와 gender
로 묶여있던 것을 ungroup()
을 통해 sex
만 제거하여 gender
만 그룹으로 남아있게 되었습니다.
|>
by_sex_gender ungroup(sex) |>
tally()
group_by()
와 함께 쓰는 동사
다음으로 dplyr
에서 group_by()
와 자주 쓰이는 함수들을 알아보겠습니다.
1. summarise()
, summarize()
summarise()
와 group_by()
가 함께 사용될 경우, 그룹별로 요약 계산을 수행합니다. 평균, 표준편차, 중앙값, 최소, 최대값과 같은 값을 출력할 수 있습니다.
|>
by_species summarise(
n=n(),
mean_height = mean(height,na.rm=T)
)
.groups
인자는 출력되는 결과의 그룹 구조를 다루는 인자입니다. keep
은 그룹으로 묶인 상태를 유지하는 반면, drop
은 그룹으로 묶인 상태를 해제합니다.
|>
by_sex_gender summarise(n=n(), .groups = 'keep')
|>
by_sex_gender summarise(n=n(), .groups = 'drop')
2. select()
, rename()
, relocate()
rename()
과 relocate()
는 group_by()
와 관계없이 동일한 작업을 수행합니다. 각각 열의 이름과 위치에만 영향을 미치게 때문입니다.
select()
가 group_by()
와 함께 쓰이면 그룹 변수가 항상 함께 선택됩니다.
|> select(mass) by_species
그룹 변수가 함께 선택되는 것을 원치 않는다면 ungroup()
을 먼저 사용해야 합니다.
|> ungroup() |> select(mass) by_species
3. arrange()
arrange()
가 group_by()
와 함께 쓰일 경우, 그냥 사용하게 되면 group_by()
가 없을 때와 동일합니다. 그러나 .by_group=T
인자를 통해 그룹 변수를 기준으로 정렬되어 결과가 출력됩니다.
|>
by_species arrange(desc(mass)) |>
relocate(species, mass)
|>
by_species arrange(desc(mass), .by_group = T) |>
relocate(species, mass)
4. mutate()
, transmute()
group_by()
와 함께 새로운 변수를 생성할 경우, 그룹 별로 동일한 값이 들어가게 됩니다.
|>
starwars group_by(species) |>
mutate(mean_height = mean(height, na.rm=T)) |>
arrange(desc(species)) |>
select(species, height, mean_height)
5. filter()
filter()
와 group_by()
를 함께 사용하여, 특정 그룹의 수를 기준으로 선택할 때 사용할 수 있습니다.
아래의 예시에서는 그룹 별 수가 1인 경우를 모두 제외하고 선택한 결과입니다.
|>
by_species filter(n()!=1) |>
tally()
6. slice()
slice()
와 slice()
계열 함수들이 group_by()
와 함께 사용될 경우, 그룹별로 해당되는 값이 출력됩니다.
# 그룹별 첫번째 값
|>
by_species slice(1)
|>
by_species filter(!is.na(height)) |>
slice_min(height,n=2)
Update: dplyr 1.1.0
dplyr 1.1.0 업데이트 이후에는 group_by()
를 사용하지 않아도 다른 함수들에서 그룹 별 계산을 수행할 수 있습니다. 바로 .by
인자를 통해서 말이죠.
|>
starwars mutate(bmi = mass/(height/100)^2) |>
summarise(mean_bmi = mean(bmi, na.rm=T),.by=species)