※資料作成は岩嵜航さん(東北大学)にご協力いただきました。

(左右キーで進みます!)

Return to HOME

もう少し高度なデータ解析へ!

1. 課題を見つける/仮説を立てる

2. 実験や観察をしてデータを集める

3. データを整理する

4. データを解析して仮説を検証する


  • 生データをプロットするだけではつまらない…
  • データの計算や解析もプログラミングで行おう!
Return to HOME

データを解析しよう

データ解析にはdplyrtidyrが便利

dplyrとtidyrとは

  • tidyverseパッケージ群の一つ
  • シンプルな関数がたくさん
  • 繋げて使う(piping)といろんな解析ができる

再現性が高まる!

同じデータ処理の繰り返しが楽!

(3回同じ操作をするならプログラミングするべし!)

Return to HOME

dplyrの使い方の基本!

パイプ演算子(%>%)で指示を繋げて使う

ショートカットも使える(Ctrl + Shift + m)

library(tidyverse)                 #読み込み
result = diamonds %>%              #diamondsのデータから
  select(carat, cut, price) %>%    #carat, cut, priceだけ抽出して
  filter(carat > 2) %>%            #carat > 2のデータを抽出して
  group_by(cut) %>%                #cutごとにグループにして
  summarise_all(mean) %>%          #すべての平均値を計算する
  print()                          #表示してみる
## # A tibble: 5 × 3
##   cut       carat  price
##   <ord>     <dbl>  <dbl>
## 1 Fair       2.30 11972.
## 2 Good       2.14 14629.
## 3 Very Good  2.12 15133.
## 4 Premium    2.16 14992.
## 5 Ideal      2.15 15589.
Return to HOME

さっそくやってみよう!

dplyrを使ってみよう!

【復習】まずはサンプルデータ(penguins)をインストール

install.packages("palmerpenguins")    #インストールは最初の1回でOK

【復習】インストールしたら読み込み

library(palmerpenguins)               #penguinsを読み込み
library(tidyverse)                    #tidyverseを読み込み
Return to HOME

dplyrを使ってみよう!

文法(1)データをざっくり眺める

  • head(【data.frameの名前】)
    • データフレームの 先頭7行を表示する
head(penguins)                        #penguinsの最初を見せて!
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

dplyrを使ってみよう!

文法(2)データの変数をリストアップする

  • str(【data.frameの名前】)
  • どの列を指定したらいいか調べるときに便利
str(penguins)                         #penguinsデータの変数を確認
## tibble [344 × 8] (S3: tbl_df/tbl/data.frame)
##  $ species          : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ island           : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ bill_length_mm   : num [1:344] 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
##  $ bill_depth_mm    : num [1:344] 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
##  $ flipper_length_mm: int [1:344] 181 186 195 NA 193 190 181 195 193 190 ...
##  $ body_mass_g      : int [1:344] 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
##  $ sex              : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
##  $ year             : int [1:344] 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
Return to HOME

dplyrを使ってみよう!

文法(3)指定した列を選び出す

  • select(【列名】)
    • 指定した 列名の列を選び出す
result = penguins %>%                    #penguinsのデータから
  select(species, bill_length_mm)        #species, bill_length_mm だけ選ぶ
head(result)                             #表示
## # A tibble: 6 × 2
##   species bill_length_mm
##   <fct>            <dbl>
## 1 Adelie            39.1
## 2 Adelie            39.5
## 3 Adelie            40.3
## 4 Adelie            NA  
## 5 Adelie            36.7
## 6 Adelie            39.3
Return to HOME

dplyrを使ってみよう!

文法(3)指定した列を選び出す

  • select(【列番号】)
    • 列番号でも指定できる
result = penguins %>%                    #penguinsのデータから
  select(1, 4)                           #1, 4列目を選ぶ
head(result)                             #表示
## # A tibble: 6 × 2
##   species bill_depth_mm
##   <fct>           <dbl>
## 1 Adelie           18.7
## 2 Adelie           17.4
## 3 Adelie           18  
## 4 Adelie           NA  
## 5 Adelie           19.3
## 6 Adelie           20.6
Return to HOME

dplyrを使ってみよう!

文法(3)指定した列を選び出す

  • select(starts_with(“【文字】”))
    • 部分一致でも指定できる
    • 文字は”“で囲むこと!
result = penguins %>%                    #penguinsのデータから
  select(starts_with("b"))               #bで始まる列を選ぶ
head(result)                             #表示
## # A tibble: 6 × 3
##   bill_length_mm bill_depth_mm body_mass_g
##            <dbl>         <dbl>       <int>
## 1           39.1          18.7        3750
## 2           39.5          17.4        3800
## 3           40.3          18          3250
## 4           NA            NA            NA
## 5           36.7          19.3        3450
## 6           39.3          20.6        3650
Return to HOME

