いずにゃんの研究日記

専門性を広げるための練習場

日本語データの入ったcsvを読む込む(Windowsの場合)

今回はたぶんWindows限定の内容な気がする。RStudioはVersion 1.0.44を使用。


csvファイルを用意する

いつものように「ラブライブ!サンシャイン!!」から,スクールアイドルグループAqoursのメンバーのデータを使用する。

library(tidyverse)
dat <-
  data_frame(
    name=c("高海千歌","桜内梨子","松浦果南","黒澤ダイヤ","渡辺曜","津島善子","国木田花丸","小原鞠莉","黒澤ルビィ"),
    grade=c(2,2,3,3,2,1,1,3,1), #学年
    height=c(157,160,162,162,157,156,152,163,154), #身長
    B=c(82,80,83,80,82,79,83,87,76), #バスト
    W=c(59,58,58,57,57,58,57,60,56), #ウエスト
    H=c(83,82,84,80,81,80,83,84,79)  #ヒップ
  )

今回はこのデータをcsvファイルにエクスポートする。まずどこにファイルが出力されるか確認するために,現在の作業ディレクトリ(フォルダ)の確認をする。

getwd()

場所を変更したい場合は,以下のコードで指定できる。なおRStudioなら,Ctrl + Shift + Hのショートカットで同じことができる。

setwd(choose.dir()) 
#実行すると一見なにも起きてないようになるけど,画面下部のタスクバーに新しいプログラムが動作しているお知らせがでるので,それを開くと場所を指定できるはず。

次のコードでcsvファイルのエクスポート完了である。

write.csv(dat, "aqours.csv",row.names = FALSE)


csvファイルを読み込む

さて,それではRStudioの便利なImport Dataset機能を使ってcsvファイルを読み込んでみる。 詳しく知りたい方は↓を読むとしゅごいって思うに違いない。

qiita.com

下の図にあるように,Import DatasetのFrom CSVの部分をクリックすればよい

f:id:izunyan:20170205002020j:plain


csvファイルを開こうとしてみると,↓のような画面になる

f:id:izunyan:20170205002340j:plain


name変数の日本語が入ってるはずの列が意味不明な文字列に!

これは,実際にRの表示上もこのままなので,解析の際にとても困る。 じゃあどうしたらよいか,ということで色々ネット上で情報を探し見たら,解決法が見つかった。

demacassette2.hateblo.jp

つまり,Code Preview:の所に出てきたコードで,エンコードcp932に変更すればよい。 下図では,とりあえずEncodingをDefaultからUTF-8に変更し,コードプレビューに表示させ,そこに手動でcp932に置き換えてみている。

f:id:izunyan:20170205002607j:plain

下記のように,ファイルの場所の指定部分に加え,locale = locale(encoding = "cp932")という部分が追加されている。

aqours <- read_csv("ここにフォルダまでのパス/aqours.csv", 
    locale = locale(encoding = "cp932"))
aqours
# A tibble: 9 × 6
        name grade height     B     W     H
       <chr> <int>  <int> <int> <int> <int>
1   高海千歌     2    157    82    59    83
2   桜内梨子     2    160    80    58    82
3   松浦果南     3    162    83    58    84
4 黒澤ダイヤ     3    162    80    57    80
5     渡辺曜     2    157    82    57    81
6   津島善子     1    156    79    58    80
7 国木田花丸     1    152    83    57    83
8   小原鞠莉     3    163    87    60    84
9 黒澤ルビィ     1    154    76    56    79

この通り,ちゃんと読み込んで日本語を表示できた!

cp932というのは,Shift_JISの拡張版みたいなやつっぽい。だから,読み込むcsvファイルの文字エンコードShift_JISであることが前提になっているが,Windowsを使っていると多くの場合そうなっているのではないかと思う。

cp932はR Scriptを保存するときに出てくる,下の画面にも出てたことに気がついた。

f:id:izunyan:20170205010301j:plain

意味不明な記号数字・・・と思ってたデフォルトの指定はこのことだったのか!

ともあれ,これでやっとAqorsメンバーの名前が正常に読み込めた。

はじめてのggplot2(1):基本構造と散布図

タイトルはggplot2であるが,RStudioを起動したら迷わず,関連パッケージを一気に読み込んでくれるtidyverseパッケージをロードすればよい。

library(tidyverse)

いつものように「ラブライブ!サンシャイン!!」のスクールアイドルグループAqoursのメンバーのデータを使用する。

