tidyverse入門

tidyverseとは

tidyverseは、データサイエンスのためのRパッケージ集です。一貫した文法でデータ操作ができます。

library(tidyverse)

パイプ演算子 |>

パイプ演算子 |> は、左側の結果を右側の関数の第1引数に渡します。

# これは
mean(students$score)
[1] 80.3
# これと同じ
students$score |> mean()
[1] 80.3

複数の操作を連続して行うとき、パイプを使うと読みやすくなります。

# パイプなし(読みにくい)
round(mean(students$score), 1)
[1] 80.3
# パイプあり(読みやすい)
students$score |> mean() |> round(1)
[1] 80.3

dplyrの主要な関数

filter():行の絞り込み

条件に合う行だけを取り出します。

# スコアが80以上
students |> filter(score >= 80)
# A tibble: 5 × 5
     id name  grade score group
  <int> <chr> <dbl> <dbl> <chr>
1     2 鈴木      2    82 B    
2     3 佐藤      4    91 A    
3     6 渡辺      4    88 B    
4     8 小林      2    95 B    
5     9 加藤      4    83 A    
# グループAかつ3年生
students |> filter(group == "A", grade == 3)
# A tibble: 2 × 5
     id name  grade score group
  <int> <chr> <dbl> <dbl> <chr>
1     1 田中      3    78 A    
2     7 中村      3    70 A    

select():列の選択

必要な列だけを取り出します。

# name と score だけ
students |> select(name, score)
# A tibble: 10 × 2
   name  score
   <chr> <dbl>
 1 田中     78
 2 鈴木     82
 3 佐藤     91
 4 山田     65
 5 伊藤     74
 6 渡辺     88
 7 中村     70
 8 小林     95
 9 加藤     83
10 吉田     77
# id 以外
students |> select(-id)
# A tibble: 10 × 4
   name  grade score group
   <chr> <dbl> <dbl> <chr>
 1 田中      3    78 A    
 2 鈴木      2    82 B    
 3 佐藤      4    91 A    
 4 山田      3    65 B    
 5 伊藤      2    74 A    
 6 渡辺      4    88 B    
 7 中村      3    70 A    
 8 小林      2    95 B    
 9 加藤      4    83 A    
10 吉田      3    77 B    

mutate():新しい列を作る

計算結果から新しい列を追加します。

students |> mutate(
  score_centered = score - mean(score),
  passed = score >= 70
)
# A tibble: 10 × 7
      id name  grade score group score_centered passed
   <int> <chr> <dbl> <dbl> <chr>          <dbl> <lgl> 
 1     1 田中      3    78 A              -2.30 TRUE  
 2     2 鈴木      2    82 B               1.70 TRUE  
 3     3 佐藤      4    91 A              10.7  TRUE  
 4     4 山田      3    65 B             -15.3  FALSE 
 5     5 伊藤      2    74 A              -6.3  TRUE  
 6     6 渡辺      4    88 B               7.7  TRUE  
 7     7 中村      3    70 A             -10.3  TRUE  
 8     8 小林      2    95 B              14.7  TRUE  
 9     9 加藤      4    83 A               2.70 TRUE  
10    10 吉田      3    77 B              -3.30 TRUE  

arrange():並べ替え

指定した列で並べ替えます。

# スコア昇順
students |> arrange(score)
# A tibble: 10 × 5
      id name  grade score group
   <int> <chr> <dbl> <dbl> <chr>
 1     4 山田      3    65 B    
 2     7 中村      3    70 A    
 3     5 伊藤      2    74 A    
 4    10 吉田      3    77 B    
 5     1 田中      3    78 A    
 6     2 鈴木      2    82 B    
 7     9 加藤      4    83 A    
 8     6 渡辺      4    88 B    
 9     3 佐藤      4    91 A    
10     8 小林      2    95 B    
# スコア降順
students |> arrange(desc(score))
# A tibble: 10 × 5
      id name  grade score group
   <int> <chr> <dbl> <dbl> <chr>
 1     8 小林      2    95 B    
 2     3 佐藤      4    91 A    
 3     6 渡辺      4    88 B    
 4     9 加藤      4    83 A    
 5     2 鈴木      2    82 B    
 6     1 田中      3    78 A    
 7    10 吉田      3    77 B    
 8     5 伊藤      2    74 A    
 9     7 中村      3    70 A    
10     4 山田      3    65 B    

summarize():集計

データを集計します。

students |> summarize(
  mean_score = mean(score),
  sd_score = sd(score),
  n = n()
)
# A tibble: 1 × 3
  mean_score sd_score     n
       <dbl>    <dbl> <int>
