Skip to main content

dplyr::mutate

dplyr::mutate は、tidyverse コレクションの dplyr パッケージに含まれる関数で、既存のデータフレームに新しい列を追加するため、または既存の列を変更・削除するために使用される。

クイックリファレンス

library(tidyverse)

df %>%
mutate(new_col = col1 + col2)
penguins %>%
mutate(bill_shape_ratio = bill_length_mm / bill_depth_mm)

# # A tibble: 344 × 9
# species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year bill_shape_ratio
# <fct> <fct> <dbl> <dbl> <int> <int> <fct> <int> <dbl>
# 1 Adelie Torgersen 39.1 18.7 181 3750 male 2007 2.09
# 2 Adelie Torgersen 39.5 17.4 186 3800 female 2007 2.27
# 3 Adelie Torgersen 40.3 18 195 3250 female 2007 2.24
# 4 Adelie Torgersen NA NA NA NA NA 2007 NA
# 5 Adelie Torgersen 36.7 19.3 193 3450 female 2007 1.90
# 6 Adelie Torgersen 39.3 20.6 190 3650 male 2007 1.91
# 7 Adelie Torgersen 38.9 17.8 181 3625 female 2007 2.19
# 8 Adelie Torgersen 39.2 19.6 195 4675 male 2007 2
# 9 Adelie Torgersen 34.1 18.1 193 3475 NA 2007 1.88
# 10 Adelie Torgersen 42 20.2 190 4250 NA 2007 2.08
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

基本構文

mutate(
.data,
...,
.by = NULL,
.keep = c("all", "used", "unused", "none"),
.before = NULL,
.after = NULL
)
引数説明
.dataデータフレーム(または tibble)。
...新しい列を生成したり、既存の列を変更・削除するための式。
.by = NULLグループ化したい列を指定する。<tidy-select> も指定可能。
.keep = "all"既存の列を保持するかを指定する。
"all" - 既存のすべての列を保持する。
"used" - 新しい列を生成するのに使用された列のみを保持する。
"unused" - 新しい列を生成するのに使用されなかった列のみを保持する。
"none" - 既存の列を保持しない。
.before = NULL新しい列を指定した列の前に追加する。<tidy-select> も指定可能。
.after = NULL新しい列を指定した列の後に追加する。<tidy-select> も指定可能。

使用例

1. 新しい列の追加

複数の列を追加したいときは、カンマで区切る。また、同じ mutate 関数内でも先に作成した列であれば、そのまま使用することができる。

penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
is_greater_than_two = if_else(bill_shape_ratio > 2, 1, 0)
)

# # A tibble: 344 × 9
# species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex bill_shape_ratio is_greater_than_two
# <fct> <fct> <dbl> <dbl> <int> <int> <fct> <dbl> <dbl>
# 1 Adelie Torgersen 39.1 18.7 181 3750 male 2.09 1
# 2 Adelie Torgersen 39.5 17.4 186 3800 female 2.27 1
# 3 Adelie Torgersen 40.3 18 195 3250 female 2.24 1
# 4 Adelie Torgersen NA NA NA NA NA NA NA
# 5 Adelie Torgersen 36.7 19.3 193 3450 female 1.90 0
# 6 Adelie Torgersen 39.3 20.6 190 3650 male 1.91 0
# 7 Adelie Torgersen 38.9 17.8 181 3625 female 2.19 1
# 8 Adelie Torgersen 39.2 19.6 195 4675 male 2 0
# 9 Adelie Torgersen 34.1 18.1 193 3475 NA 1.88 0
# 10 Adelie Torgersen 42 20.2 190 4250 NA 2.08 1
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

2. 既存の列の変更

既存の列に代入すると、列の中身を上書きできる。

penguins %>%
mutate(
island = substr(island, 1, 1),
sex = case_when(
sex == "male" ~ "M",
sex == "female" ~ "F",
TRUE ~ sex
)
)

