【技巧】如何快速按照日期分组

时间:2022-07-28
本文章向大家介绍【技巧】如何快速按照日期分组,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题的提出

在处理数据的时候,我们常常需要按照日期对数据进行分类汇总,例如每周、每月、每年汇总等。常见的做法是建立一个用于分类的变量,然后再按照这个变量进行汇总。然而这种做法特别麻烦,因为我们常常要尝试多种不同的分类长度,很难事先就一次性创建好用于分类的变量。

再次,这种常规方法很难处理一些不规则的日期间隔,例如我希望每隔3天对数据汇总一次;或者再变态一点,我希望把数据分成两组:一组是周三,另一组是非周三。遇到这种情况,我们该怎么办呢?

本期大猫将教大家使用 data.table包的 keyby语句完成上述任务。使用 data.table的好处是:

  • 不需要事先创建分类变量,啥时想分类了,直接分就可以(group on the fly)
  • 速度特别、特别快!
  • 代码非常、非常简洁!(也就十几个字符!)

注:文章中所有代码块都可以水平滚动!不信滑滑看?

实战操作

生成样例数据集

首先我们生成一个样例数据集:

# 生成 100 个日期,从2018-01-01开始
set.seed(42)
n <- 100
dt <- data.table(date = seq(ymd("2018-01-01"), length.out = n, by = "day"), x = runif(n))

生成的数据集长这个样子:

按照周进行分类

如果我们想要每周对变量 x求均值,只要在 keyby语句中指定 week=week(date)即可:

# 按照周进行分组
dt[, .(x = mean(x)), keyby = .(week = week(date))]

结果如下图:

按照星期进行分类

如果想要按照星期(周一到周日)分类,只要把 week函数改成 wday即可:

# 按照星期进行分组
res <- dt[, .(x = mean(x)), keyby = .(weekday = wday(date))]

结果如下图:

按照“是否为周三”进行分类

如果我们想把样本分成两组,一组是周三(True),一组是非周三(False),则只要使用 wday(date)==3来生成一列值为 True或者 False的向量就行。

# 按照是否为“周三”进行分组:“True”即周三,“False”即除周三以外的任何日期
dt[, .(x = mean(x)), keyby = .(is.wed = wday(date) == 3)]

结果如下:

按照“每个三天”分类

为了按照任意间隔进行分类,我们需要用到 data.table包中的 ceiling_date函数。在下面的代码中, ceiling_date(date,"3 days")含义是每三天对 date进行一次“四舍五入”。

# 按照“每3天”进行分组
dt[, .(x = mean(x)), keyby = .(three.day = ceiling_date(date, "3 days"))]

大家注意观察最后的结果,是不是每个三天才产生一个输出?

(完)

长按二维码关注