dplyrを使ってみよう!

文法(3)指定した列を選び出す

  • select(-【列名】)
    • 除外したい列も設定できる(マイナス)
    • 複数の列を除外したい場合は、列名をベクトルで指定
result = penguins %>%                    #penguinsのデータから
  select(-c(species, island))            #speciesとisland以外
head(result)                             #表示
## # A tibble: 6 × 6
##   bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex     year
##            <dbl>         <dbl>             <int>       <int> <fct>  <int>
## 1           39.1          18.7               181        3750 male    2007
## 2           39.5          17.4               186        3800 female  2007
## 3           40.3          18                 195        3250 female  2007
## 4           NA            NA                  NA          NA <NA>    2007
## 5           36.7          19.3               193        3450 female  2007
## 6           39.3          20.6               190        3650 male    2007
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • islandとbody_mass_gを選んで表示してみよう
  • (次ページに答えがあります)
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • islandとbody_mass_gを選んで表示してみよう
result = penguins %>%                    #penguinsのデータから
  select(island, body_mass_g)            #islandとbody_mass_gを選ぶ
head(result)                             #表示
## # A tibble: 6 × 2
##   island    body_mass_g
##   <fct>           <int>
## 1 Torgersen        3750
## 2 Torgersen        3800
## 3 Torgersen        3250
## 4 Torgersen          NA
## 5 Torgersen        3450
## 6 Torgersen        3650
Return to HOME

dplyrを使ってみよう!

文法(4)特定の値の行を抽出する

  • filter(【列名】 == 【値】)
    • 完全一致は ==
    • 文字列は”“で囲む
result = penguins %>%                    #penguinsのデータから
  filter(species == "Gentoo")            #ジェンツーペンギンだけを抽出
head(result)                             #表示
## # A tibble: 6 × 8
##   species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>           <dbl>         <dbl>             <int>       <int>
## 1 Gentoo  Biscoe           46.1          13.2               211        4500
## 2 Gentoo  Biscoe           50            16.3               230        5700
## 3 Gentoo  Biscoe           48.7          14.1               210        4450
## 4 Gentoo  Biscoe           50            15.2               218        5700
## 5 Gentoo  Biscoe           47.6          14.5               215        5400
## 6 Gentoo  Biscoe           46.5          13.5               210        4550
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

dplyrを使ってみよう!

文法(4)特定の値の行を抽出する

  • filter(【列名】 %in% c(【値1】, 【値2】))
    • 複数の値も抽出できる
    • 複数の値はベクトルc(A, B, C)で与える
result = penguins %>%                            #penguinsのデータから
  filter(species %in% c("Chinstrap", "Gentoo"))  #ヒゲとジェンツーだけを抽出
head(result)                                     #表示
## # A tibble: 6 × 8
##   species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>           <dbl>         <dbl>             <int>       <int>
## 1 Gentoo  Biscoe           46.1          13.2               211        4500
## 2 Gentoo  Biscoe           50            16.3               230        5700
## 3 Gentoo  Biscoe           48.7          14.1               210        4450
## 4 Gentoo  Biscoe           50            15.2               218        5700
## 5 Gentoo  Biscoe           47.6          14.5               215        5400
## 6 Gentoo  Biscoe           46.5          13.5               210        4550
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

dplyrを使ってみよう!

文法(4)特定の値の行を抽出する

  • filter(【列名】 > 【値】)
    • 比較演算子も使える
result = penguins %>%                #penguinsのデータから
  filter(bill_length_mm < 45)        #bill_length_mmが45以下を抽出
head(result)                         #表示
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           36.7          19.3               193        3450
## 5 Adelie  Torgersen           39.3          20.6               190        3650
## 6 Adelie  Torgersen           38.9          17.8               181        3625
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

うまく抽出できたかな…?(1/2)

変数(result)を直接見る

  • Environment > resultをクリック
Return to HOME

うまく抽出できたかな…?(2/2)

【復習】試しにプロットしてみよう!

まずは何もしていないデータ(penguins)で!

  • data.frame…penguins
  • X軸…bill_length_mm
  • Y軸…bill_depth_mm
  • 色…species
  • (次ページに答えがあります)
Return to HOME

うまく抽出できたかな…?(2/2)

【復習】試しにプロットしてみよう!

gp = ggplot(data = penguins) +  
     geom_point(aes(x = bill_length_mm, y = bill_depth_mm, color = species))  
