145  実践 pivot_wider よくある警告

library(tidyverse)

この変換を行う場合のよくあるエラーを確認しておきましょう。

よくある警告

yoko_error <- 
  tibble(
    city = c(rep("札幌",4)),
    hiduke = c("2018-04-01","2018-04-02","2018-04-03","2018-04-01"),
    tenki = c("晴れ","雨","雨","雨")
)

yoko_error
# A tibble: 4 × 3
  city  hiduke     tenki
  <chr> <chr>      <chr>
1 札幌  2018-04-01 晴れ 
2 札幌  2018-04-02 雨   
3 札幌  2018-04-03 雨   
4 札幌  2018-04-01 雨   

注目していただきたいのはcity列をid_colとした場合に、hidukeが重複して、2018-04-01が存在しているということです。このような場合は、

dat <- 
  yoko_error %>% 
  pivot_wider(id_cols=city,names_from=hiduke,values_from=tenki)
Warning: Values from `tenki` are not uniquely identified; output will contain list-cols.
• Use `values_fn = list` to suppress this warning.
• Use `values_fn = {summary_fun}` to summarise duplicates.
• Use the following dplyr code to identify duplicates.
  {data} %>%
  dplyr::group_by(city, hiduke) %>%
  dplyr::summarise(n = dplyr::n(), .groups = "drop") %>%
  dplyr::filter(n > 1L)
dat
# A tibble: 1 × 4
  city  `2018-04-01` `2018-04-02` `2018-04-03`
  <chr> <list>       <list>       <list>      
1 札幌  <chr [2]>    <chr [1]>    <chr [1]>   

これまで見たことのない表示になっていると思います。

これ、列の型を見てほしいのですが、listとなっております。

View(dat)

でいると明白ですが、札幌の2018-4-1のデータ、もともとの縦持ちデータでは2か所あり、それぞれ晴れと雨で全く別別の値でした。

なので、その場所に二つのデータを押し込めるために、列がこれまで扱っていたベクトルでなくてリストになってしまったという形です。(リストであれば、一か所にベクトルを入れられるので、同じ位置に二つ以上のデータを入れるようなことも可能ですね?)

このような事象が生じた場合は、そもそも、なんで重複するデータが発生しているのか次第で対策方法が変わってくるためここでは踏み込みませんが、

警告メッセージ: Values are not uniquely identified; output will contain list-cols. * Use values_fn = list to suppress this warning. * Use values_fn = length to identify where the duplicates arise * Use values_fn = {summary_fun} to summarise duplicates

にもあるように、

yoko_error %>% 
  pivot_wider(
    id_cols=city,
    names_from=hiduke,
    values_from=tenki,
    values_fn = length
  )
# A tibble: 1 × 4
  city  `2018-04-01` `2018-04-02` `2018-04-03`
  <chr>        <int>        <int>        <int>
1 札幌             2            1            1

とすることで、各「マス目」に、何個のデータが含まれるかを表示することもできます。また、データが数字データであった場合、例えば、

test <- tibble(
  col1 = c("A","A","A","B","B","B","A"),
  col2 = c("a","b","c","a","b","c","a"),
  val = c(1,2,3,4,5,6,7)
)

test
# A tibble: 7 × 3
  col1  col2    val
  <chr> <chr> <dbl>
1 A     a         1
2 A     b         2
3 A     c         3
4 B     a         4
5 B     b         5
6 B     c         6
7 A     a         7
test %>% 
  pivot_wider(
    id_cols = col1,
    names_from = col2, 
    values_from = val,
    values_fn = sum
  )
# A tibble: 2 × 4
  col1      a     b     c
  <chr> <dbl> <dbl> <dbl>
1 A         8     2     3
2 B         4     5     6

Aのaに該当する部分、縦持ちデータでは1と7があるのですが、values_fnにsum関数の括弧なしを与えてあげると、足し算をしてくれました。他にも平均を調べたければ、

test %>% 
  pivot_wider(
    id_cols = col1,
    names_from = col2, 
    values_from = val,
    values_fn = mean
  )
# A tibble: 2 × 4
  col1      a     b     c
  <chr> <dbl> <dbl> <dbl>
1 A         4     2     3
2 B         4     5     6

等を利用してそのまま計算することも可能です。

いかがでしょうか?

結構便利に使えそうですね?