dplyr是R语言tidyverse数据处理系统里面一个用来进行数据操作的一个包。里面包括很多使用的函数,这个就来介绍一下列的选择:select()函数的时候吧。这个帖子是基于https://suzanbaert.netlify.app/2018/01/dplyr-tutorial-1/的学习笔记。
这一次我们就先选择列这个select()函数进行讲解
library(tidyverse)
data("msleep")
glimpse(msleep)
## Rows: 83
## Columns: 11
## $ name <chr> "Cheetah", "Owl monkey", "Mountain beaver", "Greater sho…
## $ genus <chr> "Acinonyx", "Aotus", "Aplodontia", "Blarina", "Bos", "Br…
## $ vore <chr> "carni", "omni", "herbi", "omni", "herbi", "herbi", "car…
## $ order <chr> "Carnivora", "Primates", "Rodentia", "Soricomorpha", "Ar…
## $ conservation <chr> "lc", NA, "nt", "lc", "domesticated", NA, "vu", NA, "dom…
## $ sleep_total <dbl> 12.1, 17.0, 14.4, 14.9, 4.0, 14.4, 8.7, 7.0, 10.1, 3.0, …
## $ sleep_rem <dbl> NA, 1.8, 2.4, 2.3, 0.7, 2.2, 1.4, NA, 2.9, NA, 0.6, 0.8,…
## $ sleep_cycle <dbl> NA, NA, NA, 0.1333333, 0.6666667, 0.7666667, 0.3833333, …
## $ awake <dbl> 11.9, 7.0, 9.6, 9.1, 20.0, 9.6, 15.3, 17.0, 13.9, 21.0, …
## $ brainwt <dbl> NA, 0.01550, NA, 0.00029, 0.42300, NA, NA, NA, 0.07000, …
## $ bodywt <dbl> 50.000, 0.480, 1.350, 0.019, 600.000, 3.850, 20.490, 0.0…
最基本的选择方法
在dplyr当中,我们可以通过select()函数来选择相对应的列。我们只需要数据相对应的列名或者想要选择列的位置即可。
### 选择order和sleep_cycle两列
msleep %>% select(order, sleep_cycle) %>% head
## # A tibble: 6 x 2
## order sleep_cycle
## <chr> <dbl>
## 1 Carnivora NA
## 2 Primates NA
## 3 Rodentia NA
## 4 Soricomorpha 0.133
## 5 Artiodactyla 0.667
## 6 Pilosa 0.767
### 同时等价于
msleep %>% select(4,8) %>% head
## # A tibble: 6 x 2
## order sleep_cycle
## <chr> <dbl>
## 1 Carnivora NA
## 2 Primates NA
## 3 Rodentia NA
## 4 Soricomorpha 0.133
## 5 Artiodactyla 0.667
## 6 Pilosa 0.767
同时,如果我们需要选择连续多列的数据的话,可以使用:
来进行选择。
msleep %>% select(order:sleep_total) %>% head
## # A tibble: 6 x 3
## order conservation sleep_total
## <chr> <chr> <dbl>
## 1 Carnivora lc 12.1
## 2 Primates <NA> 17
## 3 Rodentia nt 14.4
## 4 Soricomorpha lc 14.9
## 5 Artiodactyla domesticated 4
## 6 Pilosa <NA> 14.4
##上面的这个等价于
msleep %>% select(4:6) %>% head
## # A tibble: 6 x 3
## order conservation sleep_total
## <chr> <chr> <dbl>
## 1 Carnivora lc 12.1
## 2 Primates <NA> 17
## 3 Rodentia nt 14.4
## 4 Soricomorpha lc 14.9
## 5 Artiodactyla domesticated 4
## 6 Pilosa <NA> 14.4
如果我们在选择目标列的时候,可以通过-
来反向选择目标列的。
###反向选择name:awake之外的数据,同时把conservation这一列纳入进来。
msleep %>%
select(-(name:awake), conservation) %>%
head
## # A tibble: 6 x 3
## brainwt bodywt conservation
## <dbl> <dbl> <chr>
## 1 NA 50 lc
## 2 0.0155 0.48 <NA>
## 3 NA 1.35 nt
## 4 0.00029 0.019 lc
## 5 0.423 600 domesticated
## 6 NA 3.85 <NA>
部分搜索
上面介绍的是使用精确搜索的方式来进行搜索的。但是有时候我们想要选择其中一类列的话。就不能单纯的使用数据相对应的检索试就行了。在dplyr里面,提供了一些常用的模糊所有的函数方便我们来检索的。这些函数包括:
- starts_with(): 选择以某一个字符开头的列
- ends_with(): 选择以某几个字符结尾的列
- contains(): 选择包含某几个字符的列
以上的这些其为都是在select()函数当中使用的。单独的时候是不能使用的。
msleep %>%
select(contains("eep"), ends_with("wt")) %>% head
## # A tibble: 6 x 5
## sleep_total sleep_rem sleep_cycle brainwt bodywt
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 12.1 NA NA NA 50
## 2 17 1.8 NA 0.0155 0.48
## 3 14.4 2.4 NA NA 1.35
## 4 14.9 2.3 0.133 0.00029 0.019
## 5 4 0.7 0.667 0.423 600
## 6 14.4 2.2 0.767 NA 3.85
模糊搜索
以上的搜索方法输入的也是具体的准确的词。只是列名的一部分而已。如果我们想要进行正则表达式的检索的话。还是不使用的。这个时候就可以使用matches()函数。这个函数里面可以输入正则表达式的内容。
msleep %>%
select(matches("o.+er")) %>% head
## # A tibble: 6 x 2
## order conservation
## <chr> <chr>
## 1 Carnivora lc
## 2 Primates <NA>
## 3 Rodentia nt
## 4 Soricomorpha lc
## 5 Artiodactyla domesticated
## 6 Pilosa <NA>
选择提前定义好的列名
有时候,我们在进行选择的时候,列名是提前定义好的。这样就不用一个一个的输入了。由于select()里面对于列名的数据和变量是一样的。所以我们不能把定义好的变量直接输入进行。这样代码还是会在列名当中查找输入的变量。所以需要进行一定的转换。具体的转换就是在变量名前面加!!
即可
classification <- c("name", "genus", "vore", "order", "conservation")
msleep %>%
select(!!classification) %>% head
## # A tibble: 6 x 5
## name genus vore order conservation
## <chr> <chr> <chr> <chr> <chr>
## 1 Cheetah Acinonyx carni Carnivora lc
## 2 Owl monkey Aotus omni Primates <NA>
## 3 Mountain beaver Aplodontia herbi Rodentia nt
## 4 Greater short-tailed shrew Blarina omni Soricomorpha lc
## 5 Cow Bos herbi Artiodactyla domesticated
## 6 Three-toed sloth Bradypus herbi Pilosa <NA>
列名的重命名
我们的选择列的时候。有时候觉得列名不好想要重新命名。这个时候可以在选择的时候直接重新定义了。同时如果我们只是想要修改列名的话可以使用rename()函数。
msleep %>% select(Ordered = order) %>% head
## # A tibble: 6 x 1
## Ordered
## <chr>
## 1 Carnivora
## 2 Primates
## 3 Rodentia
## 4 Soricomorpha
## 5 Artiodactyla
## 6 Pilosa
如果我有很多列名想要重新命名的话,但是如果一个一个敲打有很麻烦。那就可以提前先构建好向量。这样的话就可以一下子选择加重命名了。当然如果只是想单纯的重命名使用rename()即可了。
names(classification) <- paste0("Vars", seq_len(length(classification)))
classification
## Vars1 Vars2 Vars3 Vars4 Vars5
## "name" "genus" "vore" "order" "conservation"
msleep %>% select(!!classification) %>% head
## # A tibble: 6 x 5
## Vars1 Vars2 Vars3 Vars4 Vars5
## <chr> <chr> <chr> <chr> <chr>
## 1 Cheetah Acinonyx carni Carnivora lc
## 2 Owl monkey Aotus omni Primates <NA>
## 3 Mountain beaver Aplodontia herbi Rodentia nt
## 4 Greater short-tailed shrew Blarina omni Soricomorpha lc
## 5 Cow Bos herbi Artiodactyla domesticated
## 6 Three-toed sloth Bradypus herbi Pilosa <NA>
对所有列进行重定义
我们有时候需要对所有的列名进行相同的操作。例如把所有列名的字母都变成大写。这种情况下,我们就可以使用seelct_all()进行操作了。
msleep %>% select_all(toupper) %>% head
## # A tibble: 6 x 11
## NAME GENUS VORE ORDER CONSERVATION SLEEP_TOTAL SLEEP_REM SLEEP_CYCLE AWAKE
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Chee… Acin… carni Carn… lc 12.1 NA NA 11.9
## 2 Owl … Aotus omni Prim… <NA> 17 1.8 NA 7
## 3 Moun… Aplo… herbi Rode… nt 14.4 2.4 NA 9.6
## 4 Grea… Blar… omni Sori… lc 14.9 2.3 0.133 9.1
## 5 Cow Bos herbi Arti… domesticated 4 0.7 0.667 20
## 6 Thre… Brad… herbi Pilo… <NA> 14.4 2.2 0.767 9.6
## # … with 2 more variables: BRAINWT <dbl>, BODYWT <dbl>
这个函数操作对象还是列名的,如果我们想要替换所有列名当中的某一个符号也是可以使用这个函数的。
msleep %>% select_all(~str_replace(., "_", "-")) %>%
select(contains("-")) %>% head
## # A tibble: 6 x 3
## `sleep-total` `sleep-rem` `sleep-cycle`
## <dbl> <dbl> <dbl>
## 1 12.1 NA NA
## 2 17 1.8 NA
## 3 14.4 2.4 NA
## 4 14.9 2.3 0.133
## 5 4 0.7 0.667
## 6 14.4 2.2 0.767
按照逻辑值来进行选择
有时候我们需要想要基于列的内容来进行选择相对应的列。这个时候,使用基本的select()函数就不行了。这个时候可以使用select_if()函数来进行筛选。
select_if不是针对列名来进行筛选的,而是针对列的内容来进行筛选的。其中内在的计算逻辑是,使用一个函数对每一列进行筛选,同时返回一个逻辑值。例如:
如果在select_if当中使用is.numeric()。则代表对每一列进行is.numeric函数的判断。对于T的则选择,对于F的则不选择
### 选择是数字型的列
msleep %>% select_if(is.numeric) %>% head
## # A tibble: 6 x 6
## sleep_total sleep_rem sleep_cycle awake brainwt bodywt
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 12.1 NA NA 11.9 NA 50
## 2 17 1.8 NA 7 0.0155 0.48
## 3 14.4 2.4 NA 9.6 NA 1.35
## 4 14.9 2.3 0.133 9.1 0.00029 0.019
## 5 4 0.7 0.667 20 0.423 600
## 6 14.4 2.2 0.767 9.6 NA 3.85
### 选择不是数字型的列
msleep %>% select_if(~!is.numeric(.)) %>% head
## # A tibble: 6 x 5
## name genus vore order conservation
## <chr> <chr> <chr> <chr> <chr>
## 1 Cheetah Acinonyx carni Carnivora lc
## 2 Owl monkey Aotus omni Primates <NA>
## 3 Mountain beaver Aplodontia herbi Rodentia nt
## 4 Greater short-tailed shrew Blarina omni Soricomorpha lc
## 5 Cow Bos herbi Artiodactyla domesticated
## 6 Three-toed sloth Bradypus herbi Pilosa <NA>
同样的,我们可以在里面自定义判断公式。对于自定义的函数,我们需要在前面加~
或者使用funs()函数代表是自定义的函数。
PS: 自定义的函数返回的结果需要是逻辑值,且每一列只返回一个逻辑值。
### 选择是数值型并且均值>10的列
msleep %>% select_if(is.numeric) %>%
select_if(~mean(., na.rm = T) > 10) %>% head
## # A tibble: 6 x 3
## sleep_total awake bodywt
## <dbl> <dbl> <dbl>
## 1 12.1 11.9 50
## 2 17 7 0.48
## 3 14.4 9.6 1.35
## 4 14.9 9.1 0.019
## 5 4 20 600
## 6 14.4 9.6 3.85
### 另外一种等价的方法
msleep %>% select_if(funs(is.numeric(.) & mean(., na.rm = T) > 10)) %>% head
## Warning: funs() is soft deprecated as of dplyr 0.8.0
## Please use a list of either functions or lambdas:
##
## # Simple named list:
## list(mean = mean, median = median)
##
## # Auto named with `tibble::lst()`:
## tibble::lst(mean, median)
##
## # Using lambdas
## list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
## This warning is displayed once per session.
## Warning in mean.default(., na.rm = T): argument is not numeric or logical:
## returning NA
## Warning in mean.default(., na.rm = T): argument is not numeric or logical:
## returning NA
## Warning in mean.default(., na.rm = T): argument is not numeric or logical:
## returning NA
## Warning in mean.default(., na.rm = T): argument is not numeric or logical:
## returning NA
## Warning in mean.default(., na.rm = T): argument is not numeric or logical:
## returning NA
## # A tibble: 6 x 3
## sleep_total awake bodywt
## <dbl> <dbl> <dbl>
## 1 12.1 11.9 50
## 2 17 7 0.48
## 3 14.4 9.6 1.35
## 4 14.9 9.1 0.019
## 5 4 20 600
## 6 14.4 9.6 3.85
网友评论