108  filter()の実践

それでは、filerを実践していきましょう。まずはtibbleを作りましょう

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.2     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
dat <- tibble(a = c(1:50), b = sample(50:1))

dat
# A tibble: 50 × 2
       a     b
   <int> <int>
 1     1    12
 2     2    28
 3     3    27
 4     4     2
 5     5    26
 6     6    13
 7     7    25
 8     8    36
 9     9    37
10    10    35
# ℹ 40 more rows

まず、a列が15であるものをとりだします

dat %>% filter(a == 15)
# A tibble: 1 × 2
      a     b
  <int> <int>
1    15    10

a列が15あるいはb列が30以上の行をとりだせますか?

dat %>% filter(a == 15 | b >= 30)
# A tibble: 22 × 2
       a     b
   <int> <int>
 1     8    36
 2     9    37
 3    10    35
 4    12    48
 5    14    45
 6    15    10
 7    18    33
 8    19    42
 9    20    30
10    23    38
# ℹ 12 more rows

ロジカル型の練習問題ででてきた書き方を応用すれば、

a列が2の倍数となる行は

dat %>% filter(a %% 2 == 0)
# A tibble: 25 × 2
       a     b
   <int> <int>
 1     2    28
 2     4     2
 3     6    13
 4     8    36
 5    10    35
 6    12    48
 7    14    45
 8    16    20
 9    18    33
10    20    30
# ℹ 15 more rows

b列が2の倍数となる行は

dat %>% filter(b %% 2 == 0)
# A tibble: 25 × 2
       a     b
   <int> <int>
 1     1    12
 2     2    28
 3     4     2
 4     5    26
 5     8    36
 6    12    48
 7    13    22
 8    15    10
 9    16    20
10    19    42
# ℹ 15 more rows

こんな感じで列をTRUE、FALSEのベクトルを利用して抽出することができます。

また、もちろん、文字列型の列に対しても同じように操作ができて、

dat <- tibble(
  num = 1:10,
  chr = c("a","a","b","b","c","c","c","a","b","c")
)

dat
# A tibble: 10 × 2
     num chr  
   <int> <chr>
 1     1 a    
 2     2 a    
 3     3 b    
 4     4 b    
 5     5 c    
 6     6 c    
 7     7 c    
 8     8 a    
 9     9 b    
10    10 c    
dat %>% filter(chr == "a")
# A tibble: 3 × 2
    num chr  
  <int> <chr>
1     1 a    
2     2 a    
3     8 a    

とすることによって文字列を条件づけて行をとりだすことができます。

ここで、aとcを取り出したい場合は、

dat %>% filter(chr == c("a","c"))
# A tibble: 3 × 2
    num chr  
  <int> <chr>
1     1 a    
2     6 c    
3    10 c    

とすると実は誤っているので注意が必要です。なぜなら、

dat$chr   : "a","a","b","b","c","c","c","a","b","c"
c("a","c"): "a","c","a","c","a","c","a","c","a","c", 
             T   F   F   F   F   T   F   F   F   T

こんな感じで繰り返されたTRUE,FALSEが返ってくると解されるからです。

ここで、複数条件で絞り込む場合は、すこし特殊な、

dat %>% filter(chr %in% c("a","c"))
# A tibble: 7 × 2
    num chr  
  <int> <chr>
1     1 a    
2     2 a    
3     5 c    
4     6 c    
5     7 c    
6     8 a    
7    10 c    

%in% 記号というものを利用します。この記号を利用することで、

dat$chr   : "a","a","b","b","c","c","c","a","b","c"

c("a","c"): "a","a","a","a","a","a","a","a","a","a"
      "c","c","c","c","c","c","c","c","c","c"
             T   T   F   F   T   T   F   T   F   T

両方のどちらかと一致する形になります。もちろん、|演算子を利用して、

dat %>% filter(chr == "a" | chr == "c")
# A tibble: 7 × 2
    num chr  
  <int> <chr>
1     1 a    
2     2 a    
3     5 c    
4     6 c    
5     7 c    
6     8 a    
7    10 c    

と書いても同じ結果になりますが、 %in% の書き方を知っていると楽なので、ここで紹介しました。

それでは、filter関数の練習問題に進んでいきましょう。