6  dplyr 的两种语法

在众多对变量的操作中,有两种是最为核心的——选取和修改。

6.1 select()tidyselect

select() 可以根据位置选取列,且支持全部 tidyselect 的语法。

library(tidyverse)
diamonds %>%
  select(5) # 抽取第五列
# A tibble: 53,940 × 1
   depth
   <dbl>
 1  61.5
 2  59.8
 3  56.9
 4  62.4
 5  63.3
 6  62.8
 7  62.3
 8  61.9
 9  65.1
10  59.4
# ℹ 53,930 more rows
diamonds %>%
  select(-5) # 删除第五列
# A tibble: 53,940 × 9
   carat cut       color clarity table price     x     y     z
   <dbl> <ord>     <ord> <ord>   <dbl> <int> <dbl> <dbl> <dbl>
 1  0.23 Ideal     E     SI2        55   326  3.95  3.98  2.43
 2  0.21 Premium   E     SI1        61   326  3.89  3.84  2.31
 3  0.23 Good      E     VS1        65   327  4.05  4.07  2.31
 4  0.29 Premium   I     VS2        58   334  4.2   4.23  2.63
 5  0.31 Good      J     SI2        58   335  4.34  4.35  2.75
 6  0.24 Very Good J     VVS2       57   336  3.94  3.96  2.48
 7  0.24 Very Good I     VVS1       57   336  3.95  3.98  2.47
 8  0.26 Very Good H     SI1        55   337  4.07  4.11  2.53
 9  0.22 Fair      E     VS2        61   337  3.87  3.78  2.49
10  0.23 Very Good H     VS1        61   338  4     4.05  2.39
# ℹ 53,930 more rows

tidyselect 也可以根据名称选取列。

diamonds %>%
  select(cut) # 选取cut变量
# A tibble: 53,940 × 1
   cut      
   <ord>    
 1 Ideal    
 2 Premium  
 3 Good     
 4 Premium  
 5 Good     
 6 Very Good
 7 Very Good
 8 Very Good
 9 Fair     
10 Very Good
# ℹ 53,930 more rows
diamonds %>%
  select(-cut) # 删除cut变量
# A tibble: 53,940 × 9
   carat color clarity depth table price     x     y     z
   <dbl> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.23 E     SI2      61.5    55   326  3.95  3.98  2.43
 2  0.21 E     SI1      59.8    61   326  3.89  3.84  2.31
 3  0.23 E     VS1      56.9    65   327  4.05  4.07  2.31
 4  0.29 I     VS2      62.4    58   334  4.2   4.23  2.63
 5  0.31 J     SI2      63.3    58   335  4.34  4.35  2.75
 6  0.24 J     VVS2     62.8    57   336  3.94  3.96  2.48
 7  0.24 I     VVS1     62.3    57   336  3.95  3.98  2.47
 8  0.26 H     SI1      61.9    55   337  4.07  4.11  2.53
 9  0.22 E     VS2      65.1    61   337  3.87  3.78  2.49
10  0.23 H     VS1      59.4    61   338  4     4.05  2.39
# ℹ 53,930 more rows

6.2 :c()

: 表示多个连续的整数,比如 1:3 表示 1~3 这三个整数。

1:5
[1] 1 2 3 4 5
# 选取前五个变量
diamonds %>%
  select(1:5)
# A tibble: 53,940 × 5
   carat cut       color clarity depth
   <dbl> <ord>     <ord> <ord>   <dbl>
 1  0.23 Ideal     E     SI2      61.5
 2  0.21 Premium   E     SI1      59.8
 3  0.23 Good      E     VS1      56.9
 4  0.29 Premium   I     VS2      62.4
 5  0.31 Good      J     SI2      63.3
 6  0.24 Very Good J     VVS2     62.8
 7  0.24 Very Good I     VVS1     62.3
 8  0.26 Very Good H     SI1      61.9
 9  0.22 Fair      E     VS2      65.1
10  0.23 Very Good H     VS1      59.4
# ℹ 53,930 more rows
# 用另一种方式选取前五个变量
diamonds %>%
  select(carat:depth)
