library(tidyr)
library(dplyr)
이번 시간에는 데이터의 형태를 변환시키는 pivoting을 배워보도록 하겠습니다.
오늘 사용할 패키지는 다음과 같습니다.
tidyr
의 ‘tidy’는 ’정돈하다’ 라는 뜻입니다. 데이터를 정돈하기 위해 사용하는 패키지라고 이해하시면 되겠습니다.
1. Longer: 데이터 길게 늘이기
1) 열 이름에 문자 포함된 경우
pivot_longer()
는 데이터 내의 행의 수를 늘리고, 열의 개수를 줄임으로서 데이터를 길게 만듭니다. 즉 여러 개의 열을 줄여 행으로 바꾸는 과정에서 자연스럽게 데이터의 형태가 길어지는 것을 의미합니다.
relig_income
은 tidyr
패키지에 포함되어 있는 데이터셋으로, 사람들의 종교와 연소득 데이터가 들어있습니다.
pivot_longer()
간단한 예시를 살펴보겠습니다.
|>
relig_income pivot_longer(!religion,
names_to="income",
values_to = "values")
pivot_longer()에서 사용된 인자는 다음과 같습니다.
relig_income
: 형태를 변환시킬 데이터cols
: 데이터 내에서 길게 변환시킬 열들names_to
: 열들이 길게 변환된 뒤, 새로운 열의 이름values_to
: 길게 변환된 열들의 데이터가 갖게되는 새로운 열 이름
정리하자면 cols
에서는 기존 데이터셋에서 열들의 이름이 들어가는데, 이 열들은 names_to
에서 정해준 income
이라고 하는 하나의 열로 변환되고, cols에서 선택된 열들의 값들은 values_to
에서 정해준 values
라고 하는 하나의 열로 변환되는 것입니다.
2) 열 이름에 숫자가 포함된 경우
다음으로 billboard 데이터로 pivot_longer를 진행해보겠습니다. billboard 데이터에는 2000년도의 빌보드 순위 주(week) 단위로 들어있습니다.
이 데이터를 길게 바꾸면 다음과 같습니다.
|>
billboard pivot_longer(
cols=starts_with('wk'),
names_to='week',
values_to='rank',
values_drop_na = T
)
cols에서 열들을 선택할 때, 규칙이 있는 열들은 dplyr의 select()
에서 사용하던 starts_with()
등을 사용할 수 있습니다.
또한 데이터를 길게 변환할 때, values_drop_na
를 통해 NA인 데이터들은 제외하였습니다.
데이터를 변환하니 wk~
열들이 전부 week
라는 하나의 열로 변환되었습니다. 그런데 week
열의 데이터는 전부 wk
가 들어가있습니다. 몇 주차인지 표현하기 위해서는 숫자만 있어도 될 것 같아 보입니다.
이럴 때, names_prefix
인자를 통해 wk
접두사(prefix)를 없애주도록 하겠습니다.
이 때, names_prefix
가 추가되어도, week
의 데이터 유형은 그대로 character
입니다. week
를 숫자형태로 변환해주려면 names_transform
을 이용하면 됩니다.
|>
billboard pivot_longer(
cols=starts_with('wk'),
names_to='week',
names_prefix = 'wk',
names_transform = as.integer,
values_to='rank',
values_drop_na = T
)
3) 열들을 세부적으로 나누기
다음으로는 좀더 까다로운 데이터를 길게 변환해보도록 하겠습니다. tidyr
의 who
데이터에는 new_sp_m014
부터 newrel_f65
까지, 네 종류의 값들이 열의 이름으로 들어가 있습니다.
new_
/new
: 새로운 경우들을 값들을 나타냅니다.sp
/rel
/ep
: 진단명m
/f
: 성별014
/1524
/1524
/3544
/4554
/65
: 나이 범위
이 값들은 규칙을 띈 채로 열 이름으로 되어있기 때문에, name_pattern을 이용해 열 이름에서 추출할 수 있습니다.
|>
who pivot_longer(
cols=new_sp_m014:newrel_f65,
names_to= c('diagnosis','gender','age'),
names_pattern = "new_?(.*)_(.)(.*)", # 정규표현식
values_to="count"
)
<- tibble(
household family = 1:5,
dob_child1 = c('1998-11-26','1996-06-22','2002-07-11','2004-10-10','2000-12-05'),
dob_child2 = c('2000-01-29',NA,'2004-04-05','2009-08-27','2005-02-28'),
name_child1 = c('Susan','Mark','Sam','Craig','Parker'),
name_child2 = c('Jose',NA,'Seth','Khai','Gracie')
)
|>
household pivot_longer(
cols = !family,
names_to=c('.value',"child"),
names_sep="_",
values_drop_na = T,
)
2. Wider: 데이터 넓게 펼치기
1) Capture-recapture
|>
fish_encounters pivot_wider(
names_from = station,
values_from = seen
)
이 데이터에서 결측 값 NA
는 0과 같습니다. 다시 말해, 물고기가 발견된 적이 없다는 것이죠. 그렇기 때문에 NA
를 0으로 채워넣을 수 있습니다.
|>
fish_encounters pivot_wider(
names_from = station,
values_from = seen,
values_fill = 0
)
2) Aggregation
|>
warpbreaks pivot_wider(
names_from = c(wool),
values_from = breaks,
values_fn = mean
)