dat <-
  data_frame(
    name=c("高海千歌","桜内梨子","松浦果南","黒澤ダイヤ","渡辺曜","津島善子","国木田花丸","小原鞠莉","黒澤ルビィ"),
    grade=c(2,2,3,3,2,1,1,3,1), #学年
    height=c(157,160,162,162,157,156,152,163,154), #身長
    B=c(82,80,83,80,82,79,83,87,76), #バスト
    W=c(59,58,58,57,57,58,57,60,56), #ウエスト
    H=c(83,82,84,80,81,80,83,84,79)  #ヒップ
  )
dat

念のため,学年は因子型に変換しておく

dat$grade <- factor(dat$grade)


基本の構造

ggplot(data = dat) +
  geom_point(mapping = aes(x = height, y = B))

f:id:izunyan:20170129191703j:plain

大体身長とバストサイズが関連しているが,1名例外がいることが分かる。

まずggplot()で使うデータセットを指定し,geom_point()で点の散布図を描くという指定をしている。それぞれ情報を追加していく際に+でつなげるのが特徴である。geom_pointのpointの部分が変わると別の種類のグラフになる。aesとは,aesthetics(訳語は美学,美的感覚)のことで,視覚的な特性を定義する部分である。ここでは横軸をheight,縦軸をBと指定している。

上記コードの形が基本形だが,実際には色々省略可能であり,下記のように単純にできる。

ggplot(dat) +
  geom_point(aes(height, B))

や

ggplot(dat, aes(height, B)) +
  geom_point()

でも同じグラフが描ける。下のコードの方は,ggplot()の中にaesが入っている。


いろいろな散布図

散布図を学年で色分け

ggplot(data = dat) +
  geom_point(mapping = aes(x = height, y = B, color = grade))

f:id:izunyan:20170129191759j:plain

先ほどの点のプロットに,学年別に色を付けた。aes()の中の引数にcolor = gradeが追加されただけの操作である。それぞれのデータが学年とも関連している様子が読み取れる。


散布図を学年で記号分け

ggplot(data = dat) +
  geom_point(mapping = aes(x = height, y = B, shape = grade))

f:id:izunyan:20170129191812j:plain

色ではなくて記号で区別することもできる。こんどは,color =の所がshape =に変わっただけである。


テキストで散布図

ggplot(data = dat) +
  geom_text(mapping = aes(x = height, y = B, label = name))

f:id:izunyan:20170129191739j:plain

それぞれの点が誰のデータか把握するために,点を名前のデータで表示してみた。ここではいくつか変更点があり,geom_text()に変わっている点と,aes()の中の引数にlabel = nameが加わっている。

身長は最も低いのにバストサイズが中程度という,意図的な設定を感じざるを得ないキャラが,花丸ちゃんだということも判明する。あと,千歌ちゃんと曜ちゃんの身長とバストサイズが同じなので,文字が重なってしまっている。

はじめてのdplyr(4):キー変数で2つのデータを横に連結する

タイトルはdplyrであるが,RStudioを起動したら迷わず,関連パッケージを一気に読み込んでくれるtidyverseパッケージをロードすればよい。

library(tidyverse)


2つのデータの作成

過去の記事,

で紹介してきたデータセットは,Aqoursメンバーの名前という共通した変数nameがある。今回はnameをキー変数として,2つのデータを横に連結してみる。まずはデータを以下に再掲。

dat <-
  data_frame(
    name=c("高海千歌","桜内梨子","松浦果南","黒澤ダイヤ","渡辺曜","津島善子","国木田花丸","小原鞠莉","黒澤ルビィ"),
    grade=c(2,2,3,3,2,1,1,3,1), #学年
    height=c(157,160,162,162,157,156,152,163,154), #身長
    B=c(82,80,83,80,82,79,83,87,76), #バスト
    W=c(59,58,58,57,57,58,57,60,56), #ウエスト
    H=c(83,82,84,80,81,80,83,84,79)  #ヒップ
  )
dat
# A tibble: 9 × 6
        name grade height     B     W     H
       <chr> <dbl>  <dbl> <dbl> <dbl> <dbl>
