R语言 tidyverse 之数据处理:dplyr (中)

在 dplyr 中使用 summarize 函数进行数据汇总时,通常要结合分组函数 group_by 一起使用。

1. group_by:分组函数

group_by 一般会和 mean、sum、max、min、median 等函数一起使用,对数据进行分组汇总,可以同时处理多个字段。

library(dplyr)
library(gapminder)

# 按 year 字段分组, 统计 lifeExp 的均值、对 pop 求和
gapminder %>%
    group_by(year) %>%
    summarize(mean_lifeExp = mean(lifeExp),
              total_pop = sum(pop))

# 按 year、continent 字段分组,统计 lifeExp 的中位数、pop 的最大值、gdpPercap 的最小值
gapminder %>%
    group_by(year, continent) %>%
    summarize(median_lifeExp = median(lifeExp),
              max_pop = max(pop),
              min_gdpPercap = min(gdpPercap))
2. count:计数函数

count 函数可以直接统计一个或多个字段分组后的个数,默认会新增一个列名为 n 的字段来表示统计结果,可以使用 name 参数重命名该字段,sort = TRUE 会按个数降序排。

# 按 year 分组计数
gapminder %>% count(year)

# 按 year、continent 分组计数,并降序排
gapminder %>% count(year, continent, name = 'cnt', sort = TRUE)

当然也可以使用 group_by 和 summarise 函数实现上述计数的统计,此时需使用 n() 函数,有时候我们需要去重计数,实现类似于 count distinct 的功能,这时可以使用 n_distinct 函数。

# 按 year 分组计数, 与 count 等价
gapminder %>% 
    group_by(year) %>%
    summarise(n = n())

# 按 year、continent 分组计数, 并降序排, 与 count 等价
gapminder %>% 
    group_by(year, continent) %>%
    summarise(cnt = n()) %>%
    arrange(desc(cnt))

# 分组去重计数,按 year 分组,去重统计 continent 的个数
# 类似于 select year, count(distinct continent) from table group by year
gapminder %>% 
    group_by(year) %>%
    summarise(n = n_distinct(continent))
3. 排序函数

dplyr 中的排序函数和 SQL 类似,有 row_number、rank 和 dense_rank 三种,特别注意的是 rank 函数,在 dplyr 包中的写法是 min_rank 而不是 rank,其他两个函数的名称和 SQL 一致,三者的区别如下:

  • row_number:相同值排序不重复
  • dense_rank:相同值排序重复,排序连续
  • min_rank:相同值排序重复,排序不连续
library(tibble)
# 新建一个 tibble 数据框
student_df <- tibble(
    name = c('张三', '李四', '王五', '赵六', '孙七', '周八', '吴九'),
    score = c(85, 83, 96, 92, 96, 95, 92)
)

# row_number 排序, 相同值不会重复
student_df %>%
    mutate(asc_order = row_number(score),
           desc_order = row_number(desc(score)))

# dense_rank 排序, 相同值重复且排序连续
student_df %>%
    mutate(asc_order = dense_rank(score))

# min_rank 排序, 相同值重复且排序不连续
student_df %>%
    mutate(asc_order = min_rank(score))

row_number 排序结果:
在这里插入图片描述

dense_rank 排序结果:
在这里插入图片描述
min_rank 排序结果:
在这里插入图片描述

4. slice 系列函数
4.1 slice、slice_head、slice_tail 函数

slice 的中文含义是切片,所以该函数的功能可以理解为从数据框中选择部分数据,使用起来比较简单。

# 第10行
gapminder %>% slice(10)

# 第1000行到最后一行
gapminder %>% slice(1000:n())

# 前5行
gapminder %>% slice_head(n = 5)

# 后5行
gapminder %>% slice_tail(n = 5)
4.2 slice_max、slice_min 函数

分组查询每组的前n个值,是我们统计排行榜数据时经常需要用到的,比如电商中每个品类销量前10的商品。

早期版本的 dplyr 包,是用 top_n 函数来统计最大或最小的前 n 个值,其中 n 为正数表示最大的 n 个值,n 为负数表示最小的 n 个值。

# pop 字段最大的3个
gapminder %>% top_n(pop, n = 3)

# 按 continent 分组,查询每组 pop 字段最大的3个
gapminder %>%
    group_by(continent) %>%
    top_n(pop, n = 3)

# pop 字段最小的3个
gapminder %>% top_n(pop, n = -3)

最新版本的 dplyr 包,则使用 slice_max、slice_min 来统计最大或最小的前 n 个值,top_n 在之后的版本中会慢慢废弃,所以还是建议大家使用 slice_max 和 slice_min 函数。

和 top_n 函数相比,slice_max、slice_min 默认会排序,其他的则没有区别。

# pop 字段最大的3个, 从大到小排序
gapminder %>% slice_max(pop, n = 3)

# 按 continent 分组,查询每组 pop 字段最大的3个
gapminder %>%
    group_by(continent) %>%
    slice_max(pop, n = 3)

# pop 字段最小的3个, 从小到大排序
gapminder %>% slice_min(pop, n = 3)

top_n 取 pop 字段最大的前 3 个:
在这里插入图片描述
slice_max 取 pop 字段最大的前 3 个,会默认按 pop 值排序:
在这里插入图片描述

当然,上述功能,我们也可以结合已经学习过的 mutate、row_number 等函数来实现。

# 分组查询每个continent的前3
gapminder %>%
    group_by(continent) %>%
    slice_max(pop, n = 3) %>%
    arrange(continent, desc(pop))

# 分组查询每个continent的前3, 使用排序函数 row_number 实现
gapminder %>%
    group_by(continent) %>%
    mutate(rank_order = row_number(desc(pop))) %>%
    filter(rank_order <= 3) %>%
    select(-rank_order) %>%
    arrange(continent, desc(pop))
4.3 slice_sample:抽样函数

早期版本的 dplyr 包,是用 sample_n、 sample_frac 函数来随机抽样的。

# 按个数抽样, 抽 10 个
gapminder %>% sample_n(10)

# 按比例抽样, 抽总体的 10%
gapminder %>% sample_frac(0.1)

最新版本的 dplyr 包,建议大家使用 slice_sample 来进行抽样,而 sample_n、sample_frac 在之后的版本中会慢慢废弃。

# 按个数抽样
gapminder %>% slice_sample(n = 10)

# 按年份分组抽样, 每年随机抽2个样本
gapminder %>% 
    group_by(year) %>%
    slice_sample(n = 2)

# 按比例抽样
gapminder %>% slice_sample(prop = 0.1)
5. lead、lag:偏移函数
# 向前偏移
student_df %>% 
    mutate(lead_pop = lead(score))

# 向前偏移2个步长
student_df %>% 
    mutate(lead_pop = lead(score, n = 2))

# 向后偏移
student_df %>% 
    mutate(lead_pop = lag(score))

向前偏移 1 位,则最后一行 lead_pop 的值为 NA:在这里插入图片描述
向后偏移1位,则第一行 lead_pop 的值为 NA:
在这里插入图片描述

下一节,我们会介绍 dplyr 中不同数据框的连接操作,类似于 SQL 中的 join。

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数分进阶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值