Rのデータフレームの行操作についてのメモ

# はじめに
Rのデータフレームの行の操作について、サンプルデータを用いて具体的に練習してみました。

**目次**

- [Rのデータフレームの行についての操作](#rのデータフレームの行についての操作)
    - [練習に用いるデータ](#練習に用いるデータ)
    - [slice()：行の番号抽出](#slice行の番号抽出)
       - [slice_head(), slice_tail()：先頭のn行・末尾のn行抽出](#slice_head-slice_tail先頭のn行末尾のn行抽出)
       - [slice_max(), slice_min()：最大のn行・最小のn行抽出](#slice_max-slice_min最大のn行最小のn行抽出)
       - [slice_sample()：行のサンプリング抽出](#slice_sample行のサンプリング抽出)
    - [filter()：行の条件抽出](#filter行の条件抽出)
       - [is.na()：NAかどうか](#isnanaかどうか)
       - [%in%](#in)
       - [between()](#between)
       - [near()：計算誤差込みの等号](#near計算誤差込みの等号)
       - [str_detect()：文字列の条件抽出](#str_detect文字列の条件抽出)
    - [filter(if_all()), filter(if_any())：複数列にわたる条件での行の抽出](#filterif_all-filterif_any複数列にわたる条件での行の抽出)
       - [where()](#where)
    - [arrange()：行の並び替え](#arrange行の並び替え)
    - [distinct()：行の重複削除](#distinct行の重複削除)
    - [group_by()：グループ化](#group_byグループ化)
       - [ungroup()：グループ化の解除](#ungroupグループ化の解除)
    - [drop_na()：NAの行の削除](#drop_nanaの行の削除)
    - [complete(), expand()：列の値のすべての組み合わせからなる行の作成](#complete-expand列の値のすべての組み合わせからなる行の作成)
    - [rowid_to_column(), rownames_to_column()：行番号・行名を列名に](#rowid_to_column-rownames_to_column行番号行名を列名に)
    - [column_to_rownames()：列名を行名に](#column_to_rownames列名を行名に)
- [参考](#参考)


# Rのデータフレームの行についての操作
Rのデータフレームの行の操作について、サンプルデータを用いて具体的に練習します。
なお、以下については別記事でまとめています。
- 列の操作について：[こちら](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d)
- 集計操作について：[こちら](https://qiita.com/swathci/items/d13be09a7ed73c1a8d94)
- pivot操作について：[こちら](https://qiita.com/swathci/items/4ce25faddfeff3a29a5f)
- データフレームの関数について：[こちら](https://qiita.com/swathci/items/8d626865638079d13665)

[dplyr](https://dplyr.tidyverse.org/)
[tidyr](https://tidyr.tidyverse.org/index.html)

参考：
https://r4ds.had.co.nz/transform.html
https://github.com/tidyverse/dplyr
https://heavywatal.github.io/rstats/dplyr.html


## 練習に用いるデータ
Rのサンプルデータ`iris`と`anscombe`を用います。
行番号を表示した方が分かりやすいため、`tibble::rowid_to_column()`で行番号を列名にしています。
（[こちらの記事](https://qiita.com/swathci/items/4ce25faddfeff3a29a5f)と同じデータを用います。）

```R:R
library(dplyr)
library(tibble)
library(tidyr)

iris

# 行番号を列名に
iris_tbl <- iris %>% as_tibble() %>% rowid_to_column("id")
iris_tbl
# # A tibble: 150 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2          4.9         3            1.4         0.2 setosa 
#  3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5          5           3.6          1.4         0.2 setosa 
#  6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7          4.6         3.4          1.4         0.3 setosa 
#  8     8          5           3.4          1.5         0.2 setosa 
#  9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10          4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows

anscombe

anscombe_tbl <- anscombe %>% as_tibble() %>% rowid_to_column("id")
anscombe_tbl
# # A tibble: 11 x 9
#       id    x1    x2    x3    x4    y1    y2    y3    y4
#    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#  1     1    10    10    10     8  8.04  9.14  7.46  6.58
#  2     2     8     8     8     8  6.95  8.14  6.77  5.76
#  3     3    13    13    13     8  7.58  8.74 12.7   7.71
#  4     4     9     9     9     8  8.81  8.77  7.11  8.84
#  5     5    11    11    11     8  8.33  9.26  7.81  8.47
#  6     6    14    14    14     8  9.96  8.1   8.84  7.04
#  7     7     6     6     6     8  7.24  6.13  6.08  5.25
#  8     8     4     4     4    19  4.26  3.1   5.39 12.5 
#  9     9    12    12    12     8 10.8   9.13  8.15  5.56
# 10    10     7     7     7     8  4.82  7.26  6.42  7.91
# 11    11     5     5     5     8  5.68  4.74  5.73  6.89
```


## slice()：行の番号抽出
行を行番号で抽出します。

```R:R
# slice()
iris_tbl %>%
  slice(c(1, 3, 5))
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     5          5           3.6          1.4         0.2 setosa 

iris_tbl %>%
  slice(11:15)
# # A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1    11          5.4         3.7          1.5         0.2 setosa 
# 2    12          4.8         3.4          1.6         0.2 setosa 
# 3    13          4.8         3            1.4         0.1 setosa 
# 4    14          4.3         3            1.1         0.1 setosa 
# 5    15          5.8         4            1.2         0.2 setosa 

iris_tbl %>%
  slice(seq(1, 50, 10))
# # A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2    11          5.4         3.7          1.5         0.2 setosa 
# 3    21          5.4         3.4          1.7         0.2 setosa 
# 4    31          4.8         3.1          1.6         0.2 setosa 
# 5    41          5           3.5          1.3         0.3 setosa 

c(1, 3, 5)
# [1] 1 3 5
11:15
# [1] 11 12 13 14 15
seq(1, 50, 10)
# [1]  1 11 21 31 41
```

`group_by()`でグループ化しておくと、グループごとに番号抽出できます。

```R:R
iris_tbl %>%
  group_by(Species) %>%
  slice(c(1, 3, 5))
# # A tibble: 9 x 6
# # Groups:   Species [3]
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1     1          5.1         3.5          1.4         0.2 setosa    
# 2     3          4.7         3.2          1.3         0.2 setosa    
# 3     5          5           3.6          1.4         0.2 setosa    
# 4    51          7           3.2          4.7         1.4 versicolor
# 5    53          6.9         3.1          4.9         1.5 versicolor
# 6    55          6.5         2.8          4.6         1.5 versicolor
# 7   101          6.3         3.3          6           2.5 virginica 
# 8   103          7.1         3            5.9         2.1 virginica 
# 9   105          6.5         3            5.8         2.2 virginica 
```


### slice_head(), slice_tail()：先頭のn行・末尾のn行抽出
先頭のn行、末尾のn行を抽出します。n行（行数）の代わりに割合指定もできます。
グループ化しておくと、グループごとにn行抽出できます。

```R:R
# slice_head(), slice_tail()
iris_tbl %>%
  slice_head(n = 2)
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     2          4.9         3            1.4         0.2 setosa 

iris_tbl %>%
  slice_head(prop = 0.02)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     2          4.9         3            1.4         0.2 setosa 
# 3     3          4.7         3.2          1.3         0.2 setosa

# 150 * 0.02 == 3

iris_tbl %>%
  slice_tail(n = 2)
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
# 1   149          6.2         3.4          5.4         2.3 virginica
# 2   150          5.9         3            5.1         1.8 virginica

iris_tbl %>%
  slice_tail(prop = 0.02)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
# 1   148          6.5         3            5.2         2   virginica
# 2   149          6.2         3.4          5.4         2.3 virginica
# 3   150          5.9         3            5.1         1.8 virginica

iris_tbl %>%
  group_by(Species) %>%
  slice_head(n = 2)
# # A tibble: 6 x 6
# # Groups:   Species [3]
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1     1          5.1         3.5          1.4         0.2 setosa    
# 2     2          4.9         3            1.4         0.2 setosa    
# 3    51          7           3.2          4.7         1.4 versicolor
# 4    52          6.4         3.2          4.5         1.5 versicolor
# 5   101          6.3         3.3          6           2.5 virginica 
# 6   102          5.8         2.7          5.1         1.9 virginica 
```


### slice_max(), slice_min()：最大のn行・最小のn行抽出
最大のn行、最小のn行を抽出します。n行（行数）の代わりに割合指定もできます。
グループ化しておくと、グループごとにn行抽出できます。

```R:R
# slice_max(), slice_min()
iris_tbl %>%
  slice_max(Sepal.Length, n = 2)
# # A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
# 1   132          7.9         3.8          6.4         2   virginica
# 2   118          7.7         3.8          6.7         2.2 virginica
# 3   119          7.7         2.6          6.9         2.3 virginica
# 4   123          7.7         2.8          6.7         2   virginica
# 5   136          7.7         3            6.1         2.3 virginica
# Sepal.Lengthが2番目に大きいもの（7.7）が4個あるため、結果として5行出力される

iris_tbl %>%
  slice_max(Sepal.Length, prop = 0.02)
# # A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
# 1   132          7.9         3.8          6.4         2   virginica
# 2   118          7.7         3.8          6.7         2.2 virginica
# 3   119          7.7         2.6          6.9         2.3 virginica
# 4   123          7.7         2.8          6.7         2   virginica
# 5   136          7.7         3            6.1         2.3 virginica

iris_tbl %>%
  slice_min(Sepal.Length, n = 2)
# # A tibble: 4 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1    14          4.3         3            1.1         0.1 setosa 
# 2     9          4.4         2.9          1.4         0.2 setosa 
# 3    39          4.4         3            1.3         0.2 setosa 
# 4    43          4.4         3.2          1.3         0.2 setosa 

iris_tbl %>%
  slice_min(Sepal.Length, prop = 0.02)
# # A tibble: 4 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1    14          4.3         3            1.1         0.1 setosa 
# 2     9          4.4         2.9          1.4         0.2 setosa 
# 3    39          4.4         3            1.3         0.2 setosa 
# 4    43          4.4         3.2          1.3         0.2 setosa 

iris_tbl %>%
  group_by(Species) %>%
  slice_max(Sepal.Length, n = 2)
# # A tibble: 10 x 6
# # Groups:   Species [3]
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
#  1    15          5.8         4            1.2         0.2 setosa    
#  2    16          5.7         4.4          1.5         0.4 setosa    
#  3    19          5.7         3.8          1.7         0.3 setosa    
#  4    51          7           3.2          4.7         1.4 versicolor
#  5    53          6.9         3.1          4.9         1.5 versicolor
#  6   132          7.9         3.8          6.4         2   virginica 
#  7   118          7.7         3.8          6.7         2.2 virginica 
#  8   119          7.7         2.6          6.9         2.3 virginica 
#  9   123          7.7         2.8          6.7         2   virginica 
# 10   136          7.7         3            6.1         2.3 virginica 

iris_tbl %>%
  group_by(Species) %>%
  slice_min(Sepal.Length, n = 2)
# # A tibble: 9 x 6
# # Groups:   Species [3]
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1    14          4.3         3            1.1         0.1 setosa    
# 2     9          4.4         2.9          1.4         0.2 setosa    
# 3    39          4.4         3            1.3         0.2 setosa    
# 4    43          4.4         3.2          1.3         0.2 setosa    
# 5    58          4.9         2.4          3.3         1   versicolor
# 6    61          5           2            3.5         1   versicolor
# 7    94          5           2.3          3.3         1   versicolor
# 8   107          4.9         2.5          4.5         1.7 virginica 
# 9   122          5.6         2.8          4.9         2   virginica 
```


### slice_sample()：行のサンプリング抽出
行のサンプリング抽出をします。
グループ化しておくと、グループごとにサンプリングできます。

```R:R
# slice_sample()
set.seed(1)   # 乱数のシードの固定
iris_tbl %>%
  slice_sample(n = 2)   # 非復元抽出（デフォルト）
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1    68          5.8         2.7          4.1         1   versicolor
# 2   129          6.4         2.8          5.6         2.1 virginica 

set.seed(1)   # 乱数のシードの固定
iris_tbl %>%
  slice_sample(n = 2, replace = TRUE)   # 復元抽出
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1    68          5.8         2.7          4.1         1   versicolor
# 2   129          6.4         2.8          5.6         2.1 virginica 

set.seed(1)   # 乱数のシードの固定
iris_tbl %>%
  group_by(Species) %>%
  slice_sample(n = 2)
# # A tibble: 6 x 6
# # Groups:   Species [3]
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1     4          4.6         3.1          1.5         0.2 setosa    
# 2    39          4.4         3            1.3         0.2 setosa    
# 3    51          7           3.2          4.7         1.4 versicolor
# 4    84          6           2.7          5.1         1.6 versicolor
# 5   123          7.7         2.8          6.7         2   virginica 
# 6   143          5.8         2.7          5.1         1.9 virginica 
```


## filter()：行の条件抽出
行を条件抽出します。

```R:R
# filter()
iris_tbl %>%
  filter(Sepal.Length == 4.9)
# # A tibble: 6 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1     2          4.9         3            1.4         0.2 setosa    
# 2    10          4.9         3.1          1.5         0.1 setosa    
# 3    35          4.9         3.1          1.5         0.2 setosa    
# 4    38          4.9         3.6          1.4         0.1 setosa    
# 5    58          4.9         2.4          3.3         1   versicolor
# 6   107          4.9         2.5          4.5         1.7 virginica 

iris_tbl %>%
  filter(Sepal.Length == 4.9 & Species == "setosa")
# # A tibble: 4 x 6
# id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     2          4.9         3            1.4         0.2 setosa 
# 2    10          4.9         3.1          1.5         0.1 setosa 
# 3    35          4.9         3.1          1.5         0.2 setosa 
# 4    38          4.9         3.6          1.4         0.1 setosa 

iris_tbl %>%
  filter(Sepal.Length == 4.9 & (Species == "versicolor" | Species == "virginica"))
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1    58          4.9         2.4          3.3         1   versicolor
# 2   107          4.9         2.5          4.5         1.7 virginica 
```

`NA`が含まれるときは少し注意が必要です。（[参考](https://heavywatal.github.io/rstats/dplyr.html#行)）

```R:R
# NAが入ったデータを準備
iris_tbl_na <- iris_tbl %>%
  slice_head(n = 10) %>%
  mutate(Sepal.Length = na_if(Sepal.Length, 4.9)) %>% print()
# # A tibble: 10 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2         NA           3            1.4         0.2 setosa 
#  3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5          5           3.6          1.4         0.2 setosa 
#  6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7          4.6         3.4          1.4         0.3 setosa 
#  8     8          5           3.4          1.5         0.2 setosa 
#  9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10         NA           3.1          1.5         0.1 setosa 

iris_tbl_na %>%
  filter(Sepal.Length != 5.0)
# # A tibble: 6 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     6          5.4         3.9          1.7         0.4 setosa 
# 5     7          4.6         3.4          1.4         0.3 setosa 
# 6     9          4.4         2.9          1.4         0.2 setosa 
# NAの行も5.0ではないが、除去される

iris_tbl_na %>%
  filter(Sepal.Length == 5.0 | Sepal.Length != 5.0)
# # A tibble: 8 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     5          5           3.6          1.4         0.2 setosa 
# 5     6          5.4         3.9          1.7         0.4 setosa 
# 6     7          4.6         3.4          1.4         0.3 setosa 
# 7     8          5           3.4          1.5         0.2 setosa 
# 8     9          4.4         2.9          1.4         0.2 setosa 
# NAの行が除去されるため、「5.0または5.0でない」の結果が全体にならない
```


### is.na()：NAかどうか
`NA`かどうかを判定します。

```R:R
iris_tbl_na %>%
  filter(is.na(Sepal.Length))
# # A tibble: 2 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     2           NA         3            1.4         0.2 setosa 
# 2    10           NA         3.1          1.5         0.1 setosa 

iris_tbl_na %>%
  filter(!is.na(Sepal.Length))
# # A tibble: 8 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     5          5           3.6          1.4         0.2 setosa 
# 5     6          5.4         3.9          1.7         0.4 setosa 
# 6     7          4.6         3.4          1.4         0.3 setosa 
# 7     8          5           3.4          1.5         0.2 setosa 
# 8     9          4.4         2.9          1.4         0.2 setosa 

iris_tbl_na %>%
  drop_na(Sepal.Length)
# # A tibble: 8 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     5          5           3.6          1.4         0.2 setosa 
# 5     6          5.4         3.9          1.7         0.4 setosa 
# 6     7          4.6         3.4          1.4         0.3 setosa 
# 7     8          5           3.4          1.5         0.2 setosa 
# 8     9          4.4         2.9          1.4         0.2 setosa 
```
指定した列がNAの行を削除するには、`drop_na()`も使えます。


### %in%

```R:R
# %in%
iris_tbl %>%
  filter(Sepal.Length %in% c(4.3, 4.4, 4.5))
# A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     9          4.4         2.9          1.4         0.2 setosa 
# 2    14          4.3         3            1.1         0.1 setosa 
# 3    39          4.4         3            1.3         0.2 setosa 
# 4    42          4.5         2.3          1.3         0.3 setosa 
# 5    43          4.4         3.2          1.3         0.2 setosa
```


### between()

```R:R
# between()
iris_tbl %>%
  filter(between(Sepal.Length, left = 4.3, right = 4.5))
# A tibble: 5 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     9          4.4         2.9          1.4         0.2 setosa 
# 2    14          4.3         3            1.1         0.1 setosa 
# 3    39          4.4         3            1.3         0.2 setosa 
# 4    42          4.5         2.3          1.3         0.3 setosa 
# 5    43          4.4         3.2          1.3         0.2 setosa
# これと同じ
iris_tbl %>%
  filter(4.3 <= Sepal.Length & Sepal.Length <= 4.5)
```


### near()：計算誤差込みの等号
計算誤差のために等号`==`がうまく使えないときがあります。そのような場合に計算誤差込みで等号を判定するために使います。

```R:R
# near()
iris_tbl %>%
  filter(Sepal.Length == 4.4)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     9          4.4         2.9          1.4         0.2 setosa 
# 2    39          4.4         3            1.3         0.2 setosa 
# 3    43          4.4         3.2          1.3         0.2 setosa 
# Sepal.Length == 4.4 は3行ある

iris_tbl %>%
  filter(Sepal.Length - 0.1 == 4.3)
# # A tibble: 0 x 6
# # ... with 6 variables: id <int>, Sepal.Length <dbl>, Sepal.Width <dbl>, Petal.Length <dbl>,
# #   Petal.Width <dbl>, Species <fct>
# Sepal.Length - 0.1 == 4.3 は1行も出てこない

iris_tbl %>%
  filter(near(Sepal.Length - 0.1, 4.3))
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     9          4.4         2.9          1.4         0.2 setosa 
# 2    39          4.4         3            1.3         0.2 setosa 
# 3    43          4.4         3.2          1.3         0.2 setosa 
# near(Sepal.Length - 0.1, 4.3) とすると3行で出てくる
```

計算誤差のために`4.4 - 4.3 == 0.1`は`TRUE`になりません。`near(4.4 - 4.3, 0.1)`は`TRUE`になります。

```R:R
4.4 - 4.3 == 0.1
# [1] FALSE
near(4.4 - 4.3, 0.1)
# [1] TRUE

v <- c(4.3, 4.4, 4.5)
v
# [1] 4.3 4.4 4.5
v - 4.3
# [1] 0.0 0.1 0.2
v - 4.3 == 0.1
# [1] FALSE FALSE FALSE
near(v - 4.3, 0.1)
# [1] FALSE  TRUE FALSE

0.1 * 2 == 0.2
# [1] TRUE
0.1 * 3 == 0.3
# [1] FALSE
near(0.1 * 2, 0.2)
# [1] TRUE
near(0.1 * 3, 0.3)
# [1] TRUE

v <- seq(0.1, 1.0, by = 0.1)
v
# [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
w <- 1:10 * 0.1
w
# [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
v == w
# [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE
near(v, w)
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
```


### str_detect()：文字列の条件抽出
文字列の条件抽出には`strigr`の関数が併用できます。

```R:R
# str_detect()
library(stringr)
iris_tbl %>%
  mutate(Sepal.Length = as.character(Sepal.Length)) %>%
  filter(str_detect(Sepal.Length, "^4.")) # "4."で始まる
# # A tibble: 22 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int> <chr>              <dbl>        <dbl>       <dbl> <fct>  
#  1     2 4.9                  3            1.4         0.2 setosa 
#  2     3 4.7                  3.2          1.3         0.2 setosa 
#  3     4 4.6                  3.1          1.5         0.2 setosa 
#  4     7 4.6                  3.4          1.4         0.3 setosa 
#  5     9 4.4                  2.9          1.4         0.2 setosa 
#  6    10 4.9                  3.1          1.5         0.1 setosa 
#  7    12 4.8                  3.4          1.6         0.2 setosa 
#  8    13 4.8                  3            1.4         0.1 setosa 
#  9    14 4.3                  3            1.1         0.1 setosa 
# 10    23 4.6                  3.6          1           0.2 setosa 
# # ... with 12 more rows

iris_tbl %>%
  mutate(Sepal.Length = as.character(Sepal.Length)) %>%
  filter(str_detect(Sepal.Length, ".1$")) # ".1"で終わる
# # A tibble: 16 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#    <int> <chr>              <dbl>        <dbl>       <dbl> <fct>     
#  1     1 5.1                  3.5          1.4         0.2 setosa    
#  2    18 5.1                  3.5          1.4         0.3 setosa    
#  3    20 5.1                  3.8          1.5         0.3 setosa    
#  4    22 5.1                  3.7          1.5         0.4 setosa    
#  5    24 5.1                  3.3          1.7         0.5 setosa    
#  6    40 5.1                  3.4          1.5         0.2 setosa    
#  7    45 5.1                  3.8          1.9         0.4 setosa    
#  8    47 5.1                  3.8          1.6         0.2 setosa    
#  9    64 6.1                  2.9          4.7         1.4 versicolor
# 10    72 6.1                  2.8          4           1.3 versicolor
# 11    74 6.1                  2.8          4.7         1.2 versicolor
# 12    92 6.1                  3            4.6         1.4 versicolor
# 13    99 5.1                  2.5          3           1.1 versicolor
# 14   103 7.1                  3            5.9         2.1 virginica 
# 15   128 6.1                  3            4.9         1.8 virginica 
# 16   135 6.1                  2.6          5.6         1.4 virginica 

iris_tbl %>%
  mutate(Sepal.Length = as.character(Sepal.Length)) %>% print() %>%
  filter(str_detect(Sepal.Length, "\\.")) # "."を含む
# # A tibble: 133 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int> <chr>              <dbl>        <dbl>       <dbl> <fct>  
#  1     1 5.1                  3.5          1.4         0.2 setosa 
#  2     2 4.9                  3            1.4         0.2 setosa 
#  3     3 4.7                  3.2          1.3         0.2 setosa 
#  4     4 4.6                  3.1          1.5         0.2 setosa 
#  5     6 5.4                  3.9          1.7         0.4 setosa 
#  6     7 4.6                  3.4          1.4         0.3 setosa 
#  7     9 4.4                  2.9          1.4         0.2 setosa 
#  8    10 4.9                  3.1          1.5         0.1 setosa 
#  9    11 5.4                  3.7          1.5         0.2 setosa 
# 10    12 4.8                  3.4          1.6         0.2 setosa 
# # ... with 123 more rows

iris_tbl %>%
  mutate(Sepal.Length = as.character(Sepal.Length)) %>% print() %>%
  filter(!str_detect(Sepal.Length, "\\.")) # "."を含まない
# # A tibble: 17 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#    <int> <chr>              <dbl>        <dbl>       <dbl> <fct>     
#  1     5 5                    3.6          1.4         0.2 setosa    
#  2     8 5                    3.4          1.5         0.2 setosa    
#  3    26 5                    3            1.6         0.2 setosa    
#  4    27 5                    3.4          1.6         0.4 setosa    
#  5    36 5                    3.2          1.2         0.2 setosa    
#  6    41 5                    3.5          1.3         0.3 setosa    
#  7    44 5                    3.5          1.6         0.6 setosa    
#  8    50 5                    3.3          1.4         0.2 setosa    
#  9    51 7                    3.2          4.7         1.4 versicolor
# 10    61 5                    2            3.5         1   versicolor
# 11    63 6                    2.2          4           1   versicolor
# 12    79 6                    2.9          4.5         1.5 versicolor
# 13    84 6                    2.7          5.1         1.6 versicolor
# 14    86 6                    3.4          4.5         1.6 versicolor
# 15    94 5                    2.3          3.3         1   versicolor
# 16   120 6                    2.2          5           1.5 virginica 
# 17   139 6                    3            4.8         1.8 virginica 
```


## filter(if_all()), filter(if_any())：複数列にわたる条件での行の抽出
複数列にわたって同じ条件式を適用して、それらすべてのANDやORで条件判定して行を抽出します。
条件式が`x > 0`であれば引数`.fns`に`~ . > 0`と、`f(x) > 0`であれば引数`.fns`に`~ f(.) > 0`と指定します。

```R:R
iris_tbl %>%
  filter(if_all(ends_with("Width"), ~ . > 2.3))
iris_tbl %>%
  filter(if_all(.cols = ends_with("Width"), .fns = ~ . > 2.3))
# # A tibble: 6 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
# 1   101          6.3         3.3          6           2.5 virginica
# 2   110          7.2         3.6          6.1         2.5 virginica
# 3   115          5.8         2.8          5.1         2.4 virginica
# 4   137          6.3         3.4          5.6         2.4 virginica
# 5   141          6.7         3.1          5.6         2.4 virginica
# 6   145          6.7         3.3          5.7         2.5 virginica
# これと同じ
iris_tbl %>%
  filter(Sepal.Width > 2.3 & Petal.Width > 2.3)

iris_tbl %>%
  filter(if_any(ends_with("Width"), ~ . > 4))
iris_tbl %>%
  filter(if_any(.cols = ends_with("Width"), .fns = ~ . > 4))
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1    16          5.7         4.4          1.5         0.4 setosa 
# 2    33          5.2         4.1          1.5         0.1 setosa 
# 3    34          5.5         4.2          1.4         0.2 setosa 
# これと同じ
iris_tbl %>%
  filter(Sepal.Width > 4 | Petal.Width > 4)

anscombe_tbl %>%
  filter(if_all(x1:x4, ~ . == 8))
# # A tibble: 1 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     2     8     8     8     8  6.95  8.14  6.77  5.76
# これと同じ
anscombe_tbl %>%
  filter(x1 == 8 & x2 == 8 & x3 == 8 & x4 == 8)

anscombe_tbl %>%
  filter(if_any(x1:x4, ~ . == 8))
# # A tibble: 10 x 9
#       id    x1    x2    x3    x4    y1    y2    y3    y4
#    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#  1     1    10    10    10     8  8.04  9.14  7.46  6.58
#  2     2     8     8     8     8  6.95  8.14  6.77  5.76
#  3     3    13    13    13     8  7.58  8.74 12.7   7.71
#  4     4     9     9     9     8  8.81  8.77  7.11  8.84
#  5     5    11    11    11     8  8.33  9.26  7.81  8.47
#  6     6    14    14    14     8  9.96  8.1   8.84  7.04
#  7     7     6     6     6     8  7.24  6.13  6.08  5.25
#  8     9    12    12    12     8 10.8   9.13  8.15  5.56
#  9    10     7     7     7     8  4.82  7.26  6.42  7.91
# 10    11     5     5     5     8  5.68  4.74  5.73  6.89
# これと同じ
anscombe_tbl %>%
  filter(x1 == 8 | x2 == 8 | x3 == 8 | x4 == 8)

anscombe_tbl %>%
  filter(if_any(y1:y4, ~ round(.) == 7))
# # A tibble: 7 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     1    10    10    10     8  8.04  9.14  7.46  6.58
# 2     2     8     8     8     8  6.95  8.14  6.77  5.76
# 3     4     9     9     9     8  8.81  8.77  7.11  8.84
# 4     6    14    14    14     8  9.96  8.1   8.84  7.04
# 5     7     6     6     6     8  7.24  6.13  6.08  5.25
# 6    10     7     7     7     8  4.82  7.26  6.42  7.91
# 7    11     5     5     5     8  5.68  4.74  5.73  6.89
# これと同じ
anscombe_tbl %>%
  filter(round(y1) == 7 | round(y2) == 7 | round(y3) == 7 | round(y4) == 7)
anscombe_tbl %>%
  mutate(across(y1:y4, ~ round(.), .names = "round_{col}")) %>% print() %>%
  filter(if_any(starts_with("round_"), ~ . == 7)) %>% print() %>%
  select(-starts_with("round_"))
# # A tibble: 11 x 13
#       id    x1    x2    x3    x4    y1    y2    y3    y4 round_y1 round_y2 round_y3 round_y4
#    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
#  1     1    10    10    10     8  8.04  9.14  7.46  6.58        8        9        7        7
#  2     2     8     8     8     8  6.95  8.14  6.77  5.76        7        8        7        6
#  3     3    13    13    13     8  7.58  8.74 12.7   7.71        8        9       13        8
#  4     4     9     9     9     8  8.81  8.77  7.11  8.84        9        9        7        9
#  5     5    11    11    11     8  8.33  9.26  7.81  8.47        8        9        8        8
#  6     6    14    14    14     8  9.96  8.1   8.84  7.04       10        8        9        7
#  7     7     6     6     6     8  7.24  6.13  6.08  5.25        7        6        6        5
#  8     8     4     4     4    19  4.26  3.1   5.39 12.5         4        3        5       12
#  9     9    12    12    12     8 10.8   9.13  8.15  5.56       11        9        8        6
# 10    10     7     7     7     8  4.82  7.26  6.42  7.91        5        7        6        8
# 11    11     5     5     5     8  5.68  4.74  5.73  6.89        6        5        6        7
# # A tibble: 7 x 13
#      id    x1    x2    x3    x4    y1    y2    y3    y4 round_y1 round_y2 round_y3 round_y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
# 1     1    10    10    10     8  8.04  9.14  7.46  6.58        8        9        7        7
# 2     2     8     8     8     8  6.95  8.14  6.77  5.76        7        8        7        6
# 3     4     9     9     9     8  8.81  8.77  7.11  8.84        9        9        7        9
# 4     6    14    14    14     8  9.96  8.1   8.84  7.04       10        8        9        7
# 5     7     6     6     6     8  7.24  6.13  6.08  5.25        7        6        6        5
# 6    10     7     7     7     8  4.82  7.26  6.42  7.91        5        7        6        8
# 7    11     5     5     5     8  5.68  4.74  5.73  6.89        6        5        6        7
# # A tibble: 7 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     1    10    10    10     8  8.04  9.14  7.46  6.58
# 2     2     8     8     8     8  6.95  8.14  6.77  5.76
# 3     4     9     9     9     8  8.81  8.77  7.11  8.84
# 4     6    14    14    14     8  9.96  8.1   8.84  7.04
# 5     7     6     6     6     8  7.24  6.13  6.08  5.25
# 6    10     7     7     7     8  4.82  7.26  6.42  7.91
# 7    11     5     5     5     8  5.68  4.74  5.73  6.89
```
注意）`mutate(across())`については、[こちら](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d#mutateacross複数列にわたる計算)参照。


### where()

```R:R
anscombe_tbl %>%
  filter(if_all(where(is.double), ~ . > 7))
# # A tibble: 4 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     3    13    13    13     8  7.58  8.74 12.7   7.71
# 2     4     9     9     9     8  8.81  8.77  7.11  8.84
# 3     5    11    11    11     8  8.33  9.26  7.81  8.47
# 4     6    14    14    14     8  9.96  8.1   8.84  7.04
# これと同じ
anscombe_tbl %>%
  filter(if_all(x1:y4, ~ . > 7))
anscombe_tbl %>%
  filter(x1 > 7 & x2 > 7 & x3 > 7 & x4 > 7 & y1 > 7 & y2 > 7 & y3 > 7 & y4 > 7)

anscombe_tbl %>%
  filter(if_any(where(is.numeric), ~ round(.) == 6))
# # A tibble: 6 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     2     8     8     8     8  6.95  8.14  6.77  5.76
# 2     6    14    14    14     8  9.96  8.1   8.84  7.04
# 3     7     6     6     6     8  7.24  6.13  6.08  5.25
# 4     9    12    12    12     8 10.8   9.13  8.15  5.56
# 5    10     7     7     7     8  4.82  7.26  6.42  7.91
# 6    11     5     5     5     8  5.68  4.74  5.73  6.89
# これと同じ
anscombe_tbl %>%
  filter(if_any(id:y4, ~ round(.) == 6))
anscombe_tbl %>%
  filter(round(id) == 6 |
           round(x1) == 6 | round(x2) == 6 | round(x3) == 6 | round(x4) == 6 |
           round(y1) == 6 | round(y2) == 6 | round(y3) == 6 | round(y4) == 6 )
anscombe_tbl %>%
  mutate(across(where(is.numeric), ~ round(.), .names = "round_{col}")) %>% print() %>%
  filter(if_any(starts_with("round_"), ~ . == 6)) %>% print() %>%
  select(-starts_with("round_"))
# # A tibble: 11 x 18
#       id    x1    x2    x3    x4    y1    y2    y3    y4 round_id round_x1 round_x2 round_x3 round_x4 round_y1 round_y2 round_y3
#    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
#  1     1    10    10    10     8  8.04  9.14  7.46  6.58        1       10       10       10        8        8        9        7
#  2     2     8     8     8     8  6.95  8.14  6.77  5.76        2        8        8        8        8        7        8        7
#  3     3    13    13    13     8  7.58  8.74 12.7   7.71        3       13       13       13        8        8        9       13
#  4     4     9     9     9     8  8.81  8.77  7.11  8.84        4        9        9        9        8        9        9        7
#  5     5    11    11    11     8  8.33  9.26  7.81  8.47        5       11       11       11        8        8        9        8
#  6     6    14    14    14     8  9.96  8.1   8.84  7.04        6       14       14       14        8       10        8        9
#  7     7     6     6     6     8  7.24  6.13  6.08  5.25        7        6        6        6        8        7        6        6
#  8     8     4     4     4    19  4.26  3.1   5.39 12.5         8        4        4        4       19        4        3        5
#  9     9    12    12    12     8 10.8   9.13  8.15  5.56        9       12       12       12        8       11        9        8
# 10    10     7     7     7     8  4.82  7.26  6.42  7.91       10        7        7        7        8        5        7        6
# 11    11     5     5     5     8  5.68  4.74  5.73  6.89       11        5        5        5        8        6        5        6
# # ... with 1 more variable: round_y4 <dbl>
# # A tibble: 6 x 18
#      id    x1    x2    x3    x4    y1    y2    y3    y4 round_id round_x1 round_x2 round_x3 round_x4 round_y1 round_y2 round_y3
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
# 1     2     8     8     8     8  6.95  8.14  6.77  5.76        2        8        8        8        8        7        8        7
# 2     6    14    14    14     8  9.96  8.1   8.84  7.04        6       14       14       14        8       10        8        9
# 3     7     6     6     6     8  7.24  6.13  6.08  5.25        7        6        6        6        8        7        6        6
# 4     9    12    12    12     8 10.8   9.13  8.15  5.56        9       12       12       12        8       11        9        8
# 5    10     7     7     7     8  4.82  7.26  6.42  7.91       10        7        7        7        8        5        7        6
# 6    11     5     5     5     8  5.68  4.74  5.73  6.89       11        5        5        5        8        6        5        6
# # ... with 1 more variable: round_y4 <dbl>
# # A tibble: 6 x 9
#      id    x1    x2    x3    x4    y1    y2    y3    y4
#   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     2     8     8     8     8  6.95  8.14  6.77  5.76
# 2     6    14    14    14     8  9.96  8.1   8.84  7.04
# 3     7     6     6     6     8  7.24  6.13  6.08  5.25
# 4     9    12    12    12     8 10.8   9.13  8.15  5.56
# 5    10     7     7     7     8  4.82  7.26  6.42  7.91
# 6    11     5     5     5     8  5.68  4.74  5.73  6.89
```
注意）`mutate(across())`については、[こちら](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d#mutateacross複数列にわたる計算)参照。


## arrange()：行の並び替え
行を昇順に並び替えます。`desc()`を使うと降順にできます。

```R:R
# arrange()
iris_tbl %>%
  arrange(Sepal.Length) # 昇順
# # A tibble: 150 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1    14          4.3         3            1.1         0.1 setosa 
#  2     9          4.4         2.9          1.4         0.2 setosa 
#  3    39          4.4         3            1.3         0.2 setosa 
#  4    43          4.4         3.2          1.3         0.2 setosa 
#  5    42          4.5         2.3          1.3         0.3 setosa 
#  6     4          4.6         3.1          1.5         0.2 setosa 
#  7     7          4.6         3.4          1.4         0.3 setosa 
#  8    23          4.6         3.6          1           0.2 setosa 
#  9    48          4.6         3.2          1.4         0.2 setosa 
# 10     3          4.7         3.2          1.3         0.2 setosa 
# # ... with 140 more rows

iris_tbl %>%
  arrange(desc(id)) # 降順
# # A tibble: 150 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>    
#  1   150          5.9         3            5.1         1.8 virginica
#  2   149          6.2         3.4          5.4         2.3 virginica
#  3   148          6.5         3            5.2         2   virginica
#  4   147          6.3         2.5          5           1.9 virginica
#  5   146          6.7         3            5.2         2.3 virginica
#  6   145          6.7         3.3          5.7         2.5 virginica
#  7   144          6.8         3.2          5.9         2.3 virginica
#  8   143          5.8         2.7          5.1         1.9 virginica
#  9   142          6.9         3.1          5.1         2.3 virginica
# 10   141          6.7         3.1          5.6         2.4 virginica
# # ... with 140 more rows

iris_tbl %>%
  arrange(Sepal.Length, desc(Sepal.Width))
# # A tibble: 150 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1    14          4.3         3            1.1         0.1 setosa 
# 2    43          4.4         3.2          1.3         0.2 setosa 
# 3    39          4.4         3            1.3         0.2 setosa 
# 4     9          4.4         2.9          1.4         0.2 setosa 
# 5    42          4.5         2.3          1.3         0.3 setosa 
# 6    23          4.6         3.6          1           0.2 setosa 
# 7     7          4.6         3.4          1.4         0.3 setosa 
# 8    48          4.6         3.2          1.4         0.2 setosa 
# 9     4          4.6         3.1          1.5         0.2 setosa 
# 10     3          4.7         3.2          1.3         0.2 setosa 
# # ... with 140 more rows

iris_tbl %>%
  group_by(Species) %>%
  arrange(Sepal.Length, desc(Sepal.Width)) %>%
  slice_head(n = 5)
# # A tibble: 15 x 6
# # Groups:   Species [3]
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
#  1    14          4.3         3            1.1         0.1 setosa    
#  2    43          4.4         3.2          1.3         0.2 setosa    
#  3    39          4.4         3            1.3         0.2 setosa    
#  4     9          4.4         2.9          1.4         0.2 setosa    
#  5    42          4.5         2.3          1.3         0.3 setosa    
#  6    58          4.9         2.4          3.3         1   versicolor
#  7    94          5           2.3          3.3         1   versicolor
#  8    61          5           2            3.5         1   versicolor
#  9    99          5.1         2.5          3           1.1 versicolor
# 10    60          5.2         2.7          3.9         1.4 versicolor
# 11   107          4.9         2.5          4.5         1.7 virginica 
# 12   122          5.6         2.8          4.9         2   virginica 
# 13   114          5.7         2.5          5           2   virginica 
# 14   115          5.8         2.8          5.1         2.4 virginica 
# 15   102          5.8         2.7          5.1         1.9 virginica 
```

## distinct()：行の重複削除
指定した列について重複する行を除去します。引数`.keep_all`を`TRUE`にすると、指定した列以外の列も残せます（つまり、指定した列に重複がある場合に最初の行のみ残して重複する行が削除されます）。

```R:R
# distinct()
iris_tbl %>%
  distinct(Species)
# # A tibble: 3 x 1
#   Species   
#   <fct>     
# 1 setosa    
# 2 versicolor
# 3 virginica

iris_tbl %>%
  distinct(Species, .keep_all = TRUE)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1     1          5.1         3.5          1.4         0.2 setosa    
# 2    51          7           3.2          4.7         1.4 versicolor
# 3   101          6.3         3.3          6           2.5 virginica 
# これと同じ
iris_tbl %>%
  group_by(Species) %>%
  slice_head(n = 1)

iris_tbl %>%
  distinct(Sepal.Length, Sepal.Width)
# # A tibble: 117 x 2
#    Sepal.Length Sepal.Width
#           <dbl>       <dbl>
#  1          5.1         3.5
#  2          4.9         3  
#  3          4.7         3.2
#  4          4.6         3.1
#  5          5           3.6
#  6          5.4         3.9
#  7          4.6         3.4
#  8          5           3.4
#  9          4.4         2.9
# 10          4.9         3.1
# # ... with 107 more rows
# これと同じ
iris_tbl %>%
  select(Sepal.Length, Sepal.Width) %>%
  unique()

iris_tbl %>%
  arrange(Species, desc(Sepal.Length)) %>%
  distinct(Species, .keep_all = TRUE)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species   
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>     
# 1    15          5.8         4            1.2         0.2 setosa    
# 2    51          7           3.2          4.7         1.4 versicolor
# 3   132          7.9         3.8          6.4         2   virginica 
# これと同じ
iris_tbl %>%
  group_by(Species) %>%
  slice_max(Sepal.Length, n = 1)
```


## group_by()：グループ化
グループ別にスライスしたり、グループ別に並び替えたり、グループ別に集計したりする場合に使います。
グループ化しただけでは特に何もなりません。

```R:R
# group_by()
iris_tbl %>%
  group_by(Species)
# # A tibble: 150 x 6
# # Groups:   Species [3]
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2          4.9         3            1.4         0.2 setosa 
#  3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5          5           3.6          1.4         0.2 setosa 
#  6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7          4.6         3.4          1.4         0.3 setosa 
#  8     8          5           3.4          1.5         0.2 setosa 
#  9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10          4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows
```

### ungroup()：グループ化の解除
グループ化を解除します。

```R:R
# ungroup()
iris_tbl %>%
  group_by(Species) %>%
  ungroup()
# # A tibble: 150 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2          4.9         3            1.4         0.2 setosa 
#  3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5          5           3.6          1.4         0.2 setosa 
#  6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7          4.6         3.4          1.4         0.3 setosa 
#  8     8          5           3.4          1.5         0.2 setosa 
#  9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10          4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows
```


## drop_na()：NAの行の削除
指定した列がNAの行を削除します。

```R:R
# NAを含むデータを準備
iris_tbl_na <- iris_tbl %>%
  slice_head(n = 10) %>%
  mutate(Sepal.Length = na_if(Sepal.Length, 4.9),
         Sepal.Width = na_if(Sepal.Width, 3.4)) %>% print()
# # A tibble: 10 x 6
#       id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2         NA           3            1.4         0.2 setosa 
#  3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5          5           3.6          1.4         0.2 setosa 
#  6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7          4.6        NA            1.4         0.3 setosa 
#  8     8          5          NA            1.5         0.2 setosa 
#  9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10         NA           3.1          1.5         0.1 setosa 

# drop_na()
iris_tbl_na %>%
  drop_na(Sepal.Length)
# # A tibble: 8 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     5          5           3.6          1.4         0.2 setosa 
# 5     6          5.4         3.9          1.7         0.4 setosa 
# 6     7          4.6        NA            1.4         0.3 setosa 
# 7     8          5          NA            1.5         0.2 setosa 
# 8     9          4.4         2.9          1.4         0.2 setosa 
iris_tbl_na %>%
  filter(!is.na(Sepal.Length))

iris_tbl_na %>%
  drop_na(Sepal.Length, Sepal.Width)
# # A tibble: 6 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     3          4.7         3.2          1.3         0.2 setosa 
# 3     4          4.6         3.1          1.5         0.2 setosa 
# 4     5          5           3.6          1.4         0.2 setosa 
# 5     6          5.4         3.9          1.7         0.4 setosa 
# 6     9          4.4         2.9          1.4         0.2 setosa 
iris_tbl_na %>%
  filter(!is.na(Sepal.Length) & !is.na(Sepal.Width))
```


## complete(), expand()：列の値のすべての組み合わせからなる行の作成
指定した列の値のすべての組み合わせからなる行を作成します。
`complete()`は、指定した列の値のすべての組み合わせが登場するように、指定しなかった列にNA（または指定した値）を補完した行を挿入します（補完する値は`fill`にリストで指定します）。 
`expand()`は、指定した列の値のすべての組み合わせからなるデータフレームを返します（指定しなかった列はなくなります）。

```R:R
# complete()
iris_tbl %>%
  slice_head(n = 3) %>% print() %>%
  complete(id, Sepal.Length)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     2          4.9         3            1.4         0.2 setosa 
# 3     3          4.7         3.2          1.3         0.2 setosa 
# # A tibble: 9 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          4.7        NA           NA          NA   NA     
# 2     1          4.9        NA           NA          NA   NA     
# 3     1          5.1         3.5          1.4         0.2 setosa 
# 4     2          4.7        NA           NA          NA   NA     
# 5     2          4.9         3            1.4         0.2 setosa 
# 6     2          5.1        NA           NA          NA   NA     
# 7     3          4.7         3.2          1.3         0.2 setosa 
# 8     3          4.9        NA           NA          NA   NA     
# 9     3          5.1        NA           NA          NA   NA     

iris_tbl %>%
  slice_head(n = 3) %>% print() %>%
  complete(id, Sepal.Length, fill = list(Sepal.Width = 0.0, Species = "setosa"))
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     2          4.9         3            1.4         0.2 setosa 
# 3     3          4.7         3.2          1.3         0.2 setosa 
# A tibble: 9 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          4.7         0           NA          NA   setosa 
# 2     1          4.9         0           NA          NA   setosa 
# 3     1          5.1         3.5          1.4         0.2 setosa 
# 4     2          4.7         0           NA          NA   setosa 
# 5     2          4.9         3            1.4         0.2 setosa 
# 6     2          5.1         0           NA          NA   setosa 
# 7     3          4.7         3.2          1.3         0.2 setosa 
# 8     3          4.9         0           NA          NA   setosa 
# 9     3          5.1         0           NA          NA   setosa 

# expand()
iris_tbl %>%
  slice_head(n = 3) %>% print() %>%
  expand(id, Sepal.Length)
# # A tibble: 3 x 6
#      id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
# 1     1          5.1         3.5          1.4         0.2 setosa 
# 2     2          4.9         3            1.4         0.2 setosa 
# 3     3          4.7         3.2          1.3         0.2 setosa 
# # A tibble: 9 x 2
#      id Sepal.Length
#   <int>        <dbl>
# 1     1          4.7
# 2     1          4.9
# 3     1          5.1
# 4     2          4.7
# 5     2          4.9
# 6     2          5.1
# 7     3          4.7
# 8     3          4.9
# 9     3          5.1

iris_tbl %>%
  expand(Species)
# # A tibble: 3 x 1
#   Species   
#   <fct>     
# 1 setosa    
# 2 versicolor
# 3 virginica 
iris_tbl %>%
  distinct(Species)
```


## rowid_to_column(), rownames_to_column()：行番号・行名を列名に

```R:R
# rowid_to_column()
iris_tbl %>%
  rowid_to_column("rowid")
# # A tibble: 150 x 7
#    rowid    id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <int> <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1     1     1          5.1         3.5          1.4         0.2 setosa 
#  2     2     2          4.9         3            1.4         0.2 setosa 
#  3     3     3          4.7         3.2          1.3         0.2 setosa 
#  4     4     4          4.6         3.1          1.5         0.2 setosa 
#  5     5     5          5           3.6          1.4         0.2 setosa 
#  6     6     6          5.4         3.9          1.7         0.4 setosa 
#  7     7     7          4.6         3.4          1.4         0.3 setosa 
#  8     8     8          5           3.4          1.5         0.2 setosa 
#  9     9     9          4.4         2.9          1.4         0.2 setosa 
# 10    10    10          4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows

# rownames_to_column()
iris_tbl %>%
  rownames_to_column("rowname")
# # A tibble: 150 x 7
#    rowname    id Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#    <chr>   <int>        <dbl>       <dbl>        <dbl>       <dbl> <fct>  
#  1 1           1          5.1         3.5          1.4         0.2 setosa 
#  2 2           2          4.9         3            1.4         0.2 setosa 
#  3 3           3          4.7         3.2          1.3         0.2 setosa 
#  4 4           4          4.6         3.1          1.5         0.2 setosa 
#  5 5           5          5           3.6          1.4         0.2 setosa 
#  6 6           6          5.4         3.9          1.7         0.4 setosa 
#  7 7           7          4.6         3.4          1.4         0.3 setosa 
#  8 8           8          5           3.4          1.5         0.2 setosa 
#  9 9           9          4.4         2.9          1.4         0.2 setosa 
# 10 10         10          4.9         3.1          1.5         0.1 setosa 
# # ... with 140 more rows
```

## column_to_rownames()：列名を行名に

```R:R
# column_to_rownames()
anscombe_tbl %>%
  mutate(rowname = LETTERS[1:11]) %>% print() %>%
  column_to_rownames("rowname")
# # A tibble: 11 x 10
#       id    x1    x2    x3    x4    y1    y2    y3    y4 rowname
#    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>  
#  1     1    10    10    10     8  8.04  9.14  7.46  6.58 A      
#  2     2     8     8     8     8  6.95  8.14  6.77  5.76 B      
#  3     3    13    13    13     8  7.58  8.74 12.7   7.71 C      
#  4     4     9     9     9     8  8.81  8.77  7.11  8.84 D      
#  5     5    11    11    11     8  8.33  9.26  7.81  8.47 E      
#  6     6    14    14    14     8  9.96  8.1   8.84  7.04 F      
#  7     7     6     6     6     8  7.24  6.13  6.08  5.25 G      
#  8     8     4     4     4    19  4.26  3.1   5.39 12.5  H      
#  9     9    12    12    12     8 10.8   9.13  8.15  5.56 I      
# 10    10     7     7     7     8  4.82  7.26  6.42  7.91 J      
# 11    11     5     5     5     8  5.68  4.74  5.73  6.89 K      
#   id x1 x2 x3 x4    y1   y2    y3    y4
# A  1 10 10 10  8  8.04 9.14  7.46  6.58
# B  2  8  8  8  8  6.95 8.14  6.77  5.76
# C  3 13 13 13  8  7.58 8.74 12.74  7.71
# D  4  9  9  9  8  8.81 8.77  7.11  8.84
# E  5 11 11 11  8  8.33 9.26  7.81  8.47
# F  6 14 14 14  8  9.96 8.10  8.84  7.04
# G  7  6  6  6  8  7.24 6.13  6.08  5.25
# H  8  4  4  4 19  4.26 3.10  5.39 12.50
# I  9 12 12 12  8 10.84 9.13  8.15  5.56
# J 10  7  7  7  8  4.82 7.26  6.42  7.91
# K 11  5  5  5  8  5.68 4.74  5.73  6.89
```


# 参考
- [tidyverse](https://tidyverse.tidyverse.org/)
   - [dplyr](https://dplyr.tidyverse.org/)
   - [tidyr](https://tidyr.tidyverse.org/index.html)
- R for Data Science
   - [5 Data transformation](https://r4ds.had.co.nz/transform.html)
   - [12 Tidy data](https://r4ds.had.co.nz/tidy-data.html)
- Heavy Watal  - R stats
   - [dplyr — 高速data.frame処理](https://heavywatal.github.io/rstats/dplyr.html)
   - [tidyr — シンプルなデータ変形ツール](https://heavywatal.github.io/rstats/tidyr.html)
- Rのデータベースの操作についての自前のまとめ
   - [行の操作について](https://qiita.com/swathci/items/04f4c1bb2c3c380cae94)
   - [列の操作について](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d)
   - [集計操作について](https://qiita.com/swathci/items/d13be09a7ed73c1a8d94)
   - [pivot操作について](https://qiita.com/swathci/items/4ce25faddfeff3a29a5f)
   - [関数について](https://qiita.com/swathci/items/8d626865638079d13665)