1   高海千歌     2    157    82    59    83
2   桜内梨子     2    160    80    58    82
3   松浦果南     3    162    83    58    84
4 黒澤ダイヤ     3    162    80    57    80
5     渡辺曜     2    157    82    57    81
6   津島善子     1    156    79    58    80
7 国木田花丸     1    152    83    57    83
8   小原鞠莉     3    163    87    60    84
9 黒澤ルビィ     1    154    76    56    79

次はメンバーの名前とトリオユニット名のデータを作る。片方のデータにしかない行も追加して動きを確認してみたいため,2つ目のデータではAqoursメンバーに加えうちっちーも加えてみる。

dat_tu <-
  data_frame(
    name=c("高海千歌","桜内梨子","松浦果南","黒澤ダイヤ","渡辺曜","津島善子",
           "国木田花丸","小原鞠莉","黒澤ルビィ","うちっちー"),
    group=c("CYaRon!","Guilty Kiss","AZALEA","AZALEA","CYaRon!","Guilty Kiss",
            "AZALEA","Guilty Kiss","CYaRon!","solo") 
  )
dat_tu
# A tibble: 10 × 2
         name       group
        <chr>       <chr>
1    高海千歌    CYaRon!
2    桜内梨子 Guilty Kiss
3    松浦果南      AZALEA
4  黒澤ダイヤ      AZALEA
5      渡辺曜    CYaRon!
6    津島善子 Guilty Kiss
7  国木田花丸      AZALEA
8    小原鞠莉 Guilty Kiss
9  黒澤ルビィ    CYaRon!
10 うちっちー        solo


2つのデータの連結

それでは,名前を示している変数nameをキーとして,datデータにdat_tuの情報を横に連結してみる。datにない行もすべて追加するために,full_join()関数を使う。

dat_all <- full_join(dat,dat_tu,by="name")
dat_all
# A tibble: 10 × 7
         name grade height     B     W     H       group
        <chr> <dbl>  <dbl> <dbl> <dbl> <dbl>       <chr>
1    高海千歌     2    157    82    59    83    CYaRon!
2    桜内梨子     2    160    80    58    82 Guilty Kiss
3    松浦果南     3    162    83    58    84      AZALEA
4  黒澤ダイヤ     3    162    80    57    80      AZALEA
5      渡辺曜     2    157    82    57    81    CYaRon!
6    津島善子     1    156    79    58    80 Guilty Kiss
7  国木田花丸     1    152    83    57    83      AZALEA
8    小原鞠莉     3    163    87    60    84 Guilty Kiss
9  黒澤ルビィ     1    154    76    56    79    CYaRon!
10 うちっちー    NA     NA    NA    NA    NA        solo

一方,うちっちーはデータに謎が多すぎるから今回は連結しません,という場合はleft_join()関数を使って,datの方にある名前のみと連結させるとよい。

dat_aqours <- left_join(dat,dat_tu,by="name")
dat_aqours
# A tibble: 9 × 7
        name grade height     B     W     H       group
       <chr> <dbl>  <dbl> <dbl> <dbl> <dbl>       <chr>
1   高海千歌     2    157    82    59    83    CYaRon!
2   桜内梨子     2    160    80    58    82 Guilty Kiss
3   松浦果南     3    162    83    58    84      AZALEA
4 黒澤ダイヤ     3    162    80    57    80      AZALEA
5     渡辺曜     2    157    82    57    81    CYaRon!
6   津島善子     1    156    79    58    80 Guilty Kiss
7 国木田花丸     1    152    83    57    83      AZALEA
8   小原鞠莉     3    163    87    60    84 Guilty Kiss
9 黒澤ルビィ     1    154    76    56    79    CYaRon!

因子型(factor型)の水準操作が便利になるforcatsパッケージ

カテゴリ変数を扱う際に,因子型(factor型)の理解が必要になるが,最初は扱いに苦労する。しかし,それを解決するパッケージがあるらしい。

{forcats}パッケージでカテゴリカル変数(factor型データ)をいじってみる

これは便利!ということで,おなじみのラブライブ!サンシャイン!!のデータを使って試してみた。今回はトリオユニット名のデータを使用してみる。

dat_tu <-
  data.frame(
    name=c("高海千歌","桜内梨子","松浦果南","黒澤ダイヤ","渡辺曜","津島善子",
           "国木田花丸","小原鞠莉","黒澤ルビィ"),
    group=c("CYaRon!","Guilty Kiss","AZALEA","AZALEA","CYaRon!","Guilty Kiss",
            "AZALEA","Guilty Kiss","CYaRon!") #トリオユニット名
  )