# A tibble: 53,940 × 5
   carat cut       color clarity depth
   <dbl> <ord>     <ord> <ord>   <dbl>
 1  0.23 Ideal     E     SI2      61.5
 2  0.21 Premium   E     SI1      59.8
 3  0.23 Good      E     VS1      56.9
 4  0.29 Premium   I     VS2      62.4
 5  0.31 Good      J     SI2      63.3
 6  0.24 Very Good J     VVS2     62.8
 7  0.24 Very Good I     VVS1     62.3
 8  0.26 Very Good H     SI1      61.9
 9  0.22 Fair      E     VS2      65.1
10  0.23 Very Good H     VS1      59.4
# ℹ 53,930 more rows

c() 表示多个数的集合,它比 : 更灵活、更普适,缺点是写起来麻烦些。c(1, 2, 3)c(1:3) 显然都不如 1:3 简洁。但是,c() 既可以表示不连续的整数,也可以表示其他类型的数:

  • c(1:3, 5) 表示 1, 2, 3, 5 这四个数
  • c(1:3, 5:6) 表示 1, 2, 3, 5, 6 这五个数
  • c(1.23, pi, exp(1), sqrt(2)) 表示 1.23, \(\pi\), \(e\), \(\sqrt{2}\) 这四个数
    • 不过,只有整数能用来选变量哦

c() 是一个独立存在的底层函数,表示向量,它不属于 tidyselect 的一部分。但是,可以借用它来同时选取多个变量。

c(1, 3:5)
[1] 1 3 4 5
# 选取第1、3、4、5个变量
diamonds %>%
  select(c(1, 3:5))
# A tibble: 53,940 × 4
   carat color clarity depth
   <dbl> <ord> <ord>   <dbl>
 1  0.23 E     SI2      61.5
 2  0.21 E     SI1      59.8
 3  0.23 E     VS1      56.9
 4  0.29 I     VS2      62.4
 5  0.31 J     SI2      63.3
 6  0.24 J     VVS2     62.8
 7  0.24 I     VVS1     62.3
 8  0.26 H     SI1      61.9
 9  0.22 E     VS2      65.1
10  0.23 H     VS1      59.4
# ℹ 53,930 more rows
# 用另一种方式选取这些变量
diamonds %>%
  select(c(carat, color:depth))
# A tibble: 53,940 × 4
   carat color clarity depth
   <dbl> <ord> <ord>   <dbl>
 1  0.23 E     SI2      61.5
 2  0.21 E     SI1      59.8
 3  0.23 E     VS1      56.9
 4  0.29 I     VS2      62.4
 5  0.31 J     SI2      63.3
 6  0.24 J     VVS2     62.8
 7  0.24 I     VVS1     62.3
 8  0.26 H     SI1      61.9
 9  0.22 E     VS2      65.1
10  0.23 H     VS1      59.4
# ℹ 53,930 more rows

6.3 starts_with() 系列函数

# 选取c开头的变量
diamonds %>%
  select(starts_with("c"))
# A tibble: 53,940 × 4
   carat cut       color clarity
   <dbl> <ord>     <ord> <ord>  
 1  0.23 Ideal     E     SI2    
 2  0.21 Premium   E     SI1    
 3  0.23 Good      E     VS1    
 4  0.29 Premium   I     VS2    
 5  0.31 Good      J     SI2    
 6  0.24 Very Good J     VVS2   
 7  0.24 Very Good I     VVS1   
 8  0.26 Very Good H     SI1    
 9  0.22 Fair      E     VS2    
10  0.23 Very Good H     VS1    
# ℹ 53,930 more rows
# 选取e结尾的变量
diamonds %>%
  select(ends_with("e"))
# A tibble: 53,940 × 2
   table price
   <dbl> <int>
 1    55   326
 2    61   326
 3    65   327
 4    58   334
 5    58   335
 6    57   336
 7    57   336
 8    55   337
 9    61   337
10    61   338
# ℹ 53,930 more rows
# 选取包含a的变量
diamonds %>%
  select(matches("a"))
# A tibble: 53,940 × 3
   carat clarity table
   <dbl> <ord>   <dbl>
 1  0.23 SI2        55
 2  0.21 SI1        61
 3  0.23 VS1        65
 4  0.29 VS2        58
 5  0.31 SI2        58
 6  0.24 VVS2       57
 7  0.24 VVS1       57
 8  0.26 SI1        55
 9  0.22 VS2        61
