gather → pivot_longerの追加
神、ハドリーが作りしtidyr
パッケージにgather
とspread
に代わり、pivot_longer
とpivot_wider
関数が最近追加されました。
ばりばりのgather
とspread
ユーザーなので、その必要性がいまいち理解できていないので、とりあえずvignette("pivot")
にあるユーズケースをpivot_*
を使わないで再現してみて、どのように動くのかを実感してみたいと思います。
WHOデータの概略
列名がまったくtidyでないデータです。
new_sp_m1524
のように、国別の結核の発症を、
(rel = relapse, sn = negative pulmonary smear, sp = positive pulmonary smear, ep = extrapulmonary) to a code for gender (f = female, m = male) to a code for age group (014 = 0-14 yrs of age, 1524 = 15-24 years of age, 2534 = 25 to 34 years of age, 3544 = 35 to 44 years of age, 4554 = 45 to 54 years of age, 5564 = 55 to 64 years of age, 65 = 65 years of age or older).
というコードで表しているとのことでした。
pivot_longer
まずは、vignetteの結果をみてみると、
pivotwho <- who %>% pivot_longer(
cols = new_sp_m014:newrel_f65,
names_to = c("diagnosis", "gender", "age"),
names_pattern = "new_?(.*)_(.)(.*)",
names_ptypes = list(
gender = factor(levels = c("f","m")),
age = factor(
levels = c("014", "1524", "2534", "3544", "4554", "5564", "65"),
ordered = TRUE
)
),
values_to = "count",
values_drop_na = TRUE
)
で、処理結果が、
みごとに、new_sp_m1524
等の変数名が分けられており、ひとつの関数を通っただけでtidyな形になっています。
(pivot_*
系の関数そんなにいらないんじゃないかと思っていてごめんなさい)
gather等を駆使してみる
では、次に、pivot_longer
を使わずに同じ処理をやってみます。
pivot_longerに対応するargumentをコメントで入れてみました。
oldwho <- who %>%
gather(-country, -iso2, -iso3, -year,
key = key, value = count) %>% # values_to = "count",
extract(key,
c("diagnosis","gender","age"), # names_to = c("diagnosis", "gender", "age"),
"new_?(.*)_(.)(.*)") %>% # names_pattern = "new_?(.*)_(.)(.*)",
mutate( # names_ptypes = ...
gender = factor(gender, levels = c("f","m")),
age = factor(age, levels = c("014", "1524", "2534", "3544", "4554", "5564", "65"),
ordered = TRUE)
) %>%
filter(!is.na(count)) # values_drop_na = TRUE
確認
> identical(summary(oldwho),
+ summary(pivotwho))
[1] TRUE
感想
というわけで、pivot_longer
でした。感覚的には、tidyrの各種関数を良い感じでwrapしてくれているものという印象です?まだ、argumentの指定方法には慣れていないのですが、使いこなせると、よくある横に長いnon-tidyなデータを効率的に可読性が高い状態で処理できそうです。
(スクリプトについて、何かご指摘いただける点等ありましたらご指摘いただけると幸いです。)