library(tidyverse)
dat_tu <- tbl_df(dat_tu)
dat_tu
# A tibble: 9 × 2
        name       group
      <fctr>      <fctr>
1   高海千歌    CYaRon!
2   桜内梨子 Guilty Kiss
3   松浦果南      AZALEA
4 黒澤ダイヤ      AZALEA
5     渡辺曜    CYaRon!
6   津島善子 Guilty Kiss
7 国木田花丸      AZALEA
8   小原鞠莉 Guilty Kiss
9 黒澤ルビィ    CYaRon!

(2017/02/15修正) tbl_df()関数を使ってtibble形式にすると,data.frameでそのまま読みこんだので文字データが自動的に<fctr>,つまり因子型になっていた。変数nameも因子型になっているのは問題かもしれないが,このデータ数なのでとりあえずよしとする。因子型にしたくない場合は,引数にstringsAsFactors = FALSEといれればよい。ちなみに,data_frame()関数でtibble形式にすると,文字型<chr>のままで読み込まれる。

dat_tu$group
[1] CYaRon!    Guilty Kiss AZALEA      AZALEA      CYaRon!    Guilty Kiss AZALEA      Guilty Kiss
[9] CYaRon!   
Levels: AZALEA CYaRon! Guilty Kiss

Levels: にあるとおり,水準の順番はアルファベット順になっている。つまり,1=AZALEA, 2=CYaRon!, 3=Guilty Kissという対応関係である。これはunclass()で確認できる。

unclass(dat_tu$group)
[1] 2 3 1 1 2 3 1 3 2
attr(,"levels")
[1] "AZALEA"      "CYaRon!"    "Guilty Kiss"


水準を指定して並び変える

それではforcatsを使用してみる。まずは,fct_relevel()関数を使用して,ユニット名の水準をCDリリース順に並び変えてみる。この先もその順番を基本とする。

library(forcats)
dat_tu$group <- fct_relevel(dat_tu$group, "CYaRon!")
dat_tu$group
[1] CYaRon!    Guilty Kiss AZALEA      AZALEA      CYaRon!    Guilty Kiss AZALEA      Guilty Kiss
[9] CYaRon!   
Levels: CYaRon! AZALEA Guilty Kiss

いまの順番からだと,CYaRon!が一番最初に移動すれば解決するので,引数に指定するのはそれだけである。自分の指定したい順にするには,それぞれ水準名を追加していけばよい。たとえば,

fct_relevel(dat_tu$group, "Guilty Kiss", "AZALEA")
[1] CYaRon!    Guilty Kiss AZALEA      AZALEA      CYaRon!    Guilty Kiss AZALEA      Guilty Kiss
[9] CYaRon!   
Levels: Guilty Kiss AZALEA CYaRon!


水準の順番を逆にする

これにはfct_rev()関数を使う。現在の並びはLevels: CYaRon! AZALEA Guilty Kissであるから,逆順にすると最初と最後が入れ替わるだけである。

fct_rev(dat_tu$group)
[1] CYaRon!    Guilty Kiss AZALEA      AZALEA      CYaRon!    Guilty Kiss AZALEA      Guilty Kiss
[9] CYaRon!   
Levels: Guilty Kiss AZALEA CYaRon!


日本語を試してみる

水準が多いと複雑になるので,1年生の名前だけで試してみる。まずは公式サイトプロフィール出現順にデータを入力してみる。

first <- factor(c("津島善子", "国木田花丸", "黒澤ルビィ"))
first
[1] 津島善子   国木田花丸 黒澤ルビィ
Levels: 国木田花丸 黒澤ルビィ 津島善子

水準の順番は,法則がよく分からないけど,とりあえず入力した順番と違うようだ。ここでforcatsの出番である。

fct_relevel(first, "津島善子")
[1] 津島善子   国木田花丸 黒澤ルビィ
Levels: 津島善子 国木田花丸 黒澤ルビィ

とりあえず問題なく動いてくれた。次は逆順にしてみる。順番は最初に作ったfirstの通りだから,花丸→ルビィ→善子の逆になるはず。

fct_rev(first)
[1] 津島善子   国木田花丸 黒澤ルビィ
Levels: 津島善子 黒澤ルビィ 国木田花丸

こちらも問題ない。

RでAnime APIから季節のアニメ情報を読み込んで一覧できるデータフレームにする

