教你几招R语言中的聚合操作

还没关注?

640?wx_fmt=png

快动动手指!

前言


在数据处理和分析过程中,可能会涉及到数据的聚合操作(可理解为统计汇总),如计算门店每天的营业总额、计算各地区的二手房的平均价格、统计每个消费者在近半年内最后一笔交易时间等。如果基于数据库SQL的语法来解决这些问题,将会显得非常简便,如果没有数据库环境该如何实现类似聚合问题的解决呢?

在R语言中提供了几种实现数据聚合的常用函数,它们分别是基于stats包中的aggregate函数基于sqldf包中的sqldf函数以及基于dplyr包中的group_by函数和summarize函数。下面通过具体的案例,依次介绍这三种常用方法的用法和差异。

基于aggregate函数的聚合


aggregate函数允许用户指定单个或多个离散型变量对数值型变量进行分组聚合,该函数有两种形式的语法,一种是直接基于数据的分组聚合,另一种则是基于公式的形式完成数据的分组聚合。这两种形式的用法和参数含义如下:

# 基于类似数据框x的数值聚合aggregate(x, by, FUN, ..., simplify = TRUE, drop = TRUE)# 基于公式formula的数值聚合aggregate(formula, data, FUN, ...,
          subset, na.action = na.omit)x:指定待分组聚合的数值型数据,可以是向量也可以是数据框;
by:指定分组变量,必须以列表的形式传递,如by = list(variable);
FUN:指定分组聚合的统计函数,可以是R自带的函数也可以是用户自定义函数;...:指定FUN函数的其他参数值;
simplify:bool类型的参数,是否将聚合结果以简洁的向量或矩阵形式输出,默认为TRUE;
drop:bool类型的参数,是否删除无用的组合值(即通过by参数完成的变量组合),默认为TRUE;
formula:以公式的形式实现数据的聚合统计,例如'variable1 + variable2 ~ variable3'表示数值型变量variable1和variable2按照分组变量variable3作聚合统计;
data:指定需要分组统计的数据框或列表;
subset:通过可选的向量指定data的数据子集用于分组聚合;
na.action:指定缺失值的处理办法,默认为删除缺失值;

为使读者进一步理解aggregate函数的以上两种用法,将以某商户的订单数据为例,统计每天的交易额,代码如下:

# 加载第三方包library(lubridate)
sales <- read.csv(file = file.choose())# 将字符型的订单日期Order_Date转换为日期型sales$Order_Date <- ymd(sales$Order_Date)# 统计历史数据中每天交易额stats1 <- aggregate(x = sales$Pay_Amt, # 指定被聚合的数值变量
                 by = list(sales$Order_Date), # 指定分组变量
                 FUN = mean # 指定聚合函数为平均值函数
                 )# 统计2018年每天的交易额stats2 <- aggregate(formula = Pay_Amt ~ Order_Date, 
                 data = sales,
                 FUN = mean,
                 subset = year(Order_Date) == 2018)# 数据预览View(stats1)
View(stats2)

640?wx_fmt=png

如上表所示,左图结果为aggregate函数的第一种用法,右图结果为第二种用法。尽管它们都完成了聚合统计,但是第二种形式的返回结果更加的人性化,因为第二种用法所返回的数据框变量名称为Order_Date和Pay_Amt。

通过上方的例子,并不是说aggregate函数的第二种用法就比第一种用法好,这要根据实际的数据形式而定,如果待聚合的数值变量和分组变量不在同一个数据源,则使用第一种用法会相对便捷一些,否则推荐使用第二种用法。

基于sqldf函数的聚合


尽管aggregate函数可以非常方便地实现数据的分组聚合,但是它存在两方面的缺点一个是无法直接对数据集中的单个数值型变量使用不同的聚合函数(除法FUN为自定义函数,包含多种聚合函数);另一个是无法对数据集中多个不同的数值型变量使用不同的聚合函数。

为了弥补aggregate函数的缺点,使用sqldf包中的sqldf函数是一个不错的选择,它可以允许用户写入SQL语法,并基于SQL实现数据的聚合统计,关于该函数的用法和参数含义如下:

sqldf(x, stringsAsFactors = FALSE,row.names = FALSE, 
      dbname, drv = getOption("sqldf.driver"), 
      user, password = "", host = "localhost", port,
      dll = getOption("sqldf.dll"), 
      connection = getOption("sqldf.connection"),
      verbose = isTRUE(getOption("sqldf.verbose")))
