5 データ解析に向けて

ここまでの解説で、Excelファイルとcsvファイルの読み込みについて一通り解説してきました。この段階では、まだデータがきれいでなくて、解析に入れないことも多いと思います。

5.1 要約値や欠損データの確認

まずどんなデータがどのように入っているか、欠損値(NA)はどれくらい発生しているか確認することは重要なプロセスです。変数の一覧を要約して確認することが簡単にできるskimパッケージのskimr()関数を使って確認してみましょう。データは2.1.1で読み込んだdfを使います。

library(skimr) # version 2.1.2
skim(df)
skim()の出力

Figure 5.1: skim()の出力

データの型が数値である変数(ここではVariable type:numeric)については、hist列に簡単なヒストグラムが表示されます(図5.1)。しかしデータが大量な場合、動作が遅くなります。その場合は、ヒストグラムを描かない以下の関数が使えます。

5.1.1 結果をExcelファイルに出力する

as_tibble()関数を使うことで、結果を一つのデータフレームにまとめることができます。

res_skim_df <- 
skim(df) |> 
  as_tibble()

res_skim_df |> 
  head()        # 最初の6行を表示
## # A tibble: 6 × 17
##   skim_…¹ skim_…² n_mis…³ compl…⁴ chara…⁵ chara…⁶ chara…⁷ chara…⁸
##   <chr>   <chr>     <int>   <dbl>   <int>   <int>   <int>   <int>
## 1 charac… species       0   1           6       9       0       3
## 2 charac… 種類          0   1           2       5       0       3
## 3 charac… island        0   1           5       9       0       3
## 4 charac… sex          11   0.968       4       6       0       2
## 5 numeric bill_l…       2   0.994      NA      NA      NA      NA
## 6 numeric bill_d…       2   0.994      NA      NA      NA      NA
## # … with 9 more variables: character.whitespace <int>,
## #   numeric.mean <dbl>, numeric.sd <dbl>, numeric.p0 <dbl>,
## #   numeric.p25 <dbl>, numeric.p50 <dbl>, numeric.p75 <dbl>,
## #   numeric.p100 <dbl>, numeric.hist <chr>, and abbreviated
## #   variable names ¹​skim_type, ²​skim_variable, ³​n_missing,
## #   ⁴​complete_rate, ⁵​character.min, ⁶​character.max,
## #   ⁷​character.empty, ⁸​character.n_unique

これで好きなように加工してExcelファイルとして出力することが可能になります。例えば、数値変数だけに絞る場合は

res_skim_df |> 
  filter(skim_type  == "numeric") |> 
  select(skim_type, skim_variable,
         n_missing, numeric.mean, numeric.sd)
## # A tibble: 5 × 5
##   skim_type skim_variable     n_missing numeric.mean numeric.sd
##   <chr>     <chr>                 <int>        <dbl>      <dbl>
## 1 numeric   bill_length_mm            2         43.9      5.46 
## 2 numeric   bill_depth_mm             2         17.2      1.97 
## 3 numeric   flipper_length_mm         2        201.      14.1  
## 4 numeric   body_mass_g               2       4202.     802.   
## 5 numeric   year                      0       2008.       0.818

また、group_by()を使ってグループ別に上記結果を出すことも可能です。

res_df_num_g <- 
df |> 
  group_by(種類) |> 
  skim() |> 
  as_tibble() |> 
  filter(skim_type  == "numeric") |> 
  select(skim_type, skim_variable, 種類,
         n_missing, numeric.mean, numeric.sd)