3か月ごとに,アニメの新番組チェックが忙しくなる時期がやってくる。 こんなとき,放映されるアニメ番組一覧の情報を手軽に作成できたら便利である。 それがRでできたらさらに心健やかになるに違いない。

アニメ番組一覧の情報について,アニメとITの融合「Anitech」を 促進している秋葉原IT戦略研究所さまがとても素晴らしい 仕組みを提供している。

qiita.com

これにアクセスすれば,JSON形式で様々なアニメ番組情報が取得できる。 以下,Rでどうやって行うかを解説する。なお,R Studioを使用している。


RからAnime APIを呼び出す

library(RCurl)

getURL()関数で読み込む先のURLを指定する。 ここでは,2017年の冬アニメを指定しているので,URLの末尾が/2017/1となっている。ここの西暦(2014年以降)と最後の番号(1~4)を変えれば,他の季節のアニメ情報も取得できる。

getdata.json <- getURL('http://api.moemoe.tokyo/anime/v1/master/2017/1')

これでJSON形式の情報はRに読み込めた。しかし,Rでこれを閲覧するためには,まずJSON形式からlist形式に変換する必要がある。そこで登場するのが次のパッケージである。

library(rjson)

変換は次のコードの通りである。

getdata.list <- fromJSON(getdata.json)

少し出力が長くなってしまうがstr()を使うとどういうデータが 読み込まれているのか,listの構造を把握できる。

str(getdata.list)

最初の1作品の結果を示すと,

List of 40
 $ :List of 15
  ..$ title_short2    : chr ""
  ..$ twitter_account : chr "anime_aimaimi"
  ..$ public_url      : chr "http://www.dreamcreation.co.jp/aimaimi3/"
  ..$ title_short1    : chr "あいまいみ"
  ..$ sex             : num 0
  ..$ twitter_hash_tag: chr "あいまいみー"
  ..$ id              : num 475
  ..$ sequel          : num 3
  ..$ created_at      : chr "2017-01-03 01:10:03.0"
  ..$ city_name       : chr ""
  ..$ cours_id        : num 13
  ..$ title           : chr "ちょぼらうにょぽみ劇場第三幕 あいまいみー~Surgical Friends~"
  ..$ city_code       : num 0
  ..$ title_short3    : chr ""
  ..$ updated_at      : chr "2017-01-03 01:10:03.0"

のようになる。しかしこれでは少し中身が把握しづらい。 こんなときに便利なのが,listviewerパッケージである。

qiita.com

library(listviewer)
jsonedit(getdata.list)

と実行すると,以下のようにRstudio内で見やすい形式に中身を 確認して,listの構造も確認できる。

f:id:izunyan:20170108200619j:plain


listから必要なデータを抜き出して,データフレームにする

1つのアニメ作品に様々な情報が付与されているので,分かりやすくするためとりあえず,3つの変数(作品名,webサイトURL,twitterアカウント) として情報を抜き出してみる。これにはlapplyを使う。

Title <- as.character(lapply(getdata.list, '[[','title'))
Web <- as.character(lapply(getdata.list, '[[','public_url'))
Twitter <- as.character(lapply(getdata.list, '[[','twitter_account'))

ここの'[['というのが最初よく理解できないと思うが,詳しい説明は

複数の行列、データフレームからなるリストの各成分から特定要素を抽出する (from r-help, 2004.09.17)

などを参照すると分かるかもしれない。あとは,この3つの変数(ベクトル)をデータフレームにまとめるだけである。データ表示に便利なtibble形式にする。

library(dplyr)
dat <- data_frame(title=Title,web=Web,twitter=Twitter)
dat

f:id:izunyan:20170108200711j:plain

環境によっては長くなっている部分の変数名は省略されて表示されているかもしれないが,これで今季のアニメ視聴に役立つリストがデータフレームとして作成できた。あとはcsvで出力するなど好きなように使えばよい。


追記(2017/02/12)

申し遅れてしまったが,本記事のコードは以下の解説を大いに参考にさせていただいている。RESAS-APIについてもその内まとめてみたい。

qiita.com

はじめてのtidyr(1):データをwideからlongにする,その逆も

サンプルデータは下記記事を参照。

izunyan.hatenablog.com

        name grade height  B  W  H