10  0.23 VS1        61
# ℹ 53,930 more rows
# 选取全部变量
diamonds %>%
  select(everything())
# A tibble: 53,940 × 10
   carat cut       color clarity depth table price     x     y     z
   <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.23 Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43
 2  0.21 Premium   E     SI1      59.8    61   326  3.89  3.84  2.31
 3  0.23 Good      E     VS1      56.9    65   327  4.05  4.07  2.31
 4  0.29 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63
 5  0.31 Good      J     SI2      63.3    58   335  4.34  4.35  2.75
 6  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48
 7  0.24 Very Good I     VVS1     62.3    57   336  3.95  3.98  2.47
 8  0.26 Very Good H     SI1      61.9    55   337  4.07  4.11  2.53
 9  0.22 Fair      E     VS2      65.1    61   337  3.87  3.78  2.49
10  0.23 Very Good H     VS1      59.4    61   338  4     4.05  2.39
# ℹ 53,930 more rows
# 选取最后一个变量
diamonds %>%
  select(last_col())
# A tibble: 53,940 × 1
       z
   <dbl>
 1  2.43
 2  2.31
 3  2.31
 4  2.63
 5  2.75
 6  2.48
 7  2.47
 8  2.53
 9  2.49
10  2.39
# ℹ 53,930 more rows
# 选取最后两个变量
diamonds %>%
  select(last_col(3))
# A tibble: 53,940 × 1
   price
   <int>
 1   326
 2   326
 3   327
 4   334
 5   335
 6   336
 7   336
 8   337
 9   337
10   338
# ℹ 53,930 more rows

6.4 where()

where() 是一个比较高级的、复杂的函数,因为它是一个“包着函数的函数”。

# 选取数值型的变量
diamonds %>%
  select(where(is.numeric))
# A tibble: 53,940 × 7
   carat depth table price     x     y     z
   <dbl> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.23  61.5    55   326  3.95  3.98  2.43
 2  0.21  59.8    61   326  3.89  3.84  2.31
 3  0.23  56.9    65   327  4.05  4.07  2.31
 4  0.29  62.4    58   334  4.2   4.23  2.63
 5  0.31  63.3    58   335  4.34  4.35  2.75
 6  0.24  62.8    57   336  3.94  3.96  2.48
 7  0.24  62.3    57   336  3.95  3.98  2.47
 8  0.26  61.9    55   337  4.07  4.11  2.53
 9  0.22  65.1    61   337  3.87  3.78  2.49
10  0.23  59.4    61   338  4     4.05  2.39
# ℹ 53,930 more rows
# 选取文本型的变量(没有)
diamonds %>%
  select(where(is.character))
# A tibble: 53,940 × 0
# 选取类别型的变量
diamonds %>%
  select(where(is.factor))
# A tibble: 53,940 × 3
   cut       color clarity
   <ord>     <ord> <ord>  
 1 Ideal     E     SI2    
 2 Premium   E     SI1    
 3 Good      E     VS1    
 4 Premium   I     VS2    
 5 Good      J     SI2    
 6 Very Good J     VVS2   
 7 Very Good I     VVS1   
 8 Very Good H     SI1    
 9 Fair      E     VS2    
10 Very Good H     VS1    
# ℹ 53,930 more rows
# where() 里面可以装更复杂的函数
diamonds %>%
  select(where(is.numeric)) %>%
  select(where(~ mean(.x) < 8))
# A tibble: 53,940 × 4
   carat     x     y     z
   <dbl> <dbl> <dbl> <dbl>
 1  0.23  3.95  3.98  2.43
 2  0.21  3.89  3.84  2.31
 3  0.23  4.05  4.07  2.31
 4  0.29  4.2   4.23  2.63
 5  0.31  4.34  4.35  2.75
 6  0.24  3.94  3.96  2.48
 7  0.24  3.95  3.98  2.47
 8  0.26  4.07  4.11  2.53
 9  0.22  3.87  3.78  2.49
10  0.23  4     4.05  2.39
# ℹ 53,930 more rows