行指向から列指向へ
データ分析を行う時に、その格納形式として行指向のデータに遭遇する。
行指向データ(ロー指向、ローベース、row-oriented、ローストア)とは、各カラムに変数名が指定されており、対応する値が各レコードの格納されている形式であり、
調査や測定を行う際には、一般的に用いられることも多い。
一方で、こうしたデータ形式は扱いづらく、列指向データ(カラム指向、カラムナ指向、Columnar Database、カラムストア)に形式変換した上で集計する必要がある。
以下、a language not aletter Chapter 8: Melting & Casting を和訳して引用します。
私たちの多くは、データが単一の参加者に対応し、各列が変数に対応するように構造化されているのを、よく目にします。
このタイプのデータ構造は、行指向(本文wide format)として知られています。
しかし、Rのパッケージの多くは、単一の参加者が複数の行を占有するようにデータを拡張する必要があります。
このタイプのデータ構造は、列指向(本文long format)として知られています。
例えば、ggplot2やいくつかのデータ分析機能は列指向を必要とします。
ExcelやSPSSを使用してデータを再構築しようとしたことがある人なら誰でも、このパッケージの巨大なパワーをすぐに認識するでしょう。
行指向は横持ちなどともいわれます。の方が変数に対する値の視認性が良いなどの利点がありますが、
データの追加や削除といった点からは、列指向は縦持ちと言われますが、こちらの方が追加削除を行いやすいことは明らかだと思います。
※参考
https://mathwords.net/yokomotitatemoti
変換の練習、のためのデータ準備
library(readr)
emotion <- read_tsv("http://www.jaredlander.com/data/reaction.txt")
Parsed with column specification:
cols(
ID = col_double(),
Test = col_double(),
Age = col_double(),
Gender = col_character(),
BMI = col_double(),
React = col_double(),
Regulate = col_double()
)
emotion
# A tibble: 99 x 7
ID Test Age Gender BMI React Regulate
<dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
1 1 1 9.69 F 14.7 4.17 3.15
2 1 2 12.3 F 14.6 3.89 2.55
3 2 1 15.7 F 19.5 4.39 4.41
4 2 2 17.6 F 20.0 2.03 2.2
5 3 1 9.52 F 20.9 3.38 2.65
6 3 2 11.8 F 24.0 4 3.63
7 4 1 16.3 M 25.1 3.15 3.59
8 4 2 18.8 M 28.0 3.02 3.54
9 5 1 15.8 M 28.4 3.08 2.64
10 5 2 18.2 M 19.6 3.17 2.29
# ... with 89 more rows
行指向から列指向へ
このデータは行試行になっている(ある変数名に対して、値が入力されている。)
gather関数を使って、列指向データに変換して(reshapeのmeltに相当する)みる
Age、React、Regulateの列を1つの列にして,Measurementと名付ける
library(tidyr)
emotion %>%
+ gather(key=Type, value=Measurement, Age, BMI, React, Regulate)
A tibble: 396 x 5
ID Test Gender Type Measurement
<dbl> <dbl> <chr> <chr> <dbl>
1 1 1 F Age 9.69
2 1 2 F Age 12.3
3 2 1 F Age 15.7
4 2 2 F Age 17.6
5 3 1 F Age 9.52
6 3 2 F Age 11.8
7 4 1 M Age 16.3
8 4 2 M Age 18.8
9 5 1 M Age 15.8
10 5 2 M Age 18.2
# ... with 386 more rows
#引数で指定した列名の列が新たに作成され、列名とその列名に対応した列の値が格納される。
#type列でソートされているので、IDでソートする
emotion <- emotion %>%
+ gather(key=Type, value=Measurement, Age, BMI, React, Regulate) %>%
+ arrange(ID) #ソート
head(emotion,20)
# A tibble: 20 x 5
ID Test Gender Type Measurement
<dbl> <dbl> <chr> <chr> <dbl>
1 1 1 F Age 9.69
2 1 2 F Age 12.3
3 1 1 F BMI 14.7
4 1 2 F BMI 14.6
5 1 1 F React 4.17
6 1 2 F React 3.89
7 1 1 F Regulate 3.15
8 1 2 F Regulate 2.55
9 2 1 F Age 15.7
10 2 2 F Age 17.6
11 2 1 F BMI 19.5
12 2 2 F BMI 20.0
13 2 1 F React 4.39
14 2 2 F React 2.03
15 2 1 F Regulate 4.41
16 2 2 F Regulate 2.2
17 3 1 F Age 9.52
18 3 2 F Age 11.8
19 3 1 F BMI 20.9
20 3 2 F BMI 24.0
#-マイナス記号をつけることで、含まれない列名を指定することも可能
emotion %>%
+ gather(key=Type, value=Measurement, -ID,-Test,-Gender
+ )
# A tibble: 792 x 5
ID Test Gender Type Measurement
<dbl> <dbl> <chr> <chr> <chr>
1 1 1 F Type Age
2 1 2 F Type Age
3 1 1 F Type BMI
4 1 2 F Type BMI
5 1 1 F Type React
6 1 2 F Type React
7 1 1 F Type Regulate
8 1 2 F Type Regulate
9 2 1 F Type Age
10 2 2 F Type Age
# ... with 782 more rows
head(emotion)
# A tibble: 6 x 5
ID Test Gender Type Measurement
<dbl> <dbl> <chr> <chr> <dbl>
1 1 1 F Age 9.69
2 1 2 F Age 12.3
3 1 1 F BMI 14.7
4 1 2 F BMI 14.6
5 1 1 F React 4.17
6 1 2 F React 3.89
列指向から行指向へ変換
列指向データを行指向へ変換する(reshapeのdcastに相当する)
#引数keyで指定した列の値が新しくつくられる列の列目になる
emotion %>%
+ spread(key=Type, value=Measurement)
# A tibble: 99 x 7
ID Test Gender Age BMI React Regulate
<dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 1 1 F 9.69 14.7 4.17 3.15
2 1 2 F 12.3 14.6 3.89 2.55
3 2 1 F 15.7 19.5 4.39 4.41
4 2 2 F 17.6 20.0 2.03 2.2
5 3 1 F 9.52 20.9 3.38 2.65
6 3 2 F 11.8 24.0 4 3.63
7 4 1 M 16.3 25.1 3.15 3.59
8 4 2 M 18.8 28.0 3.02 3.54
9 5 1 M 15.8 28.4 3.08 2.64
10 5 2 M 18.2 19.6 3.17 2.29
# ... with 89 more rows
cheatseat
これらの操作を頻繁に使用するユーザーは覚えても良いし、下記のリンクからチートシートを入手して確認しても良い。
チートシートの作成者へのリスペクトがやみません・・・