1   高海千歌     2    157 82 59 83
2   桜内梨子     2    160 80 58 82
3   松浦果南     3    162 83 58 84
4 黒澤ダイヤ     3    162 80 57 80
5     渡辺曜     2    157 82 57 81
6   津島善子     1    156 79 58 80
7 国木田花丸     1    152 83 57 83
8   小原鞠莉     3    163 87 60 84
9 黒澤ルビィ     1    154 76 56 79

このように,1行に1人のデータが入っているのがよく見るデータの形であるが,解析によっては1人のデータを数行にわたらせるときがある。たとえば,複数の測定時点の変数がt1, t2, t3…と変数としてあり,それをtimeという1つの変数にまとめて縦に値を表示させたいといった場合などである。

ここではあまりあてはまらないかもしれないが,強引に身長とスリーサイズを1つの変数で表したいとする。

つまり,横長(wide)データを縦長(long)データに変換する。そんなときに便利なのがtidyrパッケージである。チートシートでは,"Reshaping Data"の部分に出てくる。

tidyrが入っていない人は,ネットにつながった環境で以下を実行

install.packages("tidyr")

まずはtidyrを読み込む。なお,%>%演算子を使うので,dplyrも読み込む。

library(tidyr)
library(dplyr)


wideからlongへの変換

wideからlongへの変換はgather( )で行う。 新しい変数bodyにheight, B, W, Hという変数名が値として入り,同じく新しい変数valueに先ほどの変数名の対応するデータが入るという構造である。nameとgradeには-をつけたが,これは変換せずそのまま残す際の記号である。

dat_long <- dat %>% gather(body,value,-name,-grade)
dat_long

次のようなデータ構造に変換された。

         name grade   body value
1    高海千歌     2 height   157
2    桜内梨子     2 height   160
3    松浦果南     3 height   162
4  黒澤ダイヤ     3 height   162
5      渡辺曜     2 height   157
6    津島善子     1 height   156
7  国木田花丸     1 height   152
8    小原鞠莉     3 height   163
9  黒澤ルビィ     1 height   154
10   高海千歌     2      B    82
11   桜内梨子     2      B    80
12   松浦果南     3      B    83
13 黒澤ダイヤ     3      B    80
14     渡辺曜     2      B    82
15   津島善子     1      B    79
16 国木田花丸     1      B    83
17   小原鞠莉     3      B    87
18 黒澤ルビィ     1      B    76
19   高海千歌     2      W    59
20   桜内梨子     2      W    58
21   松浦果南     3      W    58
22 黒澤ダイヤ     3      W    57
23     渡辺曜     2      W    57
24   津島善子     1      W    58
25 国木田花丸     1      W    57
26   小原鞠莉     3      W    60
27 黒澤ルビィ     1      W    56
28   高海千歌     2      H    83
29   桜内梨子     2      H    82
30   松浦果南     3      H    84
31 黒澤ダイヤ     3      H    80
32     渡辺曜     2      H    81
33   津島善子     1      H    80
34 国木田花丸     1      H    83
35   小原鞠莉     3      H    84
36 黒澤ルビィ     1      H    79

分かりにくいので,名前でソートしてみる。

dat_long %>% arrange(name)
         name grade   body value
1    高海千歌     2 height   157
2    高海千歌     2      B    82
3    高海千歌     2      W    59
4    高海千歌     2      H    83
5  国木田花丸     1 height   152
6  国木田花丸     1      B    83
7  国木田花丸     1      W    57
8  国木田花丸     1      H    83
9  黒澤ダイヤ     3 height   162
10 黒澤ダイヤ     3      B    80
11 黒澤ダイヤ     3      W    57
12 黒澤ダイヤ     3      H    80
13 黒澤ルビィ     1 height   154
14 黒澤ルビィ     1      B    76
15 黒澤ルビィ     1      W    56
16 黒澤ルビィ     1      H    79
17   桜内梨子     2 height   160
18   桜内梨子     2      B    80
19   桜内梨子     2      W    58
20   桜内梨子     2      H    82
21   小原鞠莉     3 height   163
22   小原鞠莉     3      B    87
23   小原鞠莉     3      W    60
24   小原鞠莉     3      H    84
25   松浦果南     3 height   162
26   松浦果南     3      B    83
27   松浦果南     3      W    58
28   松浦果南     3      H    84
29   津島善子     1 height   156
30   津島善子     1      B    79
31   津島善子     1      W    58
32   津島善子     1      H    80
33     渡辺曜     2 height   157
34     渡辺曜     2      B    82
35     渡辺曜     2      W    57
36     渡辺曜     2      H    81