gp                                    
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_point()`).

Return to HOME

うまく抽出できたかな…?(2/2)

【復習】試しにプロットしてみよう!

今度は抽出したデータ(result)で!

  • data.frame…result
  • X軸…bill_length_mm
  • Y軸…bill_depth_mm
  • 色…species
  • (次ページに答えがあります)
Return to HOME

うまく抽出できたかな…?(2/2)

【復習】試しにプロットしてみよう!

gp = ggplot(data = result) +  
     geom_point(aes(x = bill_length_mm, y = bill_depth_mm, color = species))  
gp                                    

  • 45以下のデータだけになってますね!
Return to HOME

dplyrを使ってみよう!

文法(4)特定の値の行を抽出する

  • filter(【列名A】 > 【値】, 【列名B】 > 【値】)
    • AND(,)も使える
result = penguins %>%                
  filter(bill_length_mm < 45, bill_depth_mm > 16) 
head(result)                         
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           36.7          19.3               193        3450
## 5 Adelie  Torgersen           39.3          20.6               190        3650
## 6 Adelie  Torgersen           38.9          17.8               181        3625
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

うまく抽出できたかな…?

gp = ggplot(data = result) +  
     geom_point(aes(x = bill_length_mm, y = bill_depth_mm, color = species))  
gp                                    

Return to HOME

dplyrを使ってみよう!

文法(4)特定の値の行を抽出する

  • filter(【列名A】 > 【値】|【列名B】 > 【値】)
    • OR(|)も使える
result = penguins %>%                
  filter(bill_length_mm < 40| bill_length_mm > 50) 
head(result)                         
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           36.7          19.3               193        3450
## 4 Adelie  Torgersen           39.3          20.6               190        3650
## 5 Adelie  Torgersen           38.9          17.8               181        3625
## 6 Adelie  Torgersen           39.2          19.6               195        4675
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

うまく抽出できたかな…?

plotしてみる

gp = ggplot(data = result) +  
     geom_point(aes(x = bill_length_mm, y = bill_depth_mm, color = species))  
gp                                    

Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 2008年以降のDream島のメスの体重を種ごとに比較しよう
    • どの列のどの値を取り出したらいいか?
    • 何をX軸、Y軸にして可視化したらいいか?
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 2008年以降のDream島のメスの体重を種ごとに比較しよう
  • データ抽出は…
    • year > 2007 あるいは year >= 2008
    • island == “Dream”
    • sex == “female”
  • データ可視化は…
    • X軸 = species
    • Y軸 = body_mass_g
Return to HOME

dplyrを使ってみよう!

[練習問題]

result2 = penguins %>%                
  filter(year >= 2008, island == "Dream", sex == "female") 
head(result2)                      
## # A tibble: 6 × 8
##   species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>           <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Dream            37.3          17.8               191        3350
## 2 Adelie  Dream            36.9          18.6               189        3500
## 3 Adelie  Dream            38.9          18.8               190        3600
## 4 Adelie  Dream            35.7          18                 202        3550
## 5 Adelie  Dream            34            17.1               185        3400
## 6 Adelie  Dream            36.2          17.3               187        3300
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

dplyrを使ってみよう!

[練習問題]

gp = ggplot(data = result2) +  
     geom_point(aes(x = species, y = body_mass_g))  
gp                      

  • できた人は、種ごとに色を付けてみよう!
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 2008年以降のDream島のメスの体重を種ごとに比較しよう
gp = ggplot(data = result2) +  
     geom_point(aes(x = species, y = body_mass_g, color = species))  
gp                      

Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 2008年以降のDream島のメスの体重を種ごとに比較しよう
gp = ggplot(data = result2) +  
     geom_point(aes(x = species, y = body_mass_g, color = species),
                position = position_jitter(width = 0.1))  #横にばらつかせる
gp                    

Return to HOME

dplyrを使ってみよう!

文法(5−1)新しい列を作る/既存の列の値を変更する

  • mutate(【値】)
result = penguins %>%                 
  mutate(bill_length_mm/bill_depth_mm)  #(bill_length_mm)÷(bill_depth_mm)
head(result)                            
## # A tibble: 6 × 9
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 3 more variables: sex <fct>, year <int>,
## #   `bill_length_mm/bill_depth_mm` <dbl>
Return to HOME

dplyrを使ってみよう!

文法(5−1)新しい列を作る/既存の列の値を変更する

  • mutate(【値】)
result = penguins %>%                 
  mutate(bill_length_mm/bill_depth_mm)  #(bill_length_mm)÷(bill_depth_mm)
head(result)    
## # A tibble: 6 × 9
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 3 more variables: sex <fct>, year <int>,
## #   `bill_length_mm/bill_depth_mm` <dbl>
Return to HOME

dplyrを使ってみよう!

文法(5−1)新しい列を作る/既存の列の値を変更する

  • mutate(【列名】=【値】)
    • 列名も指定できる(既存の列名にすると上書き)
result = penguins %>%                   
  mutate(slenderness = bill_length_mm/bill_depth_mm)  #slendernessと名付ける
head(result)                         
## # A tibble: 6 × 9
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 3 more variables: sex <fct>, year <int>, slenderness <dbl>
Return to HOME

dplyrを使ってみよう!

文法(5−2)新しい列を作る/既存の列の値を変更する

  • mutate(【列名】=【値】)
    • if_elseで条件に応じた値も入れられる(2条件分岐)
result = penguins %>%                   
  mutate(large_small = if_else(
    body_mass_g  < 4000,  "<4000", ">4000"
  ))  # body_mass_g が4000未満か, TRUEなら"<4000", FALSEなら">4000"
  • Environment > resultで見てみよう!
Return to HOME

dplyrを使ってみよう!

文法(5−2)新しい列を作る/既存の列の値を変更する

  • mutate(【列名】=【値】)
    • case_whenで条件に応じた値も入れられる(3条件以上)
result = penguins %>%                   
  mutate(large_small =  case_when(
    flipper_length_mm > 200 & body_mass_g > 4000 ~ "long_large",
    flipper_length_mm < 200 & body_mass_g > 4000 ~ "short_large",
    flipper_length_mm > 200 & body_mass_g < 4000 ~ "long_small",
    flipper_length_mm < 200 & body_mass_g < 4000 ~ "short_small",
    TRUE                      ~ "others" #全て条件外の場合の指定
  ))  
  • Environment > resultで見てみよう!
  • large_smallの列は思ったとおりになってるか?
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • flipper_length_mm/body_mass_gを計算し、ratioという新しい列として加えよう
  • group列に、ratioが0.05以上の場合はlarge, 0.05未満の場合はsmallと入れよう
  • (次ページに答えがあります)
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • flipper_length_mm/body_mass_gを計算し、ratioという新しい列として加えよう
  • group列に、ratioが0.05以上の場合はlarge, 0.05未満の場合はsmallと入れよう
result = penguins %>%                                   
  mutate(ratio = flipper_length_mm/body_mass_g) %>% 
  mutate(group = if_else(ratio >= 0.05, "large", "small"))
head(result)                                            
## # A tibble: 6 × 10
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 4 more variables: sex <fct>, year <int>, ratio <dbl>, group <chr>
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(【関数名】(【列名】))
    • 使える関数はmean, median, sd, max, min, n, Q1, Q2…
result = penguins %>%                   
  summarize(mean(bill_length_mm))       #くちばしの長さを平均する
head(result)                           
## # A tibble: 1 × 1
##   `mean(bill_length_mm)`
##                    <dbl>
## 1                     NA
  • 値にNAが含まれているとNAを返す
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(【関数名】(【列名】))
    • na.rm = TRUEとするとNAを除外して計算してくれる
result = penguins %>%                           
  summarize(bill_length_mean = mean(bill_length_mm, na.rm = TRUE)) 
                                                #くちばしの長さを平均する
head(result)                                    
## # A tibble: 1 × 1
##   bill_length_mean
##              <dbl>
## 1             43.9
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(【関数名】(【列名】))
    • group_byを組み合わせるとすごく便利!
result = penguins %>%                           
  group_by(species) %>%                  #speciesごとにグループ分けして
  summarize(bill_length_mean = mean(bill_length_mm, na.rm = TRUE), 
            .groups     = "drop")        #グループわけ解除
head(result)                                    
## # A tibble: 3 × 2
##   species   bill_length_mean
##   <fct>                <dbl>
## 1 Adelie                38.8
## 2 Chinstrap             48.8
## 3 Gentoo                47.5
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(【関数名】(【列名】))
    • 複数の集計もできる!
result = penguins %>%                           
  group_by(species) %>%                  #speciesごとにグループ分けして
  summarize(bill_length_mean = mean(bill_length_mm, na.rm = TRUE),
            bill_depth_median = median(bill_depth_mm, na.rm = TRUE), #中央値
            .groups     = "drop")               
head(result)                                    
## # A tibble: 3 × 3
##   species   bill_length_mean bill_depth_median
##   <fct>                <dbl>             <dbl>
## 1 Adelie                38.8              18.4
## 2 Chinstrap             48.8              18.4
## 3 Gentoo                47.5              15
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(【関数名】(【列名】))
    • 複数のグループもできる!
result = penguins %>%                           
  group_by(species, island) %>%     #species, islandごとにグループ分けして
  summarize(bill_length_mean = mean(bill_length_mm, na.rm = TRUE),
            bill_depth_median = median(bill_depth_mm, na.rm = TRUE), #中央値
            .groups     = "drop")               
head(result)                                    
## # A tibble: 5 × 4
##   species   island    bill_length_mean bill_depth_median
##   <fct>     <fct>                <dbl>             <dbl>
## 1 Adelie    Biscoe                39.0              18.5
## 2 Adelie    Dream                 38.5              18.4
## 3 Adelie    Torgersen             39.0              18.4
## 4 Chinstrap Dream                 48.8              18.4
## 5 Gentoo    Biscoe                47.5              15
Return to HOME

dplyrを使ってみよう!

文法(6)数値を要約する

  • summarize(across(【列名のベクトル】, 【関数名】))
    • across()を使うと短く書ける
result = penguins %>%                           
  group_by(species, island) %>%     #species, islandごとにグループ分けして
  summarize(across(c(bill_length_mm, bill_depth_mm),  
                   c(mean, sd), na.rm = TRUE),
            .groups     = "drop")            
## Warning: There was 1 warning in `summarize()`.
## ℹ In argument: `across(c(bill_length_mm, bill_depth_mm), c(mean, sd), na.rm =
##   TRUE)`.
## ℹ In group 1: `species = Adelie` and `island = Biscoe`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
## 
##   # Previously
##   across(a:b, mean, na.rm = TRUE)
## 
##   # Now
##   across(a:b, \(x) mean(x, na.rm = TRUE))
head(result)                                    
## # A tibble: 5 × 6
##   species   island    bill_length_mm_1 bill_length_mm_2 bill_depth_mm_1
##   <fct>     <fct>                <dbl>            <dbl>           <dbl>
## 1 Adelie    Biscoe                39.0             2.48            18.4
## 2 Adelie    Dream                 38.5             2.47            18.3
## 3 Adelie    Torgersen             39.0             3.03            18.4
## 4 Chinstrap Dream                 48.8             3.34            18.4
## 5 Gentoo    Biscoe                47.5             3.08            15.0
## # ℹ 1 more variable: bill_depth_mm_2 <dbl>
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 種×性ごとのペンギンの体重の平均(mean)と分散(sd)を計算しよう
  • (次ページに答えがあります)
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 種×性ごとのペンギンの体重の平均(mean)と分散(sd)を計算しよう
result2 = penguins %>%                           
  group_by(species, sex) %>%     #species, sexごとにグループ分けして
  summarize(body_mass_mean = mean(body_mass_g, na.rm = TRUE), #mean
            body_mass_sd = sd(body_mass_g, na.rm = TRUE),     #sd
            .groups     = "drop") 
head(result2)                                    
## # A tibble: 6 × 4
##   species   sex    body_mass_mean body_mass_sd
##   <fct>     <fct>           <dbl>        <dbl>
## 1 Adelie    female          3369.         269.
## 2 Adelie    male            4043.         347.
## 3 Adelie    <NA>            3540          477.
## 4 Chinstrap female          3527.         285.
## 5 Chinstrap male            3939.         362.
## 6 Gentoo    female          4680.         282.
Return to HOME

dplyrを使ってみよう!

[練習問題]

  • 種ごとの体重の性差を棒グラフ±エラーバーで示そう
    • 棒グラフ…geom_col(x, y)
    • エラーバー…geom_errorbar(x, ymin, ymax)
      • ymin…【平均の列名】-【分散の列名】
      • ymax…【平均の列名】+【分散の列名】
      • width…0.2
    • 種ごとにfacet_wrap()かfacet_grid()でグラフを分ける
Return to HOME

dplyrを使ってみよう!

[練習問題]

gp = ggplot(data = result2) +  
     geom_col(aes(x = sex, y = body_mass_mean)) +
     geom_errorbar(aes(x = sex, 
                       ymin = body_mass_mean - body_mass_sd, 
                       ymax = body_mass_mean + body_mass_sd),
                       width = 0.2) +
     facet_wrap(~species)
gp                    

Return to HOME

dplyrを使ってみよう!

文法(7)複数のデータフレームを結合する

[練習問題] 準備として…

  • penguinsのspecies, bill_length_mmをデータフレームpenguins_1に格納
  • island, body_mass_gをデータフレームpenguins_2に格納
  • ちゃんとできているかhead()で確認
Return to HOME

dplyrを使ってみよう!

文法(7)複数のデータフレームを結合する

[練習問題] 準備として…

penguins_1 = penguins %>%
  select(species, bill_length_mm) %>%
  rownames_to_column() #行数を列にする
head(penguins_1)
## # A tibble: 6 × 3
##   rowname species bill_length_mm
##   <chr>   <fct>            <dbl>
## 1 1       Adelie            39.1
## 2 2       Adelie            39.5
## 3 3       Adelie            40.3
## 4 4       Adelie            NA  
## 5 5       Adelie            36.7
## 6 6       Adelie            39.3
Return to HOME

dplyrを使ってみよう!

文法(7)複数のデータフレームを結合する

[練習問題] 準備として…

penguins_2 = penguins %>%
  select(island, body_mass_g) %>%
  rownames_to_column() #行数を列にする
head(penguins_2)
## # A tibble: 6 × 3
##   rowname island    body_mass_g
##   <chr>   <fct>           <int>
## 1 1       Torgersen        3750
## 2 2       Torgersen        3800
## 3 3       Torgersen        3250
## 4 4       Torgersen          NA
## 5 5       Torgersen        3450
## 6 6       Torgersen        3650
Return to HOME

dplyrを使ってみよう!

文法(7)複数のデータフレームを結合する

  • に繋げるならbind_cols()に繋げるならbind_rows()
penguins_merge = 
  bind_cols(penguins_1, penguins_2) # peguins_1とpenguins_2を結合
## New names:
## • `rowname` -> `rowname...1`
## • `rowname` -> `rowname...4`
head(penguins_merge)
## # A tibble: 6 × 6
##   rowname...1 species bill_length_mm rowname...4 island    body_mass_g
##   <chr>       <fct>            <dbl> <chr>       <fct>           <int>
## 1 1           Adelie            39.1 1           Torgersen        3750
## 2 2           Adelie            39.5 2           Torgersen        3800
## 3 3           Adelie            40.3 3           Torgersen        3250
## 4 4           Adelie            NA   4           Torgersen          NA
## 5 5           Adelie            36.7 5           Torgersen        3450
## 6 6           Adelie            39.3 6           Torgersen        3650
Return to HOME

dplyrを使ってみよう!

文法(8)複数のデータフレームを列で紐付けて結合する

  • なんとか_join(【データフレーム1】, 【データフレーム2】, by = 【紐付けたい列名】)
- leftはデータフレーム1, rightはデータフレーム2のこと 
- left_joinは左に合わせる、right_joinは右に合わせる…
Return to HOME

dplyrを使ってみよう!

文法(8)複数のデータフレームを列で紐付けて結合する

  • なんとか_join(【データフレーム1】, 【データフレーム2】, by = 【紐付けたい列名】)
penguins_merge =
  left_join(penguins_1, penguins_2, by = "rowname") 
head(penguins_merge)
## # A tibble: 6 × 5
##   rowname species bill_length_mm island    body_mass_g
##   <chr>   <fct>            <dbl> <fct>           <int>
## 1 1       Adelie            39.1 Torgersen        3750
## 2 2       Adelie            39.5 Torgersen        3800
## 3 3       Adelie            40.3 Torgersen        3250
## 4 4       Adelie            NA   Torgersen          NA
## 5 5       Adelie            36.7 Torgersen        3450
## 6 6       Adelie            39.3 Torgersen        3650
Return to HOME

dplyrの文法まとめ

  • 文法(1)head() …データを見る
  • 文法(2)str()…変数のリストアップ
  • 文法(3)select()…列の抽出
  • 文法(4)filter()…特定の値の行の抽出
  • 文法(5−1)mutate()…新たな行を作る
  • 文法(5−2)mutate(if_else), mutate(casewhen)…条件分岐
  • 文法(6)summarize()…数値の要約
  • 文法(7−1)bind_cols()…横に結合
  • 文法(7−2)bind_rows()…縦に結合
  • 文法(8)なんとか_join()…特定の列で紐付けて結合

dplyrの文法まとめ

いよいよ難関の…tidyrを使ってみよう!

データの変形ができる最強ツール

  • 他人のデータの多くは そのまま使えない…
  • 手でコピペして新たなcsvを作るのはナンセンス
  • そんなときはtidyrで一気に変換!
  • ちょっとハードルは高いけど、使えるようになると 最強です
Return to HOME

いよいよ難関の…tidyrを使ってみよう!

tidyrでできること

  • 縦長←→横広の変換
  • セルの分割/結合
  • などなど…
Return to HOME

tidyrを使ってみよう!

文法(9−1)縦長のデータを横広に

  • pivot_wider(names_from = 【新しく列名になる列の名前】, values_from = 【動かしたい値の列の名前】)
penguins_wide = penguins %>%
  pivot_wider(names_from = year,         #yearの列を横に並べて列名に
              values_from = body_mass_g) #値にはbody_mass_g列の値が入る
head(penguins_wide)
## # A tibble: 6 × 9
##   species island    bill_length_mm bill_depth_mm flipper_length_mm sex    `2007`
##   <fct>   <fct>              <dbl>         <dbl>             <int> <fct>   <int>
## 1 Adelie  Torgersen           39.1          18.7               181 male     3750
## 2 Adelie  Torgersen           39.5          17.4               186 female   3800
## 3 Adelie  Torgersen           40.3          18                 195 female   3250
## 4 Adelie  Torgersen           NA            NA                  NA <NA>       NA
## 5 Adelie  Torgersen           36.7          19.3               193 female   3450
## 6 Adelie  Torgersen           39.3          20.6               190 male     3650
## # ℹ 2 more variables: `2008` <int>, `2009` <int>
Return to HOME

tidyrを使ってみよう!

文法(9−2)横広のデータを縦長に

  • pivot_longer(cols = 【動かしたい値が含まれている列】, names_to = 【元々列名だったものを入れる列の名前】, values_to = 【値の移動先の列名】)
penguins_long = penguins_wide %>%
  pivot_longer(cols = c(`2007`, `2008`, `2009`), #これらを縦に並べて値に
               names_to = "YEAR",                #新たな列名はYEAR(文字列なので""で囲む)
               values_to = "BODY_MASS_G")        #元々の値を入れる列名はBODY_MASS_Gに
head(penguins_long, n = 5)
## # A tibble: 5 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm sex    YEAR 
##   <fct>   <fct>              <dbl>         <dbl>             <int> <fct>  <chr>
## 1 Adelie  Torgersen           39.1          18.7               181 male   2007 
## 2 Adelie  Torgersen           39.1          18.7               181 male   2008 
## 3 Adelie  Torgersen           39.1          18.7               181 male   2009 
## 4 Adelie  Torgersen           39.5          17.4               186 female 2007 
## 5 Adelie  Torgersen           39.5          17.4               186 female 2008 
## # ℹ 1 more variable: BODY_MASS_G <int>
Return to HOME

tidyrを使ってみよう!

[練習問題]

  • くちばしの長さと幅を比較するグラフを書きたいとき…
    • 比較する値はX軸に示したい
Return to HOME

tidyrを使ってみよう!

[練習問題]

  • くちばしの長さと幅を比較するグラフを書きたいとき…
    • まずは元データがどうだったか確認する
    • くちばしの長さと幅を直接X軸に指定できない…
head(penguins)                        #penguinsデータを確認
## # A tibble: 6 × 8
##   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
## 1 Adelie  Torgersen           39.1          18.7               181        3750
## 2 Adelie  Torgersen           39.5          17.4               186        3800
## 3 Adelie  Torgersen           40.3          18                 195        3250
## 4 Adelie  Torgersen           NA            NA                  NA          NA
## 5 Adelie  Torgersen           36.7          19.3               193        3450
## 6 Adelie  Torgersen           39.3          20.6               190        3650
## # ℹ 2 more variables: sex <fct>, year <int>
Return to HOME

tidyrを使ってみよう!

[練習問題]

  • くちばしの長さと幅を比較するグラフを書きたいとき…
    • こんな形だったら、x = PARTS, y = VALUE で指定できる
## # A tibble: 688 × 3
##    species PARTS          VALUE
##    <fct>   <chr>          <dbl>
##  1 Adelie  bill_length_mm  39.1
##  2 Adelie  bill_depth_mm   18.7
##  3 Adelie  bill_length_mm  39.5
##  4 Adelie  bill_depth_mm   17.4
##  5 Adelie  bill_length_mm  40.3
##  6 Adelie  bill_depth_mm   18  
##  7 Adelie  bill_length_mm  NA  
##  8 Adelie  bill_depth_mm   NA  
##  9 Adelie  bill_length_mm  36.7
## 10 Adelie  bill_depth_mm   19.3
## # ℹ 678 more rows
Return to HOME

tidyrを使ってみよう!

[練習問題]

  • くちばしの長さと幅を比較するグラフを書きたいとき…
    • pivod_longerでpenguinsを変換しよう!
    • pivot_longer(cols = 【動かしたい値が含まれている列】, names_to = 【元々列名だったものを入れる列の名前】, values_to = 【値の移動先の列名】)
      • もともとの列名を入れる列の名前…“PARTS”
      • 値の移動先の列名…“VALUE”
      • 動かしたい列はどれ?
        • 複数はベクトルc(【列名1】, 【列名2】)で指定
Return to HOME

tidyrを使ってみよう!

[練習問題]

penguins2 = penguins %>%                                  #penguins2に格納
  pivot_longer(cols = c(bill_length_mm, bill_depth_mm),   #列を指定
               names_to = "PARTS", values_to = "VALUE")   #新たな列の名前
head(penguins2)
## # A tibble: 6 × 8
##   species island    flipper_length_mm body_mass_g sex     year PARTS       VALUE
##   <fct>   <fct>                 <int>       <int> <fct>  <int> <chr>       <dbl>
## 1 Adelie  Torgersen               181        3750 male    2007 bill_lengt…  39.1
## 2 Adelie  Torgersen               181        3750 male    2007 bill_depth…  18.7
## 3 Adelie  Torgersen               186        3800 female  2007 bill_lengt…  39.5
## 4 Adelie  Torgersen               186        3800 female  2007 bill_depth…  17.4
## 5 Adelie  Torgersen               195        3250 female  2007 bill_lengt…  40.3
## 6 Adelie  Torgersen               195        3250 female  2007 bill_depth…  18
  • できたらggplot2でグラフを作ろう!(geom_pointで)
Return to HOME

tidyrを使ってみよう!

[練習問題]

gp = ggplot(data = penguins2) +
  geom_point(aes(x = PARTS, y = VALUE)) +
  facet_wrap(~species)
gp
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).

