5.2 データの整形

データの整形には、tidyverseパッケージ群に含まれるdplyrというパッケージを用いる。しかしながら、tidyverseのインストール・起動しておけばdplyrも利用できるため、特に心配する必要はない。dplyr には、いくつもの便利な関数がふくまれているが、本節では主に以下の関数および機能を紹介する。

  1. summarize()
  2. mutate()
  3. filter()
  4. select()
  5. arrange()
  6. パイプ演算子 %>%

summarize は、ある変数の平均値や標準偏差などの記述統計量を計算することができる関数である。例えば、dataというデータセットに含まれる var_name という変数の平均値を計算し、それを M という変数名として定義する場合、以下のコマンドを用いる(以下のコマンドは見本コードである)。

summarize(data, M = mean(var_name))

mutate は、データセットに引数内で指定した定義の変数(列)を追加する関数である。例えば、dataというデータセットに対し、definition で定義した変数をnew_varとして追加するには、以下のコマンドを用いる(以下は見本コードである)。実際にdefinitionを定義する場合には、様々な関数や論理式を利用する必要がある。例えば、“new_var = var1/100” という定義を用いれば、var1を1/100倍した値をnew_varとして定義することになる。また、“new_var = var1 – mean(var1)”という定義を用いれば、var1の観測値からvar1の平均値を引いた値をnew_varとしている。なお、このような操作化を一般的に「中心化」と呼ぶ。

mutate(data, new_var = definition)

mutate関数の利用においては、条件分岐を用いた変数の作成を行うこともある。そのように、研究者がある変数の値に応じて異なる値を変数を作成するときには、mutate内で、ifelse()関数を用いるのが良い。ifelse() 内の第一引数は条件、第二引数は条件が満たされたときの処理、第三引数は条件が満たされないときの処理をそれぞれ表す。なお、特定の条件の指定には “==” (同値), “>=”(以上), “<=”(以下) を使う。具体的には、var1 が2ならば1をとり、それ以外であれば0をとるという条件でnew_varを作成するという指示は、以下のようになる(以下は見本コードである)。

mutate(data, new_var = ifelse(var1 == 2, 1, 0))

filter関数は、データから特定の条件に合致する行だけ取り出す場合に用いる関数である。例えば、男性(gender == “male”)のサンプル情報のみ抽出したい場合には以下のような指示になる。

filter(data, gender == "male")

なお、特定の条件以外のものを指定したいときは、 という論理式 “!=” (not equal) を使う。男性以外の行を選ぶための指示は、以下の通りになる。

filter(data, gender != "male")

select関数は、特定の変数(列)を選んで新たなデータフレームを作成することができる関数である。例えば、dataというデータセットから、var1、var2、var3 という変数(列)を抽出して、data2というdataframeとして定義するには、以下のような指示になる。

data2<- select(data, var1, var2, var3)

反対に、取り除きたい変数を指定するときには、以下のように “-” を使う。

data2<- select(data, -var1)

列の指定方法には、いくつかのやり方が存在する。並んでいる列をまとめて指定するときは:(コロン)を使う。例えば、var1からvar5までの列をまとめて抽出し、それをdata2として定義するのは以下のようにできる。

data2<- select(data, var1:var5)

また、tidyverseのstarts_with()(ends_with())を使うことで、変数名の冒頭(末尾)が特定の文字列から始まる変数を指定するようなことも可能である。例えば、“v” という文字から始まる変数を取り出すための指示は、いかのようになる。

data3<- select(data, starts_with("v"))

arrangeは、データの並べかえを可能にする関数である。例えば、以下ではvar1の値が小さい順(昇順)に並べ替えるような指示を示す。一方で、降順にする場合は、desc(var1)と引数を指定する必要がある。

data2 <- arrange(data, var1) 
data2 <- arrange(data, desc(var1)) 

また、tidyverse環境において、変数名を変更することも、rename() 関数で可能になる。

data3 <- rename(data2, var1 = sales)

Tidyverse 内の dplyr を使うことでパイプ演算子(%>%)が使える(ショートカット: Command (control) + Shift + m)。パイプ演算子は、左側の処理結果を演算子右側の関数の第一引数として利用するための指示である。たとえば、以下のコマンドではまず \(\small 10-6\) が計算され、その結果である “4” が sqrt() の引数として利用される(sqrt(4) は 2)。

(10-6) %>% sqrt()
## [1] 2

パイプ演算子は、複数のデータ操作処理を連続して行う際に便利である。例えば、顧客の情報を含むデータセット(data)から、男性に該当する情報のみを抽出し、var1(例、購買額)についてのランキングを作成したうえでいくつかの変数を含んだデータセット(new_data)を作成する場合を考える。その際に実行すべき作業とそれらに対応する関数は以下のように示すことができる。

  1. 男性の情報だけ抜き出す(filter)
  2. Var1の値について降順に並べ替える(arrange)
  3. 第一位から最下位までの順位を割り当てた ranking 変数を作る(mutate)
  4. var1 , var2, var3, var4, orderだけ残し(select) new_dataとして定義する

上記の作業を一気に行うためのコードをパイプ演算子を使わずに書くと以下の様になる(以下は見本コード)。

new_data <- select(
 mutate(
  arrange(
   filter(data, gender == "male"),
   desc(var1)),
   ranking = 1:n()),
  var1, var2, var3, var4, order)

パイプ演算子を使わない場合、先に実行する処理が内側に来ており、一見して何を行っているのか理解するのが難しい。一方でパイプ演算子を使い、左側の処理結果を演算子右側の関数の第一引数として利用すると、以下のように書き換えることができる。

new_data <- data %>%
 filter(gender == "male")%>%
 arrange(desc(var1)) %>%
 mutate(ranking = 1:n()) %>% 
 select(var1, var2, var3, var4, order)

パイプ演算子の利用により、各関数の処理を一つの行で示せる。また、処理の順番通りに関数を記載することが可能なので、コードの記述容易性と可読性の両方が高まる。また、パイプ演算子による操作は次の関数の第一引数以外に反映されることも可能である。第一引数以外の引数に左側の処理結果を反映させる際には、該当する箇所に “.” (ドット)を使う。たとえば、\(\small 10-2\)の計算結果を用いて2から8の偶数で構成されるベクトルを返すためのコードは以下のように書くことができる。

(10-2) %>% 
  seq(from = 2, to = ., by = 2)
## [1] 2 4 6 8

データの整形・処理作業が終わったら、そのデータを自身のコンピュータ内のストレージに保存したいと考えるかもしれない。Rでは、外部への書き出しという形でデータを保存することが可能である。例えば、df という名前のデータフレームをnew_dataというファイル名で、dataというディレクトリにcsv形式を用いて保存するためには、以下のようなコードを用いる(以下は見本コード)。また、csv以外にもファイル形式は選択可能であり、例えばRのデータ形式(.Rds)で保存する場合には、“#Rds” 以降のコードを用いる。

readr::write_csv(df, path = "data/new_data.csv")

#Rds
readr::write_rds(df, path = "data/new_data.Rds")