このように,1名につき4行のlongなデータ構造に変換された。 つまり,9名×4で36行のデータとなった。


longからwideへの変換

これを逆にlongからwideに変換したいときはspread( )を使う。横長に並べなおす部分の変数だけ( )内に並べる

dat_long %>% spread(body,value) 

これでlongからwideに変換された。つまり元に戻った。

        name grade height  B  W  H
1   高海千歌     2    157 82 59 83
2   桜内梨子     2    160 80 58 82
3   松浦果南     3    162 83 58 84
4 黒澤ダイヤ     3    162 80 57 80
5     渡辺曜     2    157 82 57 81
6   津島善子     1    156 79 58 80
7 国木田花丸     1    152 83 57 83
8   小原鞠莉     3    163 87 60 84
9 黒澤ルビィ     1    154 76 56 79

はじめてのdplyr(2):平均値を算出しデータセットに追加,層別の計算も

前回の

izunyan.hatenablog.com

の続きを解説する。サンプルデータは上記記事を参照。

まずは,単純に身長の平均値をheightmという名前で作成してみる。 チートシートでは,"Summarise Data"の部分。

dat %>% summarise(heightm=mean(height))
   heightm
1 158.1111


算出した平均値を変数としてデータセットに追加する

算出した値を新たに変数として付け加えたい場合は,mutate( )を使う。 チートシートでは,"Make New Variables"の部分。

dat %>% mutate(heightm=mean(height))
        name grade height  B  W  H  heightm
1   高海千歌     2    157 82 59 83 158.1111
2   桜内梨子     2    160 80 58 82 158.1111
3   松浦果南     3    162 83 58 84 158.1111
4 黒澤ダイヤ     3    162 80 57 80 158.1111
5     渡辺曜     2    157 82 57 81 158.1111
6   津島善子     1    156 79 58 80 158.1111
7 国木田花丸     1    152 83 57 83 158.1111
8   小原鞠莉     3    163 87 60 84 158.1111
9 黒澤ルビィ     1    154 76 56 79 158.1111


層別・グループ別に計算

group_by( )を使うと,層・グループ別に処理が行える。そして,ここで %>%演算子の真価が発揮される。学年ごとに身長を出してみる場合は次のようになる。チートシートでは,"Group Data"の部分。

dat %>% group_by(grade) %>% summarise(heightm=mean(height))
# A tibble: 3 × 2
  grade  heightm
  <dbl>    <dbl>
1     1 154.0000
2     2 158.0000
3     3 162.3333

これらの平均値をデータセットに変数として追加したい場合は 次のようにする。

dat %>% group_by(grade) %>% mutate(heightm=mean(height))
        name grade height     B     W     H  heightm
      <fctr> <dbl>  <dbl> <dbl> <dbl> <dbl>    <dbl>
1   高海千歌     2    157    82    59    83 158.0000
2   桜内梨子     2    160    80    58    82 158.0000
3   松浦果南     3    162    83    58    84 162.3333
4 黒澤ダイヤ     3    162    80    57    80 162.3333
5     渡辺曜     2    157    82    57    81 158.0000
6   津島善子     1    156    79    58    80 154.0000
7 国木田花丸     1    152    83    57    83 154.0000
8   小原鞠莉     3    163    87    60    84 162.3333
9 黒澤ルビィ     1    154    76    56    79 154.0000


層別・グループ別にすべての変数の平均値を算出

このように,%>%は複数の関数をつなげて実行してくれる。1行に並べて書くと長くなるので,%>%の後で改行して複数行に渡り書くこともできる。今まで解説してきた内容に加え,新しくすべての変数に対する処理を行うsummarise_each( )を使い,学年ごとに身長とスリーサイズの平均値を一気に算出するコードを書いてみる。

dat %>% group_by(grade) %>%
        select(-name, -grade) %>%
        summarise_all(funs(mean))
# A tibble: 3 × 5
  grade   height        B        W        H
  <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1     1 154.0000 79.33333 57.00000 80.66667
2     2 158.0000 81.33333 58.00000 82.00000
3     3 162.3333 83.33333 58.33333 82.66667

名前と学年は平均値を出しても意味がないので,select( )で省いている



変更履歴

2016/12/26 誤字修正
2017/07/09 チートシートの部分を打ち消し;summarise_eachがdeprecatedになったのでsummarise_allに変更