tidyverse / group_by 설명

tidyverse 패키지 안에 dplyr 이 있는 것은 알죠? dplyr의 최애 함수는 group_by()이죠. 그룹을 지정하는 함수.

group_by()로 지정한 다음에 .x와 .y를 쓸 수 있어요. .x는 그룹별 데이터를 tibble 객체로 받고 .y는 그룹의 값을 key처럼 받아요. 파이썬이나 자바스크립트 프로그래머들에게는 익숙한 개념이죠.

.x와 .y를 이해했다면 group_map()과 group_modify()를 생각해볼 차례에요. mtcars를 사용해볼께요.

질문: 변속기 종류(am)별로 실린더 수(cyl)가 연비(mpg)에 미치는 영향력의 차이는?
이 문제를 풀려면

> lm(mpg~cyl,data=그룹데이터)

이제 그룹 데이터를 정의해야죠?

> mtcars %>% group_by(am)

변속기별로 mtcars 데이터를 나눠서 생각하자는 것이에요. 이제 좀 붙여볼까요?

> mtcars %>%
   group_by(am) %>%
   group_map(~broom::tidy(
     lm(mpg~cyl,data=.x) ))

결과는

[[1]]
# A tibble: 2 x 5
  term        estimate std.error statistic       p.value
  <chr>          <dbl>     <dbl>     <dbl>         <dbl>
1 (Intercept)    30.9      2.59      11.9  0.00000000111
2 cyl            -1.98     0.364     -5.42 0.0000458   

[[2]]
# A tibble: 2 x 5
  term        estimate std.error statistic     p.value
  <chr>          <dbl>     <dbl>     <dbl>       <dbl>
1 (Intercept)    41.0      3.57      11.5  0.000000181
2 cyl            -3.28     0.675     -4.86 0.000503 

group_map() 안에 ~를 붙여서 함수를 넣을 수 있어요.
broom의 tidy로 lm() 결과를 둘러싸면 위의 결과처럼 그룹별 결과를 list로 돌려줘요. 주목한 것은 .x에요. 그룹별 데이터를 .x로 나눠서 넣었죠.

비슷하지만 group_modify()가 있어요.

질문: iris 데이터에서 Speal.Length의 평균을 종(Species)별로 계산해보면?

코드는 아래와 같아요.

> iris %>%
    group_by(Species) %>%
    group_modify(~(function(d) {
      tibble(mean_sl=mean(d$Sepal.Length))
    })(.x))

복잡하니까 하나하나 봐요. R에서 익명함수는 (function(x,y){})(xvar,yvar)로 작성해요. xvar와 yvar가 넘겨주는 인수값이고 이것을 받는 인수가 x,y가 되요. {}안에 코드를 써요. (function(d){...})(.x)면 .x를 d로 넘겨주는 것이죠.

group_modify()는 tibble 형식으로 반환해야 해요.

결과를 보면

# A tibble: 3 x 2
# Groups:   Species [3]
  Species    mean_sl
  <fct>        <dbl>
1 setosa        5.01
2 versicolor    5.94
3 virginica     6.59

아주 쓸모있는 함수들이니까 잘 배우세요.

댓글

이 블로그의 인기 게시물

Bradley-Terry Model: paired comparison models

xlwings tutorial - 데이터 계산하여 붙여 넣기

R에서 csv 파일 읽는 법