R データフレームの縦長←→横長変換の簡単まとめ


いろいろなところで解説されてる内容ですが、自分なりにできるだけ簡単にまとめました。関数の詳しい説明については「参考サイト」を参照してください。
なお、ここではtidyr::gathertidyr::spreadを使います(理由については後述)。

必要パッケージ

tidyrを使う。

install.packages("tidyr")
# あるいは
install.packages("tidyverse")

イメージ

横長→縦長変換

縦長→横長変換

データは気象庁 台風の発生数(2019年までの確定値と2020年の速報値)を使用。列名が日本語なのとエンコードがShift-JISである点に注意。

取り込み

d <- read.csv("https://www.data.jma.go.jp/fcd/yoho/typhoon/statistics/generation/generation.csv", fileEncoding = "shift-jis")

read.csvを使った場合、(上図と違って)各月の列名が「X」はじまりになるので注意。read_csvを使うと、各月の列名はバッククオートで囲われた形で格納される。

横長→縦長変換

d.gathered <- tidyr::gather(data = d, 2:14, key = Month, value = Number) # 列数指定
d.gathered <- tidyr::gather(data = d, X1月, X2月, X3月, X4月, X5月, X6月, X7月, X8月, X9月, X10月, X11月, X12月, 年間, key = Month, value = Number) # 列名指定

またtidyverseを使っている場合には、dplyr::selectと同様の選択方法も使用可能。選択方法はこちらのサイトに詳しい。

d.gathered <- tidyr::gather(data = d,  -, key = Month, value = Number) # 「年」以外の列を選択
d.gathered <- tidyr::gather(data = d,  ends_with("月"), key = Month, value = Number) # 「月」がつく列を後方一致で選択。この場合「年間」は残る。

縦長→横長変換

d.spread <- tidyr::spread(data = d.gathered, key = Month, value = Number)

列名の順番は適宜訂正する必要あり。

gather/spreadpivot_longer/pivot_wider

tidyr内の縦横変換関数としては、gather/spreadとtidyr ver.1.0.0以降で使えるpivot_longer/pivot_widerの2種類があるが、より互換性が高いのは前者だと思うのでここではそちらを使った(tidyverseの部分アップデートで依存関係が壊れるとめんどくさい)。
ただし後者のほうが改良版で良いとのことなので、tidyr ver.1.0.0以降を使用可能ならばそちらを使ったほうがいいかもしれない。(機会があればそちらで書き直します)

参考サイト

共通

Package ‘tidyr’

gather/spread

Rstudio Data Import Cheat Sheet
縦横変換 - gather関数とspread関数

pivot_longer/pivot_wider

【tidyr】gather?, spread? もう古い。時代はpivot
tidyr — シンプルなデータ変形ツール