x:指定SQL语句,并且以字符串形式写入SQL语句;
stringsAsFactors:bool类型的参数,是否将字符型变量转换为因子型变量,默认为FALSE;
row.names:bool类型的参数,是否保留数据框中的行名称,默认为FALSE;
dbname:如果数据源来自于MySQL等数据库,该参数用于指定数据集所对应的数据库名称;
drv:指定具体的数据库驱动,如SQLite、MySQL以及PostgreSQL等;
user:指定访问数据库所需的用户名名称;
password:指定访问数据库所需的密码:
host:指定访问数据库所需的服务器名称;
port:指定访问数据库所需的端口号;

下面以上海二手房数据为例,分别统计浦东新区、黄浦区、徐汇区、长宁区和静安区中二手房的数量、最高总价、平均单价、最低面积。该数据集已存放在MySQL数据库中(读者也可以利用该函数读取本地的Excel文件),可以借助于下方的代码实现数据的读取和聚合统计:

# 加载第三方包library(sqldf)# 使用SQL语法对数据作聚合统计stats3 <- sqldf(x = "select region
                ,count(*) as Counts
                ,max(tot_amt) as Max_price
                ,avg(price_unit) as Avg_price
                ,min(size) as Min_size 
                from sec_buildings
                where region in ('浦东','黄浦','徐汇','长宁','静安') 
                group by region",  # 聚合统计的SQL语法
             drv = 'SQLite',  # 选择SQLite作为MySQL的驱动器
             dbname = 'train', # 指定表sec_buildings所在的数据库名称
             user = 'root', # 指定访问MySQL数据库的用户名
             password = '1q2w3e4r' # 指定访问MySQL数据库的密码
                )# 数据预览View(stats3)

640?wx_fmt=png

如上表所示,利用sqldf函数可以轻松得到不同变量的不同聚合结果,但前提是读者必须掌握数据库SQL的语法。尽管sqldf函数可以借助于SQL语法实现数据的聚合,但是使用该函数时容易产生异常错误,例如参数drv的值指定错误,就会导致sqldf函数无法生成结果(根据经验,参数drv的值设置为’SQLite’时,往往不会报错,不管原始数据来源于数据库MySQL还是来源于本地的Excel或csv文件)。

基于group_by和summarize函数的聚合


结合dplyr包中的group_by函数和summarize函数实现数据的分组聚合可以避开aggregate函数和sqldf函数的一些缺点,而且使用起来也非常的方便和快捷。其中group_by函数用于指定分组变量,summarize函数用于指定具体的聚合过程,关于这两个函数的用法及参数含义如下:

group_by(.data, ..., add = FALSE)
.data:指定需要聚合统计的数据框;...:指定数据库中的哪些变量需要用作分组变量;
add:bool类型的参数,是否在已分组的数据框上再添加group_by的分组设置,默认为FALSE;

summarise(.data, ...)
.data:指定已分组的数据框,即通过group_by函数处理的数据框;...:以“variable_name = aggregate_fun(variable)”的形式表达聚合过程,其中等号左边的变量表示聚合后的新变量名,等号右边是基于某个变量作聚合函数的运算;

下面以Titanic数据集为例,使用如上介绍的两个函数,统计每个船舱等级的乘客数量、乘客最小年龄、最大年龄以及平均票价,代码如下:

# 加载第三方包titanic <- read_excel(path = file.choose())# 指定分组变量grouped <- group_by(.data = titanic, # 指定待聚合统计的原始数据框
                  Pclass # 指定Pclass变量为分组变量
                  )# 聚合统计stats4 <- summarise(.data = grouped, # 指定以分组好的数据框grouped
                 Counts = n(), # 统计各舱的乘客人数
                 Min_age = min(Age, na.rm = TRUE), # 统计各舱乘客的最小年龄
                 Max_age = max(Age, na.rm = TRUE), # 统计各舱乘客的最大年龄
                 Avg_price = mean(Fare) # 统计各舱的平均价格
                    )# 数据预览View(stats4)

640?wx_fmt=png


数据源和代码的下载地址:

链接:https://pan.baidu.com/s/1O4EbHbZ_aelyp3Xz6rmAfQ 

提取码:9oeg 

结语


OK,关于数据的聚合操作就分享到这里,如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步

每天进步一点点:数据分析1480

640?wx_fmt=png

长按扫码关注我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sim1480

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

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

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

打赏作者

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

抵扣说明:

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

余额充值