Return to HOME

tidyrを使ってみよう!

文法(10)文字列カラムを複数に分割

  • separate(col = 【切り分けたい列の名前】, into = 【新しい列名】, sep = 【セパレータ】)
    • セパレータを指定しないと非アルファベットで切れる
    • 整数を渡すと位置で切れる(“A4”を1Lで切ると”A”と”4”に)
    • 詳しい使い方はこちらを参照
penguins2_sep = penguins2 %>%
  separate(col = PARTS, into = c("A", "B", "C"), sep = "_") 
                            #intoは文字列ベクターで
head(penguins2_sep)
## # A tibble: 6 × 10
##   species island    flipper_length_mm body_mass_g sex     year A     B     C    
##   <fct>   <fct>                 <int>       <int> <fct>  <int> <chr> <chr> <chr>
## 1 Adelie  Torgersen               181        3750 male    2007 bill  leng… mm   
## 2 Adelie  Torgersen               181        3750 male    2007 bill  depth mm   
## 3 Adelie  Torgersen               186        3800 female  2007 bill  leng… mm   
## 4 Adelie  Torgersen               186        3800 female  2007 bill  depth mm   
## 5 Adelie  Torgersen               195        3250 female  2007 bill  leng… mm   
## 6 Adelie  Torgersen               195        3250 female  2007 bill  depth mm   
## # ℹ 1 more variable: VALUE <dbl>
Return to HOME

