9.1 常用操作
dplyr 由 Hadley Wickham 主要由开发和维护,是Rstudio公司开源的用于数据处理的一大利器,该包号称「数据操作的语法」,与 ggplot2 的「图形语法」 对应,也就是说数据处理那一套已经建立完整的和SQL一样的功能。它们都遵循同样的处理逻辑,只不过一个用SQL写,一个用R语言写,处理效率差不多,R语言写的 SQL 会被翻译为 SQL 语句,再传至数据库查询,当然它也支持内存内的数据操作。目前 dplyr 以 dbplyr 为后端支持的数据库有:MySQL、PostgreSQL,SQLite等,完整的支持列表请看 这里,连接特定数据库,都是基于 DBI,DBI 即 Database Interface, 是使用C/C++开发的底层数据库接口,是一个统一的关系型数据库连接框架,需要根据不同的具体的数据库进行实例化,才可使用。
dplyr 常用的函数是 7 个: arrange
排序 filter
过滤行 select
选择列 mutate
变换 summarise
汇总 group_by
分组 distinct
去重
以 ggplot2 包自带的钻石数据集 diamonds 为例介绍
9.1.1 查看
除了直接打印数据集的前几行,tibble 包还提供 glimpse 函数查看数据集,而 Base R 默认查看方式是调用 str 函数
data("diamonds", package = "ggplot2")
glimpse(diamonds)
## Rows: 53,940
## Columns: 10
## $ carat <dbl> 0.23, 0.21, 0.23, 0.29, 0.31, 0.24, 0.24, 0.26, 0.22, 0.23, 0.…
## $ cut <ord> Ideal, Premium, Good, Premium, Good, Very Good, Very Good, Ver…
## $ color <ord> E, E, E, I, J, J, I, H, E, H, J, J, F, J, E, E, I, J, J, J, I,…
## $ clarity <ord> SI2, SI1, VS1, VS2, SI2, VVS2, VVS1, SI1, VS2, VS1, SI1, VS1, …
## $ depth <dbl> 61.5, 59.8, 56.9, 62.4, 63.3, 62.8, 62.3, 61.9, 65.1, 59.4, 64…
## $ table <dbl> 55, 61, 65, 58, 58, 57, 57, 55, 61, 61, 55, 56, 61, 54, 62, 58…
## $ price <int> 326, 326, 327, 334, 335, 336, 336, 337, 337, 338, 339, 340, 34…
## $ x <dbl> 3.95, 3.89, 4.05, 4.20, 4.34, 3.94, 3.95, 4.07, 3.87, 4.00, 4.…
## $ y <dbl> 3.98, 3.84, 4.07, 4.23, 4.35, 3.96, 3.98, 4.11, 3.78, 4.05, 4.…
## $ z <dbl> 2.43, 2.31, 2.31, 2.63, 2.75, 2.48, 2.47, 2.53, 2.49, 2.39, 2.…
类型 | 含义 |
---|---|
int | 整型 integer |
dbl | (单)双精度浮点类型 |
chr | 字符(串)类型 |
dttm | data-time 类型 |
lgl | 布尔类型 |
fctr | 因子类型 factor |
date | 日期类型 |
表 9.1 中 dttm 和 date 类型代指 lubridate 包指定的日期对象 POSIXct、 POSIXlt、 Date、 chron、 yearmon、 yearqtr、 zoo、 zooreg、 timeDate、 xts、 its、 ti、 jul、 timeSeries 和 fts。
9.1.2 筛选
按条件筛选数据的子集,按行筛选
|> filter(cut == "Ideal" , carat >= 3) diamonds
## # A tibble: 4 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 3.22 Ideal I I1 62.6 55 12545 9.49 9.42 5.92
## 2 3.5 Ideal H I1 62.8 57 12587 9.65 9.59 6.03
## 3 3.01 Ideal J SI2 61.7 58 16037 9.25 9.2 5.69
## 4 3.01 Ideal J I1 65.4 60 16538 8.99 8.93 5.86
先按行,再按列筛选
|>
diamonds filter(carat >= 3, color == "I") |>
select(cut, carat)
## # A tibble: 16 × 2
## cut carat
## <ord> <dbl>
## 1 Premium 3.01
## 2 Fair 3.02
## 3 Good 3
## 4 Ideal 3.22
## 5 Premium 4.01
## 6 Very Good 3.04
## 7 Very Good 4
## 8 Premium 3.67
## 9 Premium 3
## 10 Fair 3
## 11 Premium 3.01
## 12 Fair 3.01
## 13 Fair 3.01
## 14 Good 3.01
## 15 Good 3.01
## 16 Premium 3.04
9.1.3 排序
arrange 默认升序排列,按钻石重量升序,按价格降序
|>
diamonds filter(cut == "Ideal" , carat >= 3) |>
arrange(carat, desc(price))
## # A tibble: 4 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 3.01 Ideal J I1 65.4 60 16538 8.99 8.93 5.86
## 2 3.01 Ideal J SI2 61.7 58 16037 9.25 9.2 5.69
## 3 3.22 Ideal I I1 62.6 55 12545 9.49 9.42 5.92
## 4 3.5 Ideal H I1 62.8 57 12587 9.65 9.59 6.03
9.1.4 聚合
分组求和,求平均,计数
|>
diamonds filter(carat > 3, color == "I") |>
group_by(cut, clarity) |>
summarise(sum_carat = sum(carat), mean_carat = mean(carat), n_count = n())
## # A tibble: 8 × 5
## # Groups: cut [5]
## cut clarity sum_carat mean_carat n_count
## <ord> <ord> <dbl> <dbl> <int>
## 1 Fair I1 3.02 3.02 1
## 2 Fair SI2 6.02 3.01 2
## 3 Good SI2 6.02 3.01 2
## 4 Very Good I1 4 4 1
## 5 Very Good SI2 3.04 3.04 1
## 6 Premium I1 10.7 3.56 3
## 7 Premium SI2 6.05 3.02 2
## 8 Ideal I1 3.22 3.22 1
9.1.5 合并
按行合并
set.seed(2018)
<- diamonds |>
one filter(color == "I") |>
sample_n(5)
<- diamonds |>
two filter(color == "J") |>
sample_n(5)
# 按行合并数据框 one 和 two
bind_rows(one, two)
## # A tibble: 10 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.42 Ideal I VVS1 62.5 57 884 4.77 4.8 2.99
## 2 0.3 Ideal I VVS2 62.5 53.6 532 4.29 4.33 2.69
## 3 2.02 Good I VS1 57.9 63 17533 8.13 8.21 4.73
## 4 0.9 Premium I VS2 61.9 58 3398 6.18 6.23 3.84
## 5 1.98 Very Good I VS2 62.7 60 15083 7.9 7.96 4.98
## 6 1.51 Very Good J VVS2 62.6 63 8706 7.29 7.24 4.55
## 7 0.7 Very Good J SI1 61.7 57 1979 5.65 5.69 3.5
## 8 1.16 Premium J VS2 62.2 59 4702 6.74 6.69 4.18
## 9 1.5 Premium J VVS2 61.8 60 8760 7.36 7.33 4.54
## 10 1.51 Premium J SI1 60.4 62 6680 7.42 7.32 4.45
按列合并
set.seed(2018)
<- diamonds |>
three select(carat, color) |>
sample_n(5)
<- diamonds |>
four select(carat, color) |>
sample_n(5)
bind_cols(three, four)
## # A tibble: 5 × 4
## carat...1 color...2 carat...3 color...4
## <dbl> <ord> <dbl> <ord>
## 1 0.33 H 0.52 F
## 2 1.09 F 0.51 F
## 3 1.52 I 0.5 G
## 4 0.95 G 0.38 E
## 5 0.35 E 0.51 J
9.1.6 变换
添加一列,新的列或者改变原来的列
|>
diamonds filter(carat > 3, color == "I") |>
select(cut, carat) |>
mutate(vol = if_else(carat > 3.5, "A", "B"))
## # A tibble: 13 × 3
## cut carat vol
## <ord> <dbl> <chr>
## 1 Premium 3.01 B
## 2 Fair 3.02 B
## 3 Ideal 3.22 B
## 4 Premium 4.01 A
## 5 Very Good 3.04 B
## 6 Very Good 4 A
## 7 Premium 3.67 A
## 8 Premium 3.01 B
## 9 Fair 3.01 B
## 10 Fair 3.01 B
## 11 Good 3.01 B
## 12 Good 3.01 B
## 13 Premium 3.04 B
9.1.7 去重
数据去重在 dplyr 中的实现29。
set.seed(123)
<- data.frame(
df x = sample(0:1, 10, replace = T),
y = sample(0:1, 10, replace = T),
z = 1:10
) df
## x y z
## 1 0 1 1
## 2 0 1 2
## 3 0 1 3
## 4 1 0 4
## 5 0 1 5
## 6 1 0 6
## 7 1 1 7
## 8 1 0 8
## 9 0 0 9
## 10 0 0 10
去掉列重复的数据点 (x, y)
|>
df group_by(x, y) |>
filter(row_number(z) == 1)
## # A tibble: 4 × 3
## # Groups: x, y [4]
## x y z
## <int> <int> <int>
## 1 0 1 1
## 2 1 0 4
## 3 1 1 7
## 4 0 0 9
# 此处不对,没有了 z
|>
df distinct(x, y)
## x y
## 1 0 1
## 2 1 0
## 3 1 1
## 4 0 0
# 应该为
|>
df distinct(x, y, .keep_all = TRUE)
## x y z
## 1 0 1 1
## 2 1 0 4
## 3 1 1 7
## 4 0 0 9