res_df_num_g
## # A tibble: 15 × 6
##    skim_type skim_variable     種類       n_mis…¹ numer…² numer…³
##    <chr>     <chr>             <chr>        <int>   <dbl>   <dbl>
##  1 numeric   bill_length_mm    アデリー         1    38.8   2.66 
##  2 numeric   bill_length_mm    ジェンツー       1    47.5   3.08 
##  3 numeric   bill_length_mm    ヒゲ             0    48.8   3.34 
##  4 numeric   bill_depth_mm     アデリー         1    18.3   1.22 
##  5 numeric   bill_depth_mm     ジェンツー       1    15.0   0.981
##  6 numeric   bill_depth_mm     ヒゲ             0    18.4   1.14 
##  7 numeric   flipper_length_mm アデリー         1   190.    6.54 
##  8 numeric   flipper_length_mm ジェンツー       1   217.    6.48 
##  9 numeric   flipper_length_mm ヒゲ             0   196.    7.13 
## 10 numeric   body_mass_g       アデリー         1  3701.  459.   
## 11 numeric   body_mass_g       ジェンツー       1  5076.  504.   
## 12 numeric   body_mass_g       ヒゲ             0  3733.  384.   
## 13 numeric   year              アデリー         0  2008.    0.822
## 14 numeric   year              ジェンツー       0  2008.    0.792
## 15 numeric   year              ヒゲ             0  2008.    0.863
## # … with abbreviated variable names ¹​n_missing, ²​numeric.mean,
## #   ³​numeric.sd

あとは、以下のように出力するだけです。

write_xlsx(res_df_num_g, "out/種類別平均値(全数値型変数).xlsx")

5.1.2 可視化

さらにggplot2を使って可視化することも可能になります。

res_df_num_g |> 
  filter(skim_variable %in% c("bill_length_mm", "bill_depth_mm",
                             "flipper_length_mm", "body_mass_g")) |> 
  ggplot(aes(x = 種類, y = numeric.mean, fill = 種類)) +
   geom_col() +
    theme(axis.text.x = element_text(size = 5)) +
   facet_wrap(vars(skim_variable), scale = "free")

ただし、ここの場合もっと潤沢な可視化グラフは元データから作成できます。例えば

df |> 
  select(種類, bill_length_mm, bill_depth_mm, flipper_length_mm,
         body_mass_g) |> 
  pivot_longer(-種類,                  # wideデータからlongデータに変換
               names_to = "variables",
               values_to = "scores") |> 
  ggplot(aes(x = 種類, y = scores, fill = 種類)) +
   geom_boxplot(alpha = 0.3, width = 0.3) + # 箱ひげ図
   geom_violin(alpha = 0.3) +               # バイオリンプロット
    theme(axis.text.x = element_text(size = 5)) +
   facet_wrap(vars(variables), scales = "free")

詳しくは特別付録のggplot2の辞書を参照ください。

5.2 相関の確認

変数同士の相関関係を見たいという要望はビジネス、アカデミックを問わず多く発生すると思います。簡単な相関行列の出し方やその可視化について解説します。ここで便利なパッケージがcorrrです。

5.2.1 相関行列を出す

まずペンギンデータの中の数値変数だけにしぼります。そして、yearはここでは不要なので落とします。そうして作ったデータフレームcor_dfを、correlate()関数に入れるだけです。

cor_df <- 
df |> 
  select(where(is.numeric)) |> # 数値変数だけにしぼる
  select(!year)                 # 不要なので落とす  


correlate(cor_df)
## # A tibble: 4 × 5
##   term              bill_length_mm bill_depth_mm flippe…¹ body_…²
##   <chr>                      <dbl>         <dbl>    <dbl>   <dbl>
## 1 bill_length_mm            NA            -0.235    0.656   0.595
## 2 bill_depth_mm             -0.235        NA       -0.584  -0.472
## 3 flipper_length_mm          0.656        -0.584   NA       0.871
## 4 body_mass_g                0.595        -0.472    0.871  NA    
## # … with abbreviated variable names ¹​flipper_length_mm,
## #   ²​body_mass_g

上側と下型で相関係数が重複しているので、片側だけを残したい場合があります。その際はshave()関数で簡単に重複部分をなくせます。引数にupper = FALSEと入れれば、上側だけにすることもできます。

相関係数の表示したい桁の指定は、fashion()関数で、引数にdecimals =で桁数を指定することで可能になります。

cormat <- 
correlate(cor_df) |> 
  shave() |> 
  fashion(decimals = 1)

cormat
##                term bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## 1    bill_length_mm                                                           
## 2     bill_depth_mm            -.2                                            
## 3 flipper_length_mm             .7           -.6                              
## 4       body_mass_g             .6           -.5                .9

あとは、以下のように出力するだけです。

write_xlsx(cormat, "out/相関行列.xlsx")

5.2.2 相関行列の可視化

corrrパッケージの関数で相関行列の可視化も簡単にできます。

correlate(cor_df) |> 
  rplot()