7  dplyr 选取或删除

我删除了你的微信,本质上是保留了除了你以外所有人的微信。所以删除的本质就是选取。因此,在tidyverse里面,选取函数兼具了“保留”(选取)和“删除”的功能。

7.1 select()

select() 可以根据位置选取列。

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

select() 也可以根据名称选取列。

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

7.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(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

7.3 head()tail()

diamonds %>%
  head() # 抽取前六条
# A tibble: 6 × 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
diamonds %>%
  tail() # 抽取后六条
# A tibble: 6 × 10
  carat cut       color clarity depth table price     x     y     z
  <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.72 Premium   D     SI1      62.7    59  2757  5.69  5.73  3.58
2  0.72 Ideal     D     SI1      60.8    57  2757  5.75  5.76  3.5 
3  0.72 Good      D     SI1      63.1    55  2757  5.69  5.75  3.61
4  0.7  Very Good D     SI1      62.8    60  2757  5.66  5.68  3.56
5  0.86 Premium   H     SI2      61      58  2757  6.15  6.12  3.74
6  0.75 Ideal     D     SI2      62.2    55  2757  5.83  5.87  3.64

7.4 slice()

比起 head()tail()slice() 的语法要更复杂、更灵活一点。和 select() 类似,slice() 可以选取任意位置的若干行,再重新拼接起来,因此要列明所有行号。

diamonds %>%
  slice(5) # 抽取第五条
# A tibble: 1 × 10
  carat cut   color clarity depth table price     x     y     z
  <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1  0.31 Good  J     SI2      63.3    58   335  4.34  4.35  2.75
diamonds %>%
  slice(1:5) # 抽取前五条
# A tibble: 5 × 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
diamonds %>%
  slice(-5) # 删除第五条
# A tibble: 53,939 × 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.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48
 6  0.24 Very Good I     VVS1     62.3    57   336  3.95  3.98  2.47
 7  0.26 Very Good H     SI1      61.9    55   337  4.07  4.11  2.53
 8  0.22 Fair      E     VS2      65.1    61   337  3.87  3.78  2.49
 9  0.23 Very Good H     VS1      59.4    61   338  4     4.05  2.39
10  0.3  Good      J     SI1      64      55   339  4.25  4.28  2.73
# ℹ 53,929 more rows

7.5 filter()

或许你还记得 arrange() 函数的讨论。我们说到变量具有统计能力,所以我们可以对单个变量排序,表现为改变个案顺序。同理,我们也可以对变量做判断,表现为筛选个案。

比方说,我们可以判断钻石的价格有没有低于 1000,且只保留那些 1000 以内的钻石。

diamonds %>%
  filter(price < 1000) # 仅筛选$1000以内的钻石
# A tibble: 14,499 × 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
# ℹ 14,489 more rows

我们也可以判断钻石的净度是不是等于 VVS2,且只保留判断成立的钻石。

diamonds %>%
  filter(clarity == "VVS2") # 仅筛选VVS2级净度的钻石
# A tibble: 5,066 × 10
   carat cut       color clarity depth table price     x     y     z
   <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
 1  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48
 2  0.23 Very Good G     VVS2     60.4    58   354  3.97  4.01  2.41
 3  0.28 Ideal     G     VVS2     61.4    56   553  4.19  4.22  2.58
 4  0.26 Very Good F     VVS2     59.2    60   554  4.19  4.22  2.49
 5  0.26 Very Good E     VVS2     59.9    58   554  4.15  4.23  2.51
 6  0.26 Very Good D     VVS2     62.4    54   554  4.08  4.13  2.56
 7  0.26 Very Good D     VVS2     62.8    60   554  4.01  4.05  2.53
 8  0.26 Ideal     E     VVS2     62.9    58   554  4.02  4.06  2.54
 9  0.24 Premium   H     VVS2     60.7    58   554  4.07  4.04  2.46
10  0.74 Ideal     I     VVS2     62.3    55  2761  5.77  5.81  3.61
# ℹ 5,056 more rows