《数据分析实战》–用R做交叉列表
本文参考的是《数据分析实战》第四章。
背景:针对某公司的产品,发现当月的用户使用量减少了很多,但是和上月相比,本月的商业宣传和月度活动并无大的变化,需查明用户数量减少的原因。
现状:同上月相比用户数减少。
预期:恢复到与上月相同的用户数。
明确问题:根据用户的不同属性来发现某个用户群出现问题。
读取数据
dau <- read.csv('section4-dau.csv',header = T,stringsAsFactors = F)
user_info <- read.csv('section4-user_info.csv',header = T,stringsAsFactors = F)
其中,dau数据如下:
> head(dau)
log_date app_name user_id
1 2013-08-01 game-01 33754
2 2013-08-01 game-01 28598
3 2013-08-01 game-01 30306
4 2013-08-01 game-01 117
5 2013-08-01 game-01 6605
6 2013-08-01 game-01 346
user_info数据如下:
> head(user_info)
install_date app_name user_id gender generation device_type
1 2013-04-15 game-01 1 M 40 iOS
2 2013-04-15 game-01 2 M 10 Android
3 2013-04-15 game-01 3 F 40 iOS
4 2013-04-15 game-01 4 M 10 Android
5 2013-04-15 game-01 5 M 40 iOS
6 2013-04-15 game-01 6 M 40 iOS
处理数据
将两张表合并在一起,用系统自带的merge函数,合并之后数据如下:
> dau_user_info <- merge(dau,user_info,by=c('user_id','app_name'),all.x = T)
> head(dau_user_info)
user_id app_name log_date install_date gender generation device_type
1 1 game-01 2013-09-06 2013-04-15 M 40 iOS
2 1 game-01 2013-09-05 2013-04-15 M 40 iOS
3 1 game-01 2013-09-28 2013-04-15 M 40 iOS
4 1 game-01 2013-09-12 2013-04-15 M 40 iOS
5 1 game-01 2013-09-11 2013-04-15 M 40 iOS
6 1 game-01 2013-09-08 2013-04-15 M 40 iOS
同时增加月份的统计列:
> dau_user_info$log_month <- substr(dau_user_info$log_date,1,7)
> head(dau_user_info)
user_id app_name log_date install_date gender generation device_type log_month
1 1 game-01 2013-09-06 2013-04-15 M 40 iOS 2013-09
2 1 game-01 2013-09-05 2013-04-15 M 40 iOS 2013-09
3 1 game-01 2013-09-28 2013-04-15 M 40 iOS 2013-09
4 1 game-01 2013-09-12 2013-04-15 M 40 iOS 2013-09
5 1 game-01 2013-09-11 2013-04-15 M 40 iOS 2013-09
6 1 game-01 2013-09-08 2013-04-15 M 40 iOS 2013-09
数据分析
对上面的dau_user_info表进行统计:
1.首先我们考虑的性别方面有没有较大的变化,用系统自带的table函数进行统计:
使用方法:
输入table(AAA[,c(“XX”,”YY”)]),将AAA 数据的属性XX 和YY进行交叉列表统计并输出。
交叉列表统计就是计算各个属性下有多少样本数,是数据分析中最初级的一种分析。
> table(dau_user_info[,c("log_month","gender")])
gender
log_month F M
2013-08 47343 46842
2013-09 38027 38148
可以看出,通过比较2013 年8月和9 月男女用户的数量,可以看出两个用户群的数量都下降了,但各自的构成比例却大体上没有发生变化,所以性别这个属性对现在的问题影响不大。
2.考虑是不是年龄段会有较大的变化:
> table(dau_user_info[,c("log_month","generation")])
generation
log_month 10 20 30 40 50
2013-08 18785 33671 28072 8828 4829
2013-09 15391 27229 22226 7494 3835
这里也是比较上下两行的数值,可以看出在8 月和9 月,无论哪个年龄段的用户,所占总用户的比例大体上都没有变化,没有发现哪个年龄段的用户数大量减少了。
3.对用户分群(按性别× 年龄段统计)
对数据进行n重交叉列表统计,需要使用reshape2的包,使用该包里面的dcast函数:
使用方法:
输入dcast(AAA,XX~YY+ZZ,value.var=”CCC”,length),对数据AAA 中的XX(纵轴)和YY×ZZ(横轴)进行交叉列表统计。后面的value.var=”CCC”,length 表示这个交叉列表中的数值为相应的CCC的个数。(不去重)
> library(reshape2)
> dcast(dau_user_info,log_month~gender+generation,value.var = 'user_id',length)
log_month F_10 F_20 F_30 F_40 F_50 M_10 M_20 M_30 M_40 M_50
1 2013-08 9091 17181 14217 4597 2257 9694 16490 13855 4231 2572
2 2013-09 7316 13616 11458 3856 1781 8075 13613 10768 3638 2054
通过观察上述结果可以看到,上面的分析是以性别和年龄段的交叉属性作为分析轴的。通过“gender + generation”这样的方式来指定性别和年龄段的结合,将这两种属性通过“_”连接起来,并生成了分析轴。
通过观察统计的数据,可以看出这里每个用户群的用户数量都减少了,所占的比例也大体没有变,并没有发现哪个用户群的人数大量减少了。
4.通过移动设备来统计用户群体:
> table(dau_user_info[,c("log_month","device_type")])
device_type
log_month Android iOS
2013-08 46974 47211
2013-09 29647 46528
结果我们发现,9 月的iOS 用户数相比8 月下降幅度很小,然而Android 用户数却极大地减少了,因此问题很可能就出自这个用户群了。
数据可视化
按照日期和设备类型计算用户数,同时变化日期类型,因为要画时间序列的图:
> dau_user_info_device_summary <- ddply(dau_user_info,
+ .(log_date,device_type),
+ summarise,
+ dau=length(user_id))
> dau_user_info_device_summary$log_date <- as.Date(dau_user_info_device_summary$log_date)
> head(dau_user_info_device_summary)
log_date device_type dau
1 2013-08-01 Android 1784
2 2013-08-01 iOS 1805
3 2013-08-02 Android 1386
4 2013-08-02 iOS 1451
5 2013-08-03 Android 1295
6 2013-08-03 iOS 1351
画出时间序列的图:
> limits <- c(0,max(dau_user_info_device_summary$dau))
> ggplot(dau_user_info_device_summary,
+ aes(x=log_date,y=dau,col=device_type,lty=device_type,shape=device_type))+
+ geom_line(lwd=1)+
+ geom_point(size=4)+
+ scale_y_continuous(labels = comma,limits = limits)
这里注意,加号“+”要写在行后面,要不然会报错!!
结果图如下:
从上图可以看出,之前iOS 和Android 的用户数大体相当,但是从9 月的第2 周开始,Android 用户数急剧减少。
至此,数据分析结束~