【R语言】实现数据透视--基于sqldf包、dplyr包、reshape2包

0. 前言

       日常数据分析中,常常会使用Excel中的数据透视表功能解决一些汇总、求和、平均的任务;然而,当数据量比较大,无法将数据导入Excel处理,即使可以导入,Excel处理速度比较慢,有时候会出现卡死现象。既然我们使用R语言软件做数据分析,何必将数据导出用Excel分析,然后再导入R中呢?这里我们介绍一些R语言中类似于Excel中数据透视功能的函数。

1. 数据准备

       这里我们虚构一些数据:某电商有两家分店,当客户下单的时候,由于一些原因,导致客户交易失败,每个月总部会汇总每个分店交易失败的数据,数据如下:

##交易失败月份
TransFailTime <- rep(c("2018-01", "2018-02", "2018-03"), each = 16)
##分店
Branch <- rep(c("branch_1", "branch_2"), times = 24)
##交易失败原因
TransFailCode <- rep(c("Failed_code01","Failed_code02","Failed_code04",
                        "Failed_code05","Failed_code06",
                        "Failed_code07","Failed_code08",
                        "Failed_code09"), each = 2, times = 3)
##交易失败客户
set.seed(123)
TransFailCust <- sample(500:1000, 48, replace = T)

data <- data.frame(TransFailTime, Branch, TransFailCode, TransFailCust)

2. 案例分析 

       这里使用R语言中的sqldf、reshape2、以及dplyr尝试着一些案例分析,直接上代码,简单明了。

 

2.1 统计每月交易失败的人数

##dplyr包
data %>% 
  dplyr::group_by(TransFailTime) %>%
  dplyr::summarise(cnt_cust = sum(TransFailCust))

##sqldf包
library(sqldf)
sqldf::sqldf("select TransFailTime, sum(TransFailCust) cnt_cust from 
    data group by TransFailTime")

##reshape2包
reshape2::acast(data, TransFailTime ~ ., sum) ##没有行标签
reshape2::dcast(data, TransFailTime ~ ., sum) ##有行标签

       注意:不同的分析可以选择不同的聚合函数,只需替换上述3个包中的函数:例如:需要每个月分店的平均交易失败人数,dplyr和reshape2包中将sum换成mean函数,sqldf中将sum换成avg。

 

2.2 每月每个分店交易失败的人数

##dplyr包
data %>% 
  dplyr::group_by(TransFailTime, Branch) %>%
  dplyr::summarise(cnt_cust = sum(TransFailCust))

##sqldf包
sqldf("select TransFailTime, branch, sum(TransFailCust) cnt_cust from 
    data  group by TransFailTime, branch")

##reshape2包
acast(data, TransFailTime ~ Branch, sum) ##不带行标签
dcast(data, TransFailTime ~ Branch, sum) #带行标签

 注意:

       使用reshape2包中可以实现行汇总和列汇总,只需在函数中加入margins = "TransFailTime"或者margins = "Branch"或者margins = TRUE。

 

2.3 筛选:每月交易失败码是Failed_code01、Failed_code02、Failed_code03人数

     公司比较关注由于个别交易失败码导致的交易失败的人数,例如Failed_code01、Failed_code02、Failed_code03:

##dplyr包
data %>% 
  dplyr::filter(TransFailCode == "Failed_code01" | TransFailCode == "Failed_code02" | 
                  TransFailCode == "Failed_code03") %>%
  dplyr::group_by(TransFailTime, TransFailCode) %>%
  dplyr::summarise(cnt_cust = sum(TransFailCust))

##sqldf包
sqldf::sqldf("select TransFailTime, TransFailCode, sum(TransFailCust) cnt_cust from 
    data where TransFailCode in ('Failed_code01','Failed_code02','Failed_code03') 
             group by TransFailTime,TransFailCode")

##reshape2包
reshape2::acast(data, TransFailTime ~ TransFailCode, sum, 
                subset = .(TransFailCode == "Failed_code01" | TransFailCode == "Failed_code02" | TransFailCode == "Failed_code03"))

reshape2::dcast(data, TransFailTime ~ TransFailCode, sum, 
                subset = .(TransFailCode == "Failed_code01" | TransFailCode == "Failed_code02" | TransFailCode == "Failed_code03"))

3. 总结

      不同的人群可以使用不同的实现方式,比较熟悉SQL的可以使用sqldf包,喜欢呈现方式与Excel中一致的可以使用reshape2包中的函数,人生苦短,开心就好,燥起来!! 

 


 

 


更多精彩内容