# # A tibble: 344 × 7
# species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
# <fct> <chr> <dbl> <dbl> <int> <int> <chr>
# 1 Adelie T 39.1 18.7 181 3750 M
# 2 Adelie T 39.5 17.4 186 3800 F
# 3 Adelie T 40.3 18 195 3250 F
# 4 Adelie T NA NA NA NA NA
# 5 Adelie T 36.7 19.3 193 3450 F
# 6 Adelie T 39.3 20.6 190 3650 M
# 7 Adelie T 38.9 17.8 181 3625 F
# 8 Adelie T 39.2 19.6 195 4675 M
# 9 Adelie T 34.1 18.1 193 3475 NA
# 10 Adelie T 42 20.2 190 4250 NA
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

3. 既存の列の削除

既存の列に NULL を代入すると、その列は削除される。

penguins %>%
mutate(
bill_length_mm = NULL,
bill_depth_mm = NULL,
)

# # A tibble: 344 × 5
# species island flipper_length_mm body_mass_g sex
# <fct> <fct> <int> <int> <fct>
# 1 Adelie Torgersen 181 3750 male
# 2 Adelie Torgersen 186 3800 female
# 3 Adelie Torgersen 195 3250 female
# 4 Adelie Torgersen NA NA NA
# 5 Adelie Torgersen 193 3450 female
# 6 Adelie Torgersen 190 3650 male
# 7 Adelie Torgersen 181 3625 female
# 8 Adelie Torgersen 195 4675 male
# 9 Adelie Torgersen 193 3475 NA
# 10 Adelie Torgersen 190 4250 NA
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

4. グループ化集計

.by パラメータを使用すると、グループ化集計(Grouped Calculation)をすることができる。

penguins %>%
mutate(
avg_body_mass = mean(body_mass_g, na.rm = TRUE),
.by = sex
)

# # A tibble: 344 × 8
# species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex avg_body_mass
# <fct> <fct> <dbl> <dbl> <int> <int> <fct> <dbl>
# 1 Adelie Torgersen 39.1 18.7 181 3750 male 4546.
# 2 Adelie Torgersen 39.5 17.4 186 3800 female 3862.
# 3 Adelie Torgersen 40.3 18 195 3250 female 3862.
# 4 Adelie Torgersen NA NA NA NA NA 4006.
# 5 Adelie Torgersen 36.7 19.3 193 3450 female 3862.
# 6 Adelie Torgersen 39.3 20.6 190 3650 male 4546.
# 7 Adelie Torgersen 38.9 17.8 181 3625 female 3862.
# 8 Adelie Torgersen 39.2 19.6 195 4675 male 4546.
# 9 Adelie Torgersen 34.1 18.1 193 3475 NA 4006.
# 10 Adelie Torgersen 42 20.2 190 4250 NA 4006.
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

これは、dplyr::group_bydplyr::mutatedplyr::ungroup と同じ動作である。

penguins %>%
group_by(sex) %>%
mutate(avg_body_mass = mean(body_mass_g, na.rm = TRUE)) %>%
ungroup()

# # A tibble: 344 × 8
# species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex avg_body_mass
# <fct> <fct> <dbl> <dbl> <int> <int> <fct> <dbl>
# 1 Adelie Torgersen 39.1 18.7 181 3750 male 4546.
# 2 Adelie Torgersen 39.5 17.4 186 3800 female 3862.
# 3 Adelie Torgersen 40.3 18 195 3250 female 3862.
# 4 Adelie Torgersen NA NA NA NA NA 4006.
# 5 Adelie Torgersen 36.7 19.3 193 3450 female 3862.
# 6 Adelie Torgersen 39.3 20.6 190 3650 male 4546.
# 7 Adelie Torgersen 38.9 17.8 181 3625 female 3862.
# 8 Adelie Torgersen 39.2 19.6 195 4675 male 4546.
# 9 Adelie Torgersen 34.1 18.1 193 3475 NA 4006.
# 10 Adelie Torgersen 42 20.2 190 4250 NA 4006.
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

5. 新しい列と生成するのに使用した列のみを保持

.keep パラメータに "used" を指定すると、新しい列と、それを生成するのに使用した列のみを保持する。

penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
.keep = "used"
)

