数据框是R语言中的一个重要数据结构,在数据分析过程中,主要的数据对象就是数据框。R语言内置了data.frame类,dplyr包则加强了数据框的各种操作,语法与SQL类似,使数据框的处理变得灵活多变,处理速度得到很大提升。
本文针对在数据分析中数据框使用的各种常用场景,总结了dplyr包的使用方法。本文为该系列的第一篇。
环境&软件
- win10 64bit
- R 3.6.1
安装包
install.packages("dplyr")
管道操作符 %>%
管道操作符%>%
,在dplyr中被大量使用,用来简化代码结构,减少中间变量,使代码更符合思维习惯。RStudio快捷键:Ctrl+Shift+m
。
library(dplyr)
# 查看数据前3行
head(iris,3) # 常规方式
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## Species
## 1 setosa
## 2 setosa
## 3 setosa
iris %>% head(3) # 管道符方式
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## Species
## 1 setosa
## 2 setosa
## 3 setosa
数据框 tibble
tibble
是data.frame的简化版本,适用data.frame的所有语法,同时有更简单的数据框创建方式。
# 1.data.frame转为tibble
as_tibble(mtcars)
## # A tibble: 32 x 11
## mpg cyl disp hp drat wt qsec vs am
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 21 6 160 110 3.9 2.62 16.5 0 1
## 2 21 6 160 110 3.9 2.88 17.0 0 1
## 3 22.8 4 108 93 3.85 2.32 18.6 1 1
## 4 21.4 6 258 110 3.08 3.22 19.4 1 0
## 5 18.7 8 360 175 3.15 3.44 17.0 0 0
## 6 18.1 6 225 105 2.76 3.46 20.2 1 0
## 7 14.3 8 360 245 3.21 3.57 15.8 0 0
## 8 24.4 4 147. 62 3.69 3.19 20 1 0
## 9 22.8 4 141. 95 3.92 3.15 22.9 1 0
## 10 19.2 6 168. 123 3.92 3.44 18.3 1 0
## # … with 22 more rows, and 2 more variables:
## # gear <dbl>, carb <dbl>
# 2.构造tibble,引用列变量
tibble(x=1:4,y=x+1)
## # A tibble: 4 x 2
## x y
## <int> <dbl>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 3.构造tibble,不引用列变量(!!)
x <- 11:14
tibble(x=1:4,y=!!x+1)
## # A tibble: 4 x 2
## x y
## <int> <dbl>
## 1 1 12
## 2 2 13
## 3 3 14
## 4 4 15
列筛选 select
select
函数用来对数据框的列进行选择筛选。
# 数据
tbl_df <- tibble(var1=1:4,var2=2:5,label=c("a","b","a","c"))
基本方法
选择列的基本方法。
# 引用选择列
tbl_df %>% select(var1,var2)
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 范围引用选择列
tbl_df %>% select(var1:var2)
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 列位置选择列
tbl_df %>% select(1,2)
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 列位置范围选择列
tbl_df %>% select(2:3)
## # A tibble: 4 x 2
## var2 label
## <int> <chr>
## 1 2 a
## 2 3 b
## 3 4 a
## 4 5 c
# 字符向量选择列
tbl_df %>% select(c("var1","var2"))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 位置向量选择列
tbl_df %>% select(c(1,2))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
反向选择
用-
符号来进行反向选择列。
# 引用选择列(反向)
tbl_df %>% select(-var1,-var2)
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 范围引用选择列(反向)
tbl_df %>% select(-var1:-var2)
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 列位置选择列(反向)
tbl_df %>% select(-1,-2)
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 列位置范围选择列(反向)
tbl_df %>% select(-2:-3)
## # A tibble: 4 x 1
## var1
## <int>
## 1 1
## 2 2
## 3 3
## 4 4
# 字符向量选择列(反向)
tbl_df %>% select(-c("var1","var2"))
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 位置向量选择列(反向)
tbl_df %>% select(-c(1,2))
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
匹配选择
还可以通过模式匹配的方式,批量选择列。
# 1.前缀匹配
tbl_df %>% select(starts_with("var"))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 2.后缀匹配
tbl_df %>% select(ends_with("l"))
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 3.包含匹配
tbl_df %>% select(contains("a"))
## # A tibble: 4 x 3
## var1 var2 label
## <int> <int> <chr>
## 1 1 2 a
## 2 2 3 b
## 3 3 4 a
## 4 4 5 c
# 4.正则匹配
tbl_df %>% select(matches("\\d"))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 5.数字匹配
tbl_df %>% select(num_range("var",1:2))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 6.列名匹配
tbl_df %>% select(one_of(c("var1","var2")))
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 反向匹配(以上6种方法都适用)
tbl_df %>% select(-one_of(c("var1","var2")))
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
其他选择
包括一些列顺序调整,选择最后一列等小技巧。
# 条件选择(选择所有数值列)
tbl_df %>% select_if(is.numeric)
## # A tibble: 4 x 2
## var1 var2
## <int> <int>
## 1 1 2
## 2 2 3
## 3 3 4
## 4 4 5
# 列顺序调整
tbl_df %>% select(var2,everything())
## # A tibble: 4 x 3
## var2 var1 label
## <int> <int> <chr>
## 1 2 1 a
## 2 3 2 b
## 3 4 3 a
## 4 5 4 c
# 选择列的方式重命名列
tbl_df %>% select(rename_var1=var1)
## # A tibble: 4 x 1
## rename_var1
## <int>
## 1 1
## 2 2
## 3 3
## 4 4
# 选择最后一列
tbl_df %>% select(last_col())
## # A tibble: 4 x 1
## label
## <chr>
## 1 a
## 2 b
## 3 a
## 4 c
# 倒数第二列
tbl_df %>% select(last_col(1))
## # A tibble: 4 x 1
## var2
## <int>
## 1 2
## 2 3
## 3 4
## 4 5
列变形 mutate/transmute
mutate
和transmute
函数用来对数据框的列进行新增、修改、删除等操作,二者的使用方法基本相同,区别在于transmute函数会在进行操作后删除原有列,而mutate会保留原有列。
# 数据
tbl_df <- tibble(var1=1:4,var2=2:5,label=c("a","b","a","c"))
mutate
- 单个模式
单个模式中,可以完成对单列变形。
tbl_df %>% mutate(new1=var1,new2=new1+10) # 新增列(先增列能被后增列引用)
## # A tibble: 4 x 5
## var1 var2 label new1 new2
## <int> <int> <chr> <int> <dbl>
## 1 1 2 a 1 11
## 2 2 3 b 2 12
## 3 3 4 a 3 13
## 4 4 5 c 4 14
tbl_df %>% mutate(var1=NULL) # 删除原列
## # A tibble: 4 x 2
## var2 label
## <int> <chr>
## 1 2 a
## 2 3 b
## 3 4 a
## 4 5 c
tbl_df %>% mutate(var1=var1+1) # 修改原列
## # A tibble: 4 x 3
## var1 var2 label
## <dbl> <int> <chr>
## 1 2 2 a
## 2 3 3 b
## 3 4 4 a
## 4 5 5 c
var1 <- 11:14
tbl_df %>% mutate(var1=!!var1) # 新增列(非引用方式)
## # A tibble: 4 x 3
## var1 var2 label
## <int> <int> <chr>
## 1 11 2 a
## 2 12 3 b
## 3 13 4 a
## 4 14 5 c
- 批量模式
批量模式中,可以
# 全部列
tbl_df %>% mutate_all(rev) # 单函数(不产生新列)
## # A tibble: 4 x 3
## var1 var2 label
## <int> <int> <chr>
## 1 4 5 c
## 2 3 4 a
## 3 2 3 b
## 4 1 2 a
tbl_df %>% mutate_all(list(rev=rev)) # 单函数(产生新列)
## # A tibble: 4 x 6
## var1 var2 label var1_rev var2_rev label_rev
## <int> <int> <chr> <int> <int> <chr>
## 1 1 2 a 4 5 c
## 2 2 3 b 3 4 a
## 3 3 4 a 2 3 b
## 4 4 5 c 1 2 a
tbl_df %>% mutate_all(list(rev=rev,sort=sort)) # 多函数
## # A tibble: 4 x 9
## var1 var2 label var1_rev var2_rev label_rev
## <int> <int> <chr> <int> <int> <chr>
## 1 1 2 a 4 5 c
## 2 2 3 b 3 4 a
## 3 3 4 a 2 3 b
## 4 4 5 c 1 2 a
## # … with 3 more variables: var1_sort <int>,
## # var2_sort <int>, label_sort <chr>
# 指定列
tbl_df %>% mutate_at(c("var1","var2"),exp) # 列名+单函数
## # A tibble: 4 x 3
## var1 var2 label
## <dbl> <dbl> <chr>
## 1 2.72 7.39 a
## 2 7.39 20.1 b
## 3 20.1 54.6 a
## 4 54.6 148. c
tbl_df %>% mutate_at(c("var1","var2"),~round(log(.),1)) # 列名+匿名函数
## # A tibble: 4 x 3
## var1 var2 label
## <dbl> <dbl> <chr>
## 1 0 0.7 a
## 2 0.7 1.1 b
## 3 1.1 1.4 a
## 4 1.4 1.6 c
tbl_df %>% mutate_at(c(1,2),exp) # 列位置+单函数
## # A tibble: 4 x 3
## var1 var2 label
## <dbl> <dbl> <chr>
## 1 2.72 7.39 a
## 2 7.39 20.1 b
## 3 20.1 54.6 a
## 4 54.6 148. c
tbl_df %>% mutate_at(c(1,2),list(log=log,exp=exp)) # 列位置+多函数
## # A tibble: 4 x 7
## var1 var2 label var1_log var2_log var1_exp var2_exp
## <int> <int> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1 2 a 0 0.693 2.72 7.39
## 2 2 3 b 0.693 1.10 7.39 20.1
## 3 3 4 a 1.10 1.39 20.1 54.6
## 4 4 5 c 1.39 1.61 54.6 148.
tbl_df %>% mutate_at(vars(matches("\\d")),exp) # vars方式
## # A tibble: 4 x 3
## var1 var2 label
## <dbl> <dbl> <chr>
## 1 2.72 7.39 a
## 2 7.39 20.1 b
## 3 20.1 54.6 a
## 4 54.6 148. c
# 条件列
tbl_df %>% mutate_if(is.character,rev) # 单函数
## # A tibble: 4 x 3
## var1 var2 label
## <int> <int> <chr>
## 1 1 2 c
## 2 2 3 a
## 3 3 4 b
## 4 4 5 a
tbl_df %>% mutate_if(is.numeric,list(log=log,exp=exp)) # 多函数
## # A tibble: 4 x 7
## var1 var2 label var1_log var2_log var1_exp var2_exp
## <int> <int> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1 2 a 0 0.693 2.72 7.39
## 2 2 3 b 0.693 1.10 7.39 20.1
## 3 3 4 a 1.10 1.39 20.1 54.6
## 4 4 5 c 1.39 1.61 54.6 148.
transmute
- 单个模式
tbl_df %>% transmute(new1=var1,new2=new1+10) # 新增列(先增列能被后增列引用)
## # A tibble: 4 x 2
## new1 new2
## <int> <dbl>
## 1 1 11
## 2 2 12
## 3 3 13
## 4 4 14
tbl_df %>% transmute(var1=var1+1) # 覆盖原列
## # A tibble: 4 x 1
## var1
## <dbl>
## 1 2
## 2 3
## 3 4
## 4 5
var1 <- 11:14
tbl_df %>% transmute(var1=!!var1) # 新增列(非引用方式)
## # A tibble: 4 x 1
## var1
## <int>
## 1 11
## 2 12
## 3 13
## 4 14
- 批量模式
# 全部列
tbl_df %>% transmute_all(rev) # 单函数(不产生新列)
## # A tibble: 4 x 3
## var1 var2 label
## <int> <int> <chr>
## 1 4 5 c
## 2 3 4 a
## 3 2 3 b
## 4 1 2 a
tbl_df %>% transmute_all(list(rev=rev)) # 单函数(产生新列)
## # A tibble: 4 x 3
## var1_rev var2_rev label_rev
## <int> <int> <chr>
## 1 4 5 c
## 2 3 4 a
## 3 2 3 b
## 4 1 2 a
tbl_df %>% transmute_all(list(rev=rev,sort=sort)) # 多函数
## # A tibble: 4 x 6
## var1_rev var2_rev label_rev var1_sort var2_sort
## <int> <int> <chr> <int> <int>
## 1 4 5 c 1 2
## 2 3 4 a 2 3
## 3 2 3 b 3 4
## 4 1 2 a 4 5
## # … with 1 more variable: label_sort <chr>
tbl_df %>% transmute_all(list(rev=~rev(.),sort=~sort(.))) # 多匿名函数
## # A tibble: 4 x 6
## var1_rev var2_rev label_rev var1_sort var2_sort
## <int> <int> <chr> <int> <int>
## 1 4 5 c 1 2
## 2 3 4 a 2 3
## 3 2 3 b 3 4
## 4 1 2 a 4 5
## # … with 1 more variable: label_sort <chr>
# 指定列
tbl_df %>% transmute_at(c("var1","var2"),exp) # 列名+单函数
## # A tibble: 4 x 2
## var1 var2
## <dbl> <dbl>
## 1 2.72 7.39
## 2 7.39 20.1
## 3 20.1 54.6
## 4 54.6 148.
tbl_df %>% transmute_at(c("var1","var2"),~round(log(.),1)) # 列名+匿名函数
## # A tibble: 4 x 2
## var1 var2
## <dbl> <dbl>
## 1 0 0.7
## 2 0.7 1.1
## 3 1.1 1.4
## 4 1.4 1.6
tbl_df %>% transmute_at(c(1,2),exp) # 列位置+单函数
## # A tibble: 4 x 2
## var1 var2
## <dbl> <dbl>
## 1 2.72 7.39
## 2 7.39 20.1
## 3 20.1 54.6
## 4 54.6 148.
tbl_df %>% transmute_at(c(1,2),list(log=log,exp=exp)) # 列位置+多函数
## # A tibble: 4 x 4
## var1_log var2_log var1_exp var2_exp
## <dbl> <dbl> <dbl> <dbl>
## 1 0 0.693 2.72 7.39
## 2 0.693 1.10 7.39 20.1
## 3 1.10 1.39 20.1 54.6
## 4 1.39 1.61 54.6 148.
tbl_df %>% transmute_at(vars(matches("\\d")),exp) # vars方式
## # A tibble: 4 x 2
## var1 var2
## <dbl> <dbl>
## 1 2.72 7.39
## 2 7.39 20.1
## 3 20.1 54.6
## 4 54.6 148.
# 条件列
tbl_df %>% transmute_if(is.character,rev) # 单函数
## # A tibble: 4 x 1
## label
## <chr>
## 1 c
## 2 a
## 3 b
## 4 a
tbl_df %>% transmute_if(is.numeric,list(log=log,exp=exp)) # 多函数
## # A tibble: 4 x 4
## var1_log var2_log var1_exp var2_exp
## <dbl> <dbl> <dbl> <dbl>
## 1 0 0.693 2.72 7.39
## 2 0.693 1.10 7.39 20.1
## 3 1.10 1.39 20.1 54.6
## 4 1.39 1.61 54.6 148.