1       80.3     9.41    10

group_by():グループ化

グループごとに集計できます。

students |>
  group_by(group) |>
  summarize(
    mean_score = mean(score),
    n = n()
  )
# A tibble: 2 × 3
  group mean_score     n
  <chr>      <dbl> <int>
1 A           79.2     5
2 B           81.4     5
students |>
  group_by(grade) |>
  summarize(
    mean_score = mean(score),
    n = n()
  )
# A tibble: 3 × 3
  grade mean_score     n
  <dbl>      <dbl> <int>
1     2       83.7     3
2     3       72.5     4
3     4       87.3     3

組み合わせて使う

パイプで複数の操作をつなげます。

# 3年生以上で、グループ別の平均スコアを計算し、降順に並べる
students |>
  filter(grade >= 3) |>
  group_by(group) |>
  summarize(mean_score = mean(score)) |>
  arrange(desc(mean_score))
# A tibble: 2 × 2
  group mean_score
  <chr>      <dbl>
1 A           80.5
2 B           76.7

tidyrの主要な関数

pivot_longer():縦長に変換

複数の列を1つの列にまとめます(ワイド形式 → ロング形式)。

# 例:テストの点数データ
exam_wide <- tibble(
  name = c("田中", "鈴木"),
  math = c(80, 75),
  english = c(70, 85),
  science = c(90, 80)
)
exam_wide
# A tibble: 2 × 4
  name   math english science
  <chr> <dbl>   <dbl>   <dbl>
1 田中     80      70      90
2 鈴木     75      85      80
# 縦長に変換
exam_wide |>
  pivot_longer(
    cols = c(math, english, science),
    names_to = "subject",
    values_to = "score"
  )
# A tibble: 6 × 3
  name  subject score
  <chr> <chr>   <dbl>
1 田中  math       80
2 田中  english    70
3 田中  science    90
4 鈴木  math       75
5 鈴木  english    85
6 鈴木  science    80

pivot_wider():横長に変換

1つの列を複数の列に展開します(ロング形式 → ワイド形式)。

# 例:縦長データ
exam_long <- tibble(
  name = rep(c("田中", "鈴木"), each = 3),
  subject = rep(c("math", "english", "science"), 2),
  score = c(80, 70, 90, 75, 85, 80)
)
exam_long
# A tibble: 6 × 3
  name  subject score
  <chr> <chr>   <dbl>
1 田中  math       80
2 田中  english    70
3 田中  science    90
4 鈴木  math       75
5 鈴木  english    85
6 鈴木  science    80
# 横長に変換
exam_long |>
  pivot_wider(
    names_from = subject,
    values_from = score
  )
# A tibble: 2 × 4
  name   math english science
  <chr> <dbl>   <dbl>   <dbl>
1 田中     80      70      90
2 鈴木     75      85      80

練習問題

students データを使って以下を行ってください:

  1. スコアが75以上の学生だけを抽出し、スコアの降順で並べる
  2. 各学年(grade)の平均スコアを計算する
  3. スコアの偏差値(平均50、標準偏差10に変換した値)を新しい列として追加する
# 1
students |>
  filter(score >= 75) |>
  arrange(desc(score))
# A tibble: 7 × 5
     id name  grade score group
  <int> <chr> <dbl> <dbl> <chr>
1     8 小林      2    95 B    
2     3 佐藤      4    91 A    
3     6 渡辺      4    88 B    
4     9 加藤      4    83 A    
5     2 鈴木      2    82 B    
6     1 田中      3    78 A    
7    10 吉田      3    77 B    
# 2
students |>
  group_by(grade) |>
  summarize(mean_score = mean(score))
# A tibble: 3 × 2
  grade mean_score
  <dbl>      <dbl>
1     2       83.7
2     3       72.5
3     4       87.3
# 3
students |>
  mutate(
    deviation = (score - mean(score)) / sd(score) * 10 + 50
  )
# A tibble: 10 × 6
      id name  grade score group deviation
   <int> <chr> <dbl> <dbl> <chr>     <dbl>
 1     1 田中      3    78 A          47.6
 2     2 鈴木      2    82 B          51.8
 3     3 佐藤      4    91 A          61.4
 4     4 山田      3    65 B          33.7
 5     5 伊藤      2    74 A          43.3
 6     6 渡辺      4    88 B          58.2
 7     7 中村      3    70 A          39.0
 8     8 小林      2    95 B          65.6
 9     9 加藤      4    83 A          52.9
10    10 吉田      3    77 B          46.5