tidyrを使ってみよう!

冗長だったX軸の値もスッキリ!

gp = ggplot(data = penguins2_sep) +
  geom_point(aes(x = B, y = VALUE)) +
  facet_wrap(~species)
gp
## Warning: Removed 4 rows containing missing values or values outside the scale range
## (`geom_point()`).

Return to HOME

tidyrを使ってみよう!

文法(11)複数の文字列カラムを結合

  • unite(col = 【新しい列名】, 【結合したい列名をベクターで】, sep = 【セパレータ】)
penguins2_unite = penguins2_sep %>%
  unite(col = "PARTS", c(A, B, C), sep = ".") 
head(penguins2_unite)
## # A tibble: 6 × 8
##   species island    flipper_length_mm body_mass_g sex     year PARTS       VALUE
##   <fct>   <fct>                 <int>       <int> <fct>  <int> <chr>       <dbl>
## 1 Adelie  Torgersen               181        3750 male    2007 bill.lengt…  39.1
## 2 Adelie  Torgersen               181        3750 male    2007 bill.depth…  18.7
## 3 Adelie  Torgersen               186        3800 female  2007 bill.lengt…  39.5
## 4 Adelie  Torgersen               186        3800 female  2007 bill.depth…  17.4
## 5 Adelie  Torgersen               195        3250 female  2007 bill.lengt…  40.3
## 6 Adelie  Torgersen               195        3250 female  2007 bill.depth…  18
Return to HOME

