LoginSignup
5
0

More than 3 years have passed since last update.

tidyrのpivot_longerでできることをpivot_longerを使わないでやってみる

Last updated at Posted at 2019-10-01

gather → pivot_longerの追加

神、ハドリーが作りしtidyrパッケージにgatherspreadに代わり、pivot_longerpivot_wider関数が最近追加されました。

ばりばりのgatherspreadユーザーなので、その必要性がいまいち理解できていないので、とりあえずvignette("pivot")にあるユーズケースをpivot_*を使わないで再現してみて、どのように動くのかを実感してみたいと思います。

image.png

WHOデータの概略

Vignettの一番最初にある例
image.png

列名がまったく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
)

で、処理結果が、

image.png

みごとに、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なデータを効率的に可読性が高い状態で処理できそうです。

(スクリプトについて、何かご指摘いただける点等ありましたらご指摘いただけると幸いです。)

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0