R에서 가장 인기가 많은 패키지 중 하나를 꼽으라고 한다면 바로 dplyr
일 것입니다.
dplyr
는 데이터 핸들링 패키지 중 하나로, 아래의 작업을 빠르고 쉽게 도와줄 수 있습니다.
데이터를 다루는 흐름을 그대로 코드에 나타냄으로써, 분석 흐름을 이해하기 쉽습니다.
단순한 영어 동사로 이루어진 함수들을 제공하여, 작성하는 코드를 이해하기 쉽습니다.
dplyr
패키지에 대해 설명하기 위해 starwars
데이터를 사용하도록 하겠습니다. 자세한 사항은 ?starwars
를 통해 확인할 수 있습니다.
Luke Skywalker 172 77.0 blond fair blue 19.0 male masculine C-3PO 167 75.0 NA gold yellow 112.0 none masculine R2-D2 96 32.0 NA white, blue red 33.0 none masculine Darth Vader 202 136.0 none white yellow 41.9 male masculine Leia Organa 150 49.0 brown light brown 19.0 female feminine Owen Lars 178 120.0 brown, grey light blue 52.0 male masculine Beru Whitesun lars 165 75.0 brown light blue 47.0 female feminine R5-D4 97 32.0 NA white, red red NA none masculine Biggs Darklighter 183 84.0 black light brown 24.0 male masculine Obi-Wan Kenobi 182 77.0 auburn, white fair blue-gray 57.0 male masculine
starwars
는 tibble
데이터 구조를 갖습니다. 이는 dplyr
로 데이터를 불러올 때의 데이터 구조입니다. tibble
은 data.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' )
Leia Organa 150 49 brown light brown 19 female feminine Alderaan Biggs Darklighter 183 84 black light brown 24 male masculine Tatooine Cordé 157 NA brown light brown NA female feminine Naboo Dormé 165 NA brown light brown NA female feminine Naboo Raymus Antilles 188 79 brown light brown NA male masculine Alderaan Poe Dameron NA NA brown light brown NA male masculine NA Padmé Amidala 165 45 brown light brown 46 female feminine Naboo
이는 기본 R 코드에서 다음과 같이 구현할 수 있습니다.
starwars[starwars$ skin_color== 'light' & starwars$ eye_color== 'brown' ,]
Leia Organa 150 49 brown light brown 19 female feminine Alderaan Biggs Darklighter 183 84 black light brown 24 male masculine Tatooine Cordé 157 NA brown light brown NA female feminine Naboo Dormé 165 NA brown light brown NA female feminine Naboo Raymus Antilles 188 79 brown light brown NA male masculine Alderaan Poe Dameron NA NA brown light brown NA male masculine NA Padmé Amidala 165 45 brown light brown 46 female feminine Naboo
dplyr
를 이용하면, 불필요하게 데이터$변수
를 반복해서 사용할 필요가 없겠죠.
4. arrange()
: 행 순서 정렬하기
arrange()
는 filter()
와 동일하게 행을 다루는 함수입니다. 다만 arrange()
는 다루는 데이터의 행을 정렬합니다.
만약 두 가지 이상의 열 이름을 제공하는 경우, 첫 번째 열에서 같은 값이 나왔을 때, 추가적으로 행을 정렬하는 기준이 정해지게 됩니다.
starwars |> arrange (height)
Yoda 66 17.0 white green brown 896.0 male masculine Ratts Tyerell 79 15.0 none grey, blue unknown NA male masculine Wicket Systri Warrick 88 20.0 brown brown brown 8.0 male masculine Dud Bolt 94 45.0 none blue, grey yellow NA male masculine R2-D2 96 32.0 NA white, blue red 33.0 none masculine R4-P17 96 NA none silver, red red, blue NA none feminine R5-D4 97 32.0 NA white, red red NA none masculine Sebulba 112 40.0 none grey, red orange NA male masculine Gasgano 122 NA none white, blue black NA male masculine Watto 137 NA black blue, grey yellow NA male masculine
위의 정렬된 결과를 보면 R2-D2와 R4-P17의 키가 동일한 것을 알 수 있습니다. 이처럼 동일한 값이 오는 경우, arrange()
에 하나의 값을 더 추가함으로써 추가적인 정렬 기준을 세우는 것입니다.
starwars |> arrange (height, mass)
Yoda 66 17.0 white green brown 896.0 male masculine Ratts Tyerell 79 15.0 none grey, blue unknown NA male masculine Wicket Systri Warrick 88 20.0 brown brown brown 8.0 male masculine Dud Bolt 94 45.0 none blue, grey yellow NA male masculine R2-D2 96 32.0 NA white, blue red 33.0 none masculine R4-P17 96 NA none silver, red red, blue NA none feminine R5-D4 97 32.0 NA white, red red NA none masculine Sebulba 112 40.0 none grey, red orange NA male masculine Gasgano 122 NA none white, blue black NA male masculine Watto 137 NA black blue, grey yellow NA male masculine
height
를 기준으로 오름차순이 되었고, height
가 같은 경우, mass
가 작은 값부터 오게끔 정렬되었습니다.
만약 내림차순으로 데이터를 정렬하고 싶은 경우는 desc()
를 함께 사용하면 됩니다.
starwars |> arrange (desc (height))
Yarael Poof 264 NA none white yellow NA male masculine Tarfful 234 136.0 brown brown blue NA male masculine Lama Su 229 88.0 none grey black NA male masculine Chewbacca 228 112.0 brown unknown blue 200.0 male masculine Roos Tarpals 224 82.0 none grey orange NA male masculine Grievous 216 159.0 none brown, white green, yellow NA male masculine Taun We 213 NA none grey black NA female feminine Rugor Nass 206 NA none green orange NA male masculine Tion Medon 206 80.0 none grey black NA male masculine Darth Vader 202 136.0 none white yellow 41.9 male masculine
5. slice()
: 행의 위치를 통한 행 선택
slice()
는 행의 번호(index)를 통해 행들을 선택합니다.
Leia Organa 150 49 brown light brown 19 female feminine Alderaan Owen Lars 178 120 brown, grey light blue 52 male masculine Tatooine Beru Whitesun lars 165 75 brown light blue 47 female feminine Tatooine R5-D4 97 32 NA white, red red NA none masculine Tatooine Biggs Darklighter 183 84 black light brown 24 male masculine Tatooine Obi-Wan Kenobi 182 77 auburn, white fair blue-gray 57 male masculine Stewjon
slice()
계열의 함수들은 다음과 같습니다.
slice_head()
, slice_tail()
: 각각 데이터의 첫 ~행, 마지막 ~행을 선택할 수 있습니다.
starwars |> slice_head (n= 5 )
Luke Skywalker 172 77 blond fair blue 19.0 male masculine Tatooine C-3PO 167 75 NA gold yellow 112.0 none masculine Tatooine R2-D2 96 32 NA white, blue red 33.0 none masculine Naboo Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine Leia Organa 150 49 brown light brown 19.0 female feminine Alderaan
starwars |> slice_tail (n= 3 )
BB8 NA NA none none black NA none masculine NA Captain Phasma NA NA unknown unknown unknown NA NA NA NA Padmé Amidala 165 45 brown light brown 46 female feminine Naboo
slice_sample()
: 무작위로 행을 선택합니다. n
을 통해 행의 개수를 선택하거나, prop
옵션을 통해 특정 비율만큼 행을 선택할 수 있습니다.
starwars |> slice_sample (n= 10 )
Eeth Koth 171 NA black brown brown NA male masculine Iridonia Jek Tono Porkins 180 110 brown fair blue NA male masculine Bestine IV Greedo 173 74 NA green black 44.0 male masculine Rodia Darth Vader 202 136 none white yellow 41.9 male masculine Tatooine IG-88 200 140 none metal red 15.0 none masculine NA Quarsh Panaka 183 NA black dark brown 62.0 NA NA Naboo Rugor Nass 206 NA none green orange NA male masculine Naboo Kit Fisto 196 87 none green black NA male masculine Glee Anselm R2-D2 96 32 NA white, blue red 33.0 none masculine Naboo Mon Mothma 150 NA auburn fair blue 48.0 female feminine Chandrila
starwars |> slice_sample (prop = 0.1 )
Grievous 216 159 none brown, white green, yellow NA male masculine Kalee Han Solo 180 80 brown fair brown 29 male masculine Corellia San Hill 191 NA none grey gold NA male masculine Muunilinst R2-D2 96 32 NA white, blue red 33 none masculine Naboo Wicket Systri Warrick 88 20 brown brown brown 8 male masculine Endor Finn NA NA black dark dark NA male masculine NA Yoda 66 17 white green brown 896 male masculine NA Shmi Skywalker 163 NA black fair brown 72 female feminine Tatooine
replace=T
를 통해 복원추출을 수행할 수 있습니다.
slice_min()
, slice_max()
를 통해 특정 열의 가장 높거나 가장 낮은 값을 갖는 행을 선택할 수 있습니다.
starwars |> slice_max (height,n= 3 )
Yarael Poof 264 NA none white yellow NA male masculine Quermia Tarfful 234 136 brown brown blue NA male masculine Kashyyyk Lama Su 229 88 none grey black NA male masculine Kamino
6. select()
: 열 선택하기
큰 데이터를 다루게 될 경우, 많은 열이 존재하기 마련입니다. 이 중 분석하고자 하는 일부의 열만 선택할 수 있도록 도와주는 함수가 바로 select()
입니다.
starwars |> select (hair_color, skin_color, eye_color)
blond fair blue NA gold yellow NA white, blue red none white yellow brown light brown brown, grey light blue brown light blue NA white, red red black light brown auburn, white fair blue-gray
만약 열들이 붙어 있다면 :
을 이용해 한번에 출력할 수도 있습니다.
starwars |> select (hair_color: eye_color)
blond fair blue NA gold yellow NA white, blue red none white yellow brown light brown brown, grey light blue brown light blue NA white, red red black light brown auburn, white fair blue-gray
또한 select()
안에서 열 이름이 갖는 규칙을 활용하여, 특정 규칙만을 갖는 열만 선택할 수 있습니다.
starts_with()
: 특정한 값으로 시작하는 열 이름 찾기
starwars |> select (starts_with ('hair' ))
blond NA NA none brown brown, grey brown NA black auburn, white
ends_with()
: 특정한 값으로 끝나는 열 이름 찾기
starwars |> select (ends_with ('hair' ))
matches()
: 정규 표현식을 통한 열 이름 찾기
starwars |> select (matches ('^[a-z]{4}_' ))
blond fair NA gold NA white, blue none white brown light brown, grey light brown light NA white, red black light auburn, white fair
contains()
:특정한 문자가 포함된 열 이름 찾기
starwars |> select (contains ('_' ))
blond fair blue 19.0 NA gold yellow 112.0 NA white, blue red 33.0 none white yellow 41.9 brown light brown 19.0 brown, grey light blue 52.0 brown light blue 47.0 NA white, red red NA black light brown 24.0 auburn, white fair blue-gray 57.0
num_range()
: 특정 숫자범위를 갖는 열 이름 찾기
num_range()
함수를 설명하기 위해 tidyr
패키지에 있는 billboard
데이터를 사용하겠습니다.
library (tidyr)
billboard |> select (num_range ('wk' ,1 : 10 ))
87 82 72 77 87 94 99 NA NA NA 91 87 92 NA NA NA NA NA NA NA 81 70 68 67 66 57 54 53 51 51 76 76 72 69 67 65 55 59 62 61 57 34 25 17 17 31 36 49 53 57 51 39 34 26 26 19 2 2 3 6 97 97 96 95 100 NA NA NA NA NA 84 62 51 41 38 35 35 38 38 36 59 53 38 28 21 18 16 14 12 10 76 76 74 69 68 67 61 58 57 59
7. rename()
: 열 이름 변경
select()
문을 이용해 원하는 이름으로 열을 출력할 수도 있습니다.
starwars |> select (home_world= homeworld)
Tatooine Tatooine Naboo Tatooine Alderaan Tatooine Tatooine Tatooine Tatooine Stewjon
그러나 select()
는 선택된 열 이외에 다른 열들은 모두 버리기 때문에, rename()
을 이용해 열 이름을 변경해줄 수 있습니다.
# rename(new = old)
starwars |> rename (home_world = homeworld)
Luke Skywalker 172 77.0 blond fair blue 19.0 male masculine C-3PO 167 75.0 NA gold yellow 112.0 none masculine R2-D2 96 32.0 NA white, blue red 33.0 none masculine Darth Vader 202 136.0 none white yellow 41.9 male masculine Leia Organa 150 49.0 brown light brown 19.0 female feminine Owen Lars 178 120.0 brown, grey light blue 52.0 male masculine Beru Whitesun lars 165 75.0 brown light blue 47.0 female feminine R5-D4 97 32.0 NA white, red red NA none masculine Biggs Darklighter 183 84.0 black light brown 24.0 male masculine Obi-Wan Kenobi 182 77.0 auburn, white fair blue-gray 57.0 male masculine
8. mutate()
: 새로운 열 추가하기
starwars |> mutate (height_m = height / 100 )
Luke Skywalker 172 77.0 blond fair blue 19.0 male masculine C-3PO 167 75.0 NA gold yellow 112.0 none masculine R2-D2 96 32.0 NA white, blue red 33.0 none masculine Darth Vader 202 136.0 none white yellow 41.9 male masculine Leia Organa 150 49.0 brown light brown 19.0 female feminine Owen Lars 178 120.0 brown, grey light blue 52.0 male masculine Beru Whitesun lars 165 75.0 brown light blue 47.0 female feminine R5-D4 97 32.0 NA white, red red NA none masculine Biggs Darklighter 183 84.0 black light brown 24.0 male masculine Obi-Wan Kenobi 182 77.0 auburn, white fair blue-gray 57.0 male masculine
tibble
특성 상 새롭게 만든 열이 바로 보이지 않지만, select()
를 이용해 출력할 수 있습니다.
starwars |>
mutate (height_m = height / 100 ) %>%
select (height_m, height, everything ())
1.72 172 Luke Skywalker 77.0 blond fair blue 19.0 male masculine 1.67 167 C-3PO 75.0 NA gold yellow 112.0 none masculine 0.96 96 R2-D2 32.0 NA white, blue red 33.0 none masculine 2.02 202 Darth Vader 136.0 none white yellow 41.9 male masculine 1.50 150 Leia Organa 49.0 brown light brown 19.0 female feminine 1.78 178 Owen Lars 120.0 brown, grey light blue 52.0 male masculine 1.65 165 Beru Whitesun lars 75.0 brown light blue 47.0 female feminine 0.97 97 R5-D4 32.0 NA white, red red NA none masculine 1.83 183 Biggs Darklighter 84.0 black light brown 24.0 male masculine 1.82 182 Obi-Wan Kenobi 77.0 auburn, white fair blue-gray 57.0 male masculine
mutate()
안에서 새롭게 만든 열도 접근이 가능합니다.
starwars |>
mutate (
height_m = height / 100 ,
BMI = mass / (height_m^ 2 )
) %>%
select (BMI, everything ())
26.02758 Luke Skywalker 172 77.0 blond fair blue 19.0 male masculine 26.89232 C-3PO 167 75.0 NA gold yellow 112.0 none masculine 34.72222 R2-D2 96 32.0 NA white, blue red 33.0 none masculine 33.33007 Darth Vader 202 136.0 none white yellow 41.9 male masculine 21.77778 Leia Organa 150 49.0 brown light brown 19.0 female feminine 37.87401 Owen Lars 178 120.0 brown, grey light blue 52.0 male masculine 27.54821 Beru Whitesun lars 165 75.0 brown light blue 47.0 female feminine 34.00999 R5-D4 97 32.0 NA white, red red NA none masculine 25.08286 Biggs Darklighter 183 84.0 black light brown 24.0 male masculine 23.24598 Obi-Wan Kenobi 182 77.0 auburn, white fair blue-gray 57.0 male masculine
만약 기존의 열은 없애고 새로운 열만 남기고 싶다면, transmute()
를 이용할 수 있습니다.
starwars |>
transmute (
height_m = height / 100 ,
BMI = mass / (height_m^ 2 )
)
1.72 26.02758 1.67 26.89232 0.96 34.72222 2.02 33.33007 1.50 21.77778 1.78 37.87401 1.65 27.54821 0.97 34.00999 1.83 25.08286 1.82 23.24598
9. relocate()
: 순서 변경
relocate()
는 옮길 열들과, 옮길 위치를 지정해주면 됩니다.
# .before or .after
starwars |> relocate (sex: homeworld, # 옮길 열들
.before = height # 옮길 위치
)
Luke Skywalker male masculine Tatooine 172 77.0 blond fair blue C-3PO none masculine Tatooine 167 75.0 NA gold yellow R2-D2 none masculine Naboo 96 32.0 NA white, blue red Darth Vader male masculine Tatooine 202 136.0 none white yellow Leia Organa female feminine Alderaan 150 49.0 brown light brown Owen Lars male masculine Tatooine 178 120.0 brown, grey light blue Beru Whitesun lars female feminine Tatooine 165 75.0 brown light blue R5-D4 none masculine Tatooine 97 32.0 NA white, red red Biggs Darklighter male masculine Tatooine 183 84.0 black light brown Obi-Wan Kenobi male masculine Stewjon 182 77.0 auburn, white fair blue-gray
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
Aleena male 79.0000 15.00000 Besalisk male 198.0000 102.00000 Cerean male 198.0000 82.00000 Chagrian male 196.0000 NaN Clawdite female 168.0000 55.00000 Droid none 131.2000 69.75000 Dug male 112.0000 40.00000 Ewok male 88.0000 20.00000 Geonosian male 183.0000 80.00000 Gungan male 208.6667 74.00000
Reference
https://dplyr.tidyverse.org/articles/dplyr.html
Back to top