# # A tibble: 344 × 3
# bill_length_mm bill_depth_mm bill_shape_ratio
# <dbl> <dbl> <dbl>
# 1 39.1 18.7 2.09
# 2 39.5 17.4 2.27
# 3 40.3 18 2.24
# 4 NA NA NA
# 5 36.7 19.3 1.90
# 6 39.3 20.6 1.91
# 7 38.9 17.8 2.19
# 8 39.2 19.6 2
# 9 34.1 18.1 1.88
# 10 42 20.2 2.08
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

6. 新しい列と生成するのに使用しなかった列のみを保持

.keep パラメータに "unused" を指定すると、新しい列と、それを生成するのに使用しなかった列のみを保持する。

penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
.keep = "unused"
)

# # A tibble: 344 × 6
# species island flipper_length_mm body_mass_g sex bill_shape_ratio
# <fct> <fct> <int> <int> <fct> <dbl>
# 1 Adelie Torgersen 181 3750 male 2.09
# 2 Adelie Torgersen 186 3800 female 2.27
# 3 Adelie Torgersen 195 3250 female 2.24
# 4 Adelie Torgersen NA NA NA NA
# 5 Adelie Torgersen 193 3450 female 1.90
# 6 Adelie Torgersen 190 3650 male 1.91
# 7 Adelie Torgersen 181 3625 female 2.19
# 8 Adelie Torgersen 195 4675 male 2
# 9 Adelie Torgersen 193 3475 NA 1.88
# 10 Adelie Torgersen 190 4250 NA 2.08
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

7. 新しい列のみ保持

.keep パラメータに "none" を指定すると、新しい列のみ保持する。

penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
.keep = "none"
)

# # A tibble: 344 × 1
# bill_shape_ratio
# <dbl>
# 1 2.09
# 2 2.27
# 3 2.24
# 4 NA
# 5 1.90
# 6 1.91
# 7 2.19
# 8 2
# 9 1.88
# 10 2.08
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows

8. 新しい列を任意の場所に追加

新しく作成した列は、.before パラメータで指定した列の前に、.after パラメータで指定した列の後に追加することができる。

penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
.before = "island"
)

# # A tibble: 344 × 8
# species bill_shape_ratio island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
# <fct> <dbl> <fct> <dbl> <dbl> <int> <int> <fct>
# 1 Adelie 2.09 Torgersen 39.1 18.7 181 3750 male
# 2 Adelie 2.27 Torgersen 39.5 17.4 186 3800 female
# 3 Adelie 2.24 Torgersen 40.3 18 195 3250 female
# 4 Adelie NA Torgersen NA NA NA NA NA
# 5 Adelie 1.90 Torgersen 36.7 19.3 193 3450 female
# 6 Adelie 1.91 Torgersen 39.3 20.6 190 3650 male
# 7 Adelie 2.19 Torgersen 38.9 17.8 181 3625 female
# 8 Adelie 2 Torgersen 39.2 19.6 195 4675 male
# 9 Adelie 1.88 Torgersen 34.1 18.1 193 3475 NA
# 10 Adelie 2.08 Torgersen 42 20.2 190 4250 NA
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows
penguins %>%
mutate(
bill_shape_ratio = bill_length_mm / bill_depth_mm,
.after = "island"
)

# # A tibble: 344 × 8
# species island bill_shape_ratio bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
# <fct> <fct> <dbl> <dbl> <dbl> <int> <int> <fct>
# 1 Adelie Torgersen 2.09 39.1 18.7 181 3750 male
# 2 Adelie Torgersen 2.27 39.5 17.4 186 3800 female
# 3 Adelie Torgersen 2.24 40.3 18 195 3250 female
# 4 Adelie Torgersen NA NA NA NA NA NA
# 5 Adelie Torgersen 1.90 36.7 19.3 193 3450 female
# 6 Adelie Torgersen 1.91 39.3 20.6 190 3650 male
# 7 Adelie Torgersen 2.19 38.9 17.8 181 3625 female
# 8 Adelie Torgersen 2 39.2 19.6 195 4675 male
# 9 Adelie Torgersen 1.88 34.1 18.1 193 3475 NA
# 10 Adelie Torgersen 2.08 42 20.2 190 4250 NA
# # ℹ 334 more rows
# # ℹ Use `print(n = ...)` to see more rows