Data Manipulation and Handling

カテゴリカル変数をダミー変数にする

  • nnetパッケージ(ニューラルネットワーク)に含まれているclass.ind()関数を利用
  • 0 = 棄権; 1 = 投票という「投票有無」という変数を「棄権」と「投票」という二つのダミー変数にするにはclass.ind(投票有無)
  • 返される値はデータフレーム型

dplyrを使ってみる

  • 実習用のデータセットは
url <- "http://jaysong.net/2014-07-08.csv"
download.file(url, dest ="sample_data.csv")
df <- read.csv("sample_data.csv", header = TRUE, stringsAsFactors = FALSE)
  • 大きなデータはdata.frameよりdata.tableが効率的なので
library(dplyr)
dt <- tbl_df(df)

変数の選択(select)

  • 普段ならsubset()とかを使って一部の変数を抽出するが、dplyrを使うと
select(dt, X, size, country)
  • のような命令で簡単にできる。ちなみに
  • select(dt, -X)ならXを除く。複数の変数ならselect(dt, -c(X, size, country))のように
  • また、select(dt, X:size)select(dt, -(X:size))なども出来る

指定した値と一致するケースのみ抽出(filter)

  • もしdplyrを使わずにpackageが"swirl"のケースのみが抽出したいなら
dt[which(dt$package == "swirl"), ]
  • と打てばいい。

  • dplyrを使うともっと楽になる

filter(dt, package == "swirl")
  • 複数のフィルターを適用したいなら
filter(dt, package == "swirl", country == "US")
  • 上記のコンマはand演算子だが、もしor演算子が使いたいなら
filter(dt, country == "US" | country == "IN")
  • 欠損値の除いたケースのみが見たいなら
filter(dt, !is.na(r_version))

指定した変数を基準にソートする(arrange)

  • dplyrなしなら
dt[order(dt$ip_id), ]
  • dplyrを使うなら
arrange(dt, ip_id)
  • だけで十分
  • 逆は arrange(dt, desc(ip_id))
  • もちろん複数の変数を基準にソートすることも可能
  • arrange(dt, ip_id, country)とかarrange(dt, ip_id, desc(country))などなど

計算結果から新しい変数を作成する(mutate)

sizeをMBに変換し、size_mbという新しい変数に格納する

mutate(dt, size_mb = size / 2^20)
  • もちろん
mutate(dt, size_mb = size / 2^20, size_gb = size_mb / 2^10)
  • などもできる

統計量を見る(summarize)

  • もし、sizeの平均値が見たいならmean(dt$size)
  • dplyrを使うなら
summarize(dt, avg_size = mean(size))
  • むしろ長くなったが、色んな組合せができ、data.frame型に返還されるから使い勝手がいい

変数でグループ化する(group_by)

  • countryごとにsizeの平均と標準偏差が見たい場合は
by_country <- group_by(dt, country)
summarize(by_country, mean(size), sd(size))
  • mean()とかsd()以外にも個数(n())、ユニークな値の個数(n_distinct())などがある

グループ化し、抽出し、要約し、整列し…(chaining)

  • 以下のような例を考えてみる
step1 <- group_by(dt, country)
step2 <- summarize(step2, unique = n_distinct(ip_id), avg_size = mean(size))
step3 <- filter(step1, size > 10000)
step4 <- arrange(step3, desc(size))
print(step4)
  • これは以下のコードと同じ機能を果たす
arrange(
        filter(
               summarize(
                         group_by(dt, country),
                         unique = n_distinct(ip_id), avg_size = mean(size)),
               size > 10000),   
        desc(size))
  • もっと簡単にしたい!と思ったらchainingが役立つ
dt %>% group_by(country) %>% summarize(unique = n_distinct(ip_id), avg_size = mean(size)) %>% filter(size > 10000) %>% arrange(desc(size))
  • 左から順番に処理の順序を書くだけでいい。最初にデータセット(dt)を指定したので次からはデータセットは指定しなくてもいい。
  • 最後に %>% print を書いておくと結果の表示までされる。(なくてもいいが、オブジェクトに格納する場合は自動的に表示されないから、表示させたい場合は書いとく)