4.3 基于dplyr包的数据描述性统计
我们将在本节学习6个dplyr核心函数,它们可以解决在数据处理中遇到的大部分问题。接下来我们将结合global-superstore数据集对这6个函数进行详细介绍。
4.3.1 使用filter()函数筛选行
filter() 函数可以基于观测的值筛选出一个观测子集,例如我们筛选出type(订单类型)为办公用品并且subtype(细分类型)为装订机的行。filter(orders,type == '办公用品'&subtype == '装订机')
## # A tibble: 6,152 x 24
## id orderid purchasedate shipdate shipway custid custname
## <dbl> <chr> <dttm> <dttm> <chr> <chr> <chr>
## 1 4 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 2 11 MX-201~ 2013-09-27 00:00:00 2013-10-01 00:00:00 标准级 DP-13~ 邹凤
## 3 24 US-201~ 2014-10-03 00:00:00 2014-10-08 00:00:00 标准级 DW-13~ 万刚
## 4 28 US-201~ 2013-05-24 00:00:00 2013-05-31 00:00:00 标准级 SC-20~ 张升
## 5 64 MX-201~ 2014-03-14 00:00:00 2014-03-17 00:00:00 一级 BT-11~ 宋忠
## 6 65 MX-201~ 2014-03-14 00:00:00 2014-03-17 00:00:00 一级 BT-11~ 宋忠
## 7 75 MX-201~ 2012-02-17 00:00:00 2012-02-22 00:00:00 标准级 FM-14~ 葛欢
## 8 91 MX-201~ 2012-12-28 00:00:00 2013-01-01 00:00:00 标准级 SC-20~ 楚宣
## 9 134 US-201~ 2014-09-29 00:00:00 2014-10-04 00:00:00 标准级 TT-21~ 庄伟
## 10 137 MX-201~ 2014-10-29 00:00:00 2014-11-03 00:00:00 标准级 FW-14~ 何惠
## # ... with 6,142 more rows, and 17 more variables: segment <chr>, city <chr>,
## # state <chr>, country <chr>, zipcode <lgl>, market <chr>, area <chr>,
## # productid <chr>, type <chr>, subtype <chr>, productname <chr>, sales <dbl>,
## # quantity <dbl>, discount <dbl>, profit <dbl>, shipcost <dbl>,
## # priority <chr>
filter()函数中,第一个参数是数据框名称,第二个参数以及随后的参数是用来筛选数据框的表达式。这行代码会返回一个新的数据框,如果你想保存结果,需要对这行代码赋值。R要么输出结果,要么将结果保存在一个变量中。如果想同时完成这两种操作,那么你可以用括号将赋值语句括起来:这行代码还使用了比较运算符和逻辑运算符。R提供了标准的比较运算符和逻辑运算符,如果有遗忘的读者,可以返回第三章进行查阅。
4.3.2 使用arrange()函数对观测值进行排序
arrange()函数的工作方式与filter()函数非常相似,但前者不是选择行,而是改变行的顺序。例如,我们按照sales(销售量)进行排序。为了数据更加的直观,我们首先将进行排序的部分列筛选出来:<- orders %>%
orders4 select(type:profit) %>%
arrange(sales)
orders4
## # A tibble: 51,290 x 7
## type subtype productname sales quantity discount profit
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 办公用品 电器 Hoover Replacement Belt for ~ 0.444 1 0.8 -1.11
## 2 办公用品 装订机 Acco Suede Grain Vinyl Round~ 0.556 1 0.8 -0.945
## 3 办公用品 装订机 Avery Durable Slant Ring Bin~ 0.836 1 0.8 -1.34
## 4 办公用品 装订机 Avery Round Ring Poly Binders 0.852 1 0.7 -0.596
## 5 办公用品 装订机 Acco 3-Hole Punch 0.876 1 0.8 -1.40
## 6 办公用品 装订机 Avery Non-Stick Binders 0.898 1 0.8 -1.57
## 7 办公用品 装订机 Avery Triangle Shaped Sheet ~ 0.984 2 0.8 -1.48
## 8 技术 配件 Maxell 4.7GB DVD-R 5/Pack 0.99 1 0 0.436
## 9 办公用品 装订机 Acco Economy Flexible Poly R~ 1.04 1 0.8 -1.83
## 10 办公用品 装订机 Wilson Jones Easy Flow II Sh~ 1.08 3 0.8 -1.73
## # ... with 51,280 more rows
arrange()接受一个数据框和一组作为排序依据的列名(或者更复杂的表达式)作为参数。如果列名不只一个,那么就使用后面的列在前面排序的基础上继续排序。另外,arrange()默认进行升序排列,使用desc()可以进行降序排列:<- orders %>%
orders4 select(type:profit) %>%
arrange(desc(profit))
orders4
## # A tibble: 51,290 x 7
## type subtype productname sales quantity discount profit
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 技术 复印机 Canon imageCLASS 2200 Advan~ 17500. 5 0 8400.
## 2 技术 复印机 Canon imageCLASS 2200 Advan~ 14000. 4 0 6720.
## 3 技术 复印机 Canon imageCLASS 2200 Advan~ 10500. 3 0 5040.
## 4 办公用品 装订机 GBC Ibimaster 500 Manual Pr~ 9893. 13 0 4946.
## 5 办公用品 装订机 Ibico EPK-21 Electric Bindi~ 9450. 5 0 4630.
## 6 办公用品 电器 Hoover Stove, Red 7959. 14 0 3979.
## 7 技术 复印机 Canon imageCLASS 2200 Advan~ 11200. 4 0.2 3920.
## 8 办公用品 装订机 Fellowes PB500 Electric Pun~ 6355. 5 0 3177.
## 9 技术 电话 Samsung Smart Phone, VoIP 6999. 11 0 2939.
## 10 技术 电话 Apple Smart Phone, with Cal~ 5752. 9 0 2818.
## # ... with 51,280 more rows
4.3.3 使用select()函数选择需要的列
在大数据时代,数据集有几百甚至几千个变量已经司空见惯。这种情况下,找出真正有用的变量经常是我们面临的第一个挑战。通过基于变量名的操作,select()函数快速生成你需要的变量子集。本数据集只有24个字段,使用select()的效果不是非常明显,但是可以通过本数据集了解select()的用法:<- orders %>%
orders4 filter(type == "办公用品" , subtype=="装订机") %>%
select(type,subtype)
orders4
## # A tibble: 6,152 x 2
## type subtype
## <chr> <chr>
## 1 办公用品 装订机
## 2 办公用品 装订机
## 3 办公用品 装订机
## 4 办公用品 装订机
## 5 办公用品 装订机
## 6 办公用品 装订机
## 7 办公用品 装订机
## 8 办公用品 装订机
## 9 办公用品 装订机
## 10 办公用品 装订机
## # ... with 6,142 more rows
select()函数上文中已经多次提及,相信读者对它的用法已经有了基本了解:它接受两个参数,第一个为数据框,第二个则为要筛选的变量,可以一次筛选多个变量,变量之间用逗号分隔,也可以使用type:profit这种形式,筛选type到profit之间的所有变量。或者可以使用-(type:profit)筛选除type到profit的所有变量:
select(orders,-(type:profit))
## # A tibble: 51,290 x 17
## id orderid purchasedate shipdate shipway custid custname
## <dbl> <chr> <dttm> <dttm> <chr> <chr> <chr>
## 1 1 MX-201~ 2014-10-02 00:00:00 2014-10-06 00:00:00 标准级 SC-20~ 常松
## 2 2 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 3 3 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 4 4 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 5 5 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 6 6 MX-201~ 2012-10-15 00:00:00 2012-10-20 00:00:00 标准级 KW-16~ 郝立勤
## 7 7 MX-201~ 2013-09-27 00:00:00 2013-10-01 00:00:00 标准级 DP-13~ 邹凤
## 8 8 MX-201~ 2013-09-27 00:00:00 2013-10-01 00:00:00 标准级 DP-13~ 邹凤
## 9 9 MX-201~ 2013-09-27 00:00:00 2013-10-01 00:00:00 标准级 DP-13~ 邹凤
## 10 10 MX-201~ 2013-09-27 00:00:00 2013-10-01 00:00:00 标准级 DP-13~ 邹凤
## # ... with 51,280 more rows, and 10 more variables: segment <chr>, city <chr>,
## # state <chr>, country <chr>, zipcode <lgl>, market <chr>, area <chr>,
## # productid <chr>, shipcost <dbl>, priority <chr>
同时,select()还可以配合一些辅助函数来使用。例如:和start_with(‘abc’)(end_with)配合,匹配以abc开头或者结尾的变量;和contains()配合筛选变量名包含某些字段的变量;使用matches()进行正则匹配;或者和everything()配合将变量移动到数据框的开头:
select(orders,type:profit,everything())
## # A tibble: 51,290 x 24
## type subtype productname sales quantity discount profit id orderid
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 办公用品 标签 Hon File Folde~ 13.1 3 0 4.56 1 MX-201~
## 2 家具 用具 Tenex Clock, D~ 252. 8 0 90.7 2 MX-201~
## 3 家具 书架 Ikea 3-Shelf C~ 193. 2 0 54.1 3 MX-201~
## 4 办公用品 装订机 Cardinal Binde~ 35.4 4 0 4.96 4 MX-201~
## 5 办公用品 美术 Sanford Canvas~ 71.6 2 0 11.4 5 MX-201~
## 6 办公用品 信封 GlobeWeis Mail~ 56.1 2 0 21.3 6 MX-201~
## 7 办公用品 信封 GlobeWeis Mail~ 56.1 2 0 21.3 7 MX-201~
## 8 技术 设备 Konica Card Pr~ 345. 3 0 165. 8 MX-201~
## 9 办公用品 用品 Elite Box Cutt~ 97.4 4 0 19.4 9 MX-201~
## 10 技术 配件 Enermax Router~ 342. 2 0 13.6 10 MX-201~
## # ... with 51,280 more rows, and 15 more variables: purchasedate <dttm>,
## # shipdate <dttm>, shipway <chr>, custid <chr>, custname <chr>,
## # segment <chr>, city <chr>, state <chr>, country <chr>, zipcode <lgl>,
## # market <chr>, area <chr>, productid <chr>, shipcost <dbl>, priority <chr>
4.3.4 使用mutate()新增变量
在数据分析中,分析两变量或者多变量之间的函数关系是我们经常要进行的操作。mutate()函数可以对现有列进行函数操作,并将结果保存为新的变量。例如,我们需要想要获得单位商品的价格,就需要sales列除以quanlity(商品数量)列:
<- orders %>%
orders5 mutate(unitprice=sales/quantity ) %>%
select(sales,quantity, unitprice)
<- orders %>%
orders5 mutate(unitprice=sales/quantity,
unitcost = unitprice-(profit/quantity)) %>%
select(sales,quantity, unitprice,unitcost)
orders5
## # A tibble: 51,290 x 4
## sales quantity unitprice unitcost
## <dbl> <dbl> <dbl> <dbl>
## 1 13.1 3 4.36 2.84
## 2 252. 8 31.5 20.2
## 3 193. 2 96.6 69.6
## 4 35.4 4 8.86 7.62
## 5 71.6 2 35.8 30.1
## 6 56.1 2 28.1 17.4
## 7 56.1 2 28.1 17.4
## 8 345. 3 115. 59.7
## 9 97.4 4 24.3 19.5
## 10 342. 2 171. 164.
## # ... with 51,280 more rows
我们在上述代码块中选择了进行操作的变量和新增变量,如果我们只需要保存新增变量,可以使用transmute()函数:transmute(orders,unitprice=sales/quantity,
unitcost = unitprice-(profit/quantity))
## # A tibble: 51,290 x 2
## unitprice unitcost
## <dbl> <dbl>
## 1 4.36 2.84
## 2 31.5 20.2
## 3 96.6 69.6
## 4 8.86 7.62
## 5 35.8 30.1
## 6 28.1 17.4
## 7 28.1 17.4
## 8 115. 59.7
## 9 24.3 19.5
## 10 171. 164.
## # ... with 51,280 more rows
4.3.5 使用group_by()对数据进行分组
R语言的group_by()函数按照某个变量分组,数据集本身并不会发生什么变化,只有在与dplyr包中的其它函数结合使用时才会体现出它的作用。例如,我们将数据中的订单按区域进行分组并且使用tally()函数统计订单数量:
<- orders %>%
orders5 group_by(area) %>%
tally()
group_by()的基本用法很简单:第一个参数为数据框,第二个参数为进行分组的变量。通过上面几行代码,我们就可以得到不同区域的订单数量。不过,通过与其它函数的配合,才能真正体现group_by()的强大。
4.3.6 使用summarize()汇总数据
summarize()函数可以将数据框折叠成一行。summarise(orders,avg_sales=mean(sales))
## # A tibble: 1 x 1
## avg_sales
## <dbl>
## 1 246.
summarize()函数通常与group_by()函数一起使用。group_by()函数可以将整个数据集划分为不同的组,接下来,在分组后的数据框上使用dplyr函数时,它们会自动的每个组进行操作。summarize()返回值一般为新的一个数据框,且该数据框一般情况下和原始的数据框长度一定不相同,列数应该是group_by参数+summarize参数,例如:
<- orders %>%
orders5 group_by(type) %>%
summarise(avg_sales=mean(sales)) %>%
head()
orders5
## # A tibble: 3 x 2
## type avg_sales
## <chr> <dbl>
## 1 办公用品 121.
## 2 技术 468.
## 3 家具 416.