tidyrの文法まとめ

  • 文法(9−1)pivod_wider() …縦長を横広に
  • 文法(9−2)pivod_longer()…横広を縦長に
  • 文法(10)separate()…カラムを分割
  • 文法(11)unite()…カラムを結合
Return to HOME

tidyrの文法まとめ

dplyrとtidyrの使い方のおさらい!

パイプ演算子(%>%)で指示を繋げて使う

library(tidyverse)                 #読み込み
result = diamonds %>%              #diamondsのデータから
  select(carat, cut, price) %>%    #carat, cut, priceだけ抽出して
  filter(carat > 2) %>%            #carat > 2のデータを抽出して
  group_by(cut) %>%                #cutごとにグループにして
  summarise_all(mean) %>%          #すべての平均値を計算する
  print()                          #表示してみる
  • エラーを解決するコツは…
  • 一度にコードを走らせず、各行の%>%の前まで走らせる
  • head(result)で結果を見て、どこまでうまくいってるか調べる
  • エラーが出た行をよく見て間違いを探す
Return to HOME

dplyrとtidyrのまとめ

データを解析したいな

  • まずはどんなグラフを描きたいか考えよう
  • 次にどんなdata.frameがほしいか考えよう

どうやるんだっけ

  • 規則性のある形ならだいたいなんとかなる。
  • 具体的な方法を忘れたらググる!前のコードを使い回す!
  • めっちゃエラーが出るんですけど…

Step 5:自分のデータを扱おう

Return to HOME