6 要約値を作る:summarise
- 本章のポイント
- パッケージ
dplyr
の関数summarise()
- 結果をデータフレームとして出力するため,扱いが便利
- データを知るうえで要約作業は頻繁に行うことが想定される
- 便利な要約パッケージが色々あるものの,
summarise()
は柔軟な出力が可能なので使いこなせると役に立つ
- パッケージ
6.1 基本
-
summarise()
の中に出力したい変数名を書き,=
の後に計算する関数を入れる - 例:bill_length_mmの平均値を算出する
- データは2.1で読み込んだdfを使用
# まだtidyverseパッケージを読み込んでない場合は以下の#を外して実行
# library(tidyverse)
df |>
summarise(blm_平均値 = mean(bill_length_mm, na.rm = TRUE))
## # A tibble: 1 × 1
## blm_平均値
## <dbl>
## 1 43.9
6.2 複数の計算
- 複数の変数について平均値と標準偏差(SD)と人数(n)を出したいときは,基本知識では全部書くので長くなる
- SDは
sd()
関数,nは変数内の欠損のない行以外の数の合計で算出 -
sum(!is.na(.x))
は,NAのない行の数を総計するので,平均値やSDの計算に用いた人数を取得できる
- SDは
df |>
summarise(blm_mean = mean(bill_length_mm, na.rm = TRUE),
bdm_mean = mean(bill_depth_mm, na.rm = TRUE),
blm_sd = sd(bill_length_mm, na.rm = TRUE),
bdm_sd = sd(bill_depth_mm, na.rm = TRUE),
blm_n = sum(!is.na(bill_length_mm)),
bdm_n = sum(!is.na(bill_depth_mm)))
## # A tibble: 1 × 6
## blm_mean bdm_mean blm_sd bdm_sd blm_n bdm_n
## <dbl> <dbl> <dbl> <dbl> <int> <int>
## 1 43.9 17.2 5.46 1.97 342 342
6.2.1 【効率化】
-
5.3.2で出てきた
across()
がここでも有用 -
across()
の第一引数に指定したい変数名ベクトル,またはヘルパー関数を入れる - 実行したい関数を無名関数としてlist内に名前(これが接尾辞になる)をつけて列挙する
df |>
summarise(across(c(bill_length_mm, bill_depth_mm),
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE),
n = \(x) sum(!is.na(x)))))
## # A tibble: 1 × 6
## bill_length_mm_mean bill_length_mm_sd bill_length_mm_n
## <dbl> <dbl> <int>
## 1 43.9 5.46 342
## # ℹ 3 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>, bill_depth_mm_n <int>
# purrr 1.0.0より前のバージョンでの書き方
# df |>
# summarise(across(c(bill_length_mm, bill_depth_mm),
# list(mean = ~mean(.x, na.rm = TRUE),
# sd = ~sd(.x, na.rm = TRUE),
# n = ~sum(!is.na(.x)))))
-
across()
ではヘルパー関数が使える
df |>
summarise(across(starts_with("bill"),
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE),
n = \(x) sum(!is.na(x)))))
## # A tibble: 1 × 6
## bill_length_mm_mean bill_length_mm_sd bill_length_mm_n
## <dbl> <dbl> <int>
## 1 43.9 5.46 342
## # ℹ 3 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>, bill_depth_mm_n <int>
-
list()
内に関数を並べている部分は,関数を名前付きリストにしているだけなので,外に出して1回オブジェクトとして指定すれば記述がすっきりするし,後の同じ作業で繰り返し使える
# 関数のリストをオブジェクトfnlistに格納
fnlist <-
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE),
n = \(x) sum(!is.na(x)))
df |>
summarise(across(ends_with("mm"),
all_of(fnlist)))
## # A tibble: 1 × 9
## bill_length_mm_mean bill_length_mm_sd bill_length_mm_n
## <dbl> <dbl> <int>
## 1 43.9 5.46 342
## # ℹ 6 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>, bill_depth_mm_n <int>,
## # flipper_length_mm_mean <dbl>, flipper_length_mm_sd <dbl>,
## # flipper_length_mm_n <int>
6.2.2 【並び替え】
- 上記の出力は横に長いため見にくい
-
tidyr::pivot_longer()
で,データフレームの行列入れ替えができる - 引数を
names_pattern
とnames_to
を下記のように指定することで,変数の接尾辞を列名にできる - 下記コードの
summarise()
部分の構造は前のチャンクと変数名以外同じ
df |>
summarise(across(bill_length_mm:body_mass_g,
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE),
n = \(x) sum(!is.na(x))))) |>
pivot_longer(everything(),
names_to = c("items", ".value"), # ".value"の部分を列名に
names_pattern = "(.*)_(.*)") # 正規表現
## # A tibble: 4 × 4
## items mean sd n
## <chr> <dbl> <dbl> <int>
## 1 bill_length_mm 43.9 5.46 342
## 2 bill_depth_mm 17.2 1.97 342
## 3 flipper_length_mm 201. 14.1 342
## 4 body_mass_g 4202. 802. 342
6.2.3 [練習問題]
- dfデータの変数名に”length”を含む変数に対して平均値とSDとnを計算したデータフレームを作成して”res”オブジェクトに格納しよう
- 次に作成したデータフレームを
pivot_longer()
を使って見やすいように縦に変換しよう
6.3 層別(グループ別)集計
-
group_by()
にグループを表す変数を指定するとできる
df |>
group_by(species) |>
summarise(across(c(bill_length_mm, bill_depth_mm),
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE))))
## # A tibble: 3 × 5
## species bill_length_mm_mean bill_length_mm_sd
## <fct> <dbl> <dbl>
## 1 Adelie 38.8 2.66
## 2 Chinstrap 48.8 3.34
## 3 Gentoo 47.5 3.08
## # ℹ 2 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>
- グループを重ねることも可能
df |>
group_by(species, sex) |>
summarise(across(c(bill_length_mm, bill_depth_mm),
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE))))
## # A tibble: 8 × 6
## # Groups: species [3]
## species sex bill_length_mm_mean bill_length_mm_sd
## <fct> <fct> <dbl> <dbl>
## 1 Adelie female 37.3 2.03
## 2 Adelie male 40.4 2.28
## 3 Adelie <NA> 37.8 2.80
## 4 Chinstrap female 46.6 3.11
## 5 Chinstrap male 51.1 1.56
## 6 Gentoo female 45.6 2.05
## 7 Gentoo male 49.5 2.72
## 8 Gentoo <NA> 45.6 1.37
## # ℹ 2 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>
6.4 【効率化】関数にする
- 関数作成の基本は(1.4.2.2参照)
6.4.1 複数変数の平均値とSDとnを計算する関数
- 「
{{ }}
」はcurly curly
と読み,関数を作成するときに,代入先の変数名の場所を指定する時などに活躍- 下記の例の場合,
{{ }}
を外すと動かない
- 下記の例の場合,
- 例:引数にデータフレーム(
data
)と変数(vars
)を入れると平均値とSDとnを返す関数mean_sd_n()
を定義
mean_sd_n <- function(data, vars){
data |>
summarise(across({{vars}},
list(mean = \(x) mean(x, na.rm = TRUE),
sd = \(x) sd(x, na.rm = TRUE),
n = \(x) sum(!is.na(x)))))
}
- ここで定義した関数
mean_sd_n()
に引数としてデータフレームと変数を入れると結果が表示される
mean_sd_n(df, bill_length_mm)
## # A tibble: 1 × 3
## bill_length_mm_mean bill_length_mm_sd bill_length_mm_n
## <dbl> <dbl> <int>
## 1 43.9 5.46 342
- 引数
vars
の部分はacross()
の第一引数に入れるものと同じ指定ができるため,変数ベクトルやヘルパー関数が入る
# 変数ベクトル
mean_sd_n(df, c(flipper_length_mm, body_mass_g))
## # A tibble: 1 × 6
## flipper_length_mm_mean flipper_length_mm_sd flipper_length_mm_n
## <dbl> <dbl> <int>
## 1 201. 14.1 342
## # ℹ 3 more variables: body_mass_g_mean <dbl>,
## # body_mass_g_sd <dbl>, body_mass_g_n <int>
# 文字でも可能
# mean_sd_n(df, c("flipper_length_mm", "body_mass_g"))
# ヘルパー関数
mean_sd_n(df, starts_with("bill"))
## # A tibble: 1 × 6
## bill_length_mm_mean bill_length_mm_sd bill_length_mm_n
## <dbl> <dbl> <int>
## 1 43.9 5.46 342
## # ℹ 3 more variables: bill_depth_mm_mean <dbl>,
## # bill_depth_mm_sd <dbl>, bill_depth_mm_n <int>