1、获取数据
从 QQ 消息管理器中导出消息记录,保存的文本类型选择 txt 文件。这里获取的是某群从 2016-04-18 到?2016-05-07 期间的聊天记录,记录样本如下所示。

2、数据预处理
打开 R 软件,先通过 File—>Change dir 切换到聊天文件所在目录。
引入包:
library(stringr)
library(plyr)
library(lubridate)
library(ggplot2)
library(reshape2)
library(igraph)
没有的包要通过命令?install.packages(”扩展包名”) ?安装。
读取聊天记录文件到内存:
qqsrcdata<-readLines("QQGroup.txt",encoding="UTF-8")
这里我们不关心聊天内容,只看时间和发言人,所以,我们把类似 “2016-04-18 20:04:20 我来弄死谁(66554432)” 这样的内容提取出来。这里要用到正则表达式,对 R 语言的 grep、sub、gregexpr 等字符串处理函数不熟的,网上搜一下,资料多的是。
srcdata<-qqsrcdata[grep("^d{4}-d{2}-d{2} d+:d{2}:d{2} .+$",qqsrcdata)]
看看 srcdata 内容,就已经全是发言时间和发言人信息了,没有其它闲杂数据。
然后再从 srcdata 中提取发言时间和发言人信息,分别存到列表 data 的 time 和 id 中。对发言人信息的提取很简单:
data={} ?# 创建一个空的 listdata$id<-sub("d{4}-d{2}-d{2} d+:d{2}:d{2} ","",srcdata)
对发言时间的提取要稍麻烦些,因为时间字符串的长度不一样,有些是 18 位,如 “2016-04-18 7:36:32”,有些是 19 位,如 “2016-04-18 19:24:01”,所以,在提取时间时,需先用?gregexpr 确定时间字符串的起始和结束位置,然后再用 substring 提取出相应的时间,注意 substring 和 sub 是不同的函数。
getcontent <- function(s,g){
?substring(s,g,g+attr(g,'match.length')-1) ?# 读取 s 中的数据
gg<-gregexpr("d{4}-d{2}-d{2} d+:d{2}:d{2}",srcdata,perl=TRUE)for(j in 1:length(gg))
{
data$time[j]<-getcontent(srcdata[j],gg[[j]])
}
现在时间和发言人信息都读到 data 的 time 和 id 中了,可以确认下提取内容:data、dataid、datatime。
还没完,时间还是字符串,还需要继续处理:
# 数据整理# 将字符串中的日期和时间划分为不同变量
''
result1 <- ldply(temp1,.fun=NULL)
names(result1) <- c('date','clock')#分离年月日
'-'
result2 <- ldply(temp2,.fun=NULL)
names(result2) <- c('year','month','day')# 分离小时分钟':'
result3 <- ldply(temp3,.fun=NULL)
names(result3) <- c('hour','minutes','second')# 合并数据
cbind(data,result1,result2,result3)
# 转换日期为时间格式
ymd(newdata$date)
# 提取星期数据
wday(newdata$date)# 转换数据格式
newdata$year <- ordered(newdata$year)
newdata$day <- ordered(as.numeric(newdata$day))
newdata$hour <- ordered(as.numeric(newdata$hour))
newdata$wday <- ordered(newdata$wday)
至此,数据预处理完成,时间和发言人数据都已合适地存到 newdata 中,可以开始任性地分析了~
3、数据分析
qplot(wday,data=newdata,geom='bar')
周三是工作日,还这么活跃,周六话最多,周日估计出去玩了,周一专心上班。
qplot(hour,geom='bar')
这群一天中聊得最嗨的是上午 10 点和下午 17 点,形成两个高峰。
user <- as.data.frame(table(newdata$id)) ?# 用 table 统计频数
user <- user[order(user$Freq,decreasing=T),]
user[1:10,] ? # 显示前十大发言人的 ID 和 发言次数
topuser <- user[1:10,]$Var1 # 存前十大发言人的 ID
# 活跃天数计算# 将数据展开为宽表,每一行为用户,每一列为日期,对应数值为发言次数
'date'
flat.mat <- as.matrix(flat.day[-1]) #转为矩阵# 转为0-1值,以观察是否活跃
,0)# 根据上线天数求和
names(topday) <- c('id','days')
topday <- topday[order(topday$days,decreasing=T),]# 获得前十大活跃用户
# 观察每天的发言次数# online.day为每天的发言次数# -1 表示去除第一列,第一列是 ID
qplot(x=time,y=online.day,ymin=0,ymax=online.day,data=tempdf,geom='linerange')# 观察到有少数峰值日,看超过200次发言以上是哪几天
#根据flat.day数据观察每天活跃用户变化# numday为每天发言人数
tempdf <- data.frame(time=ymd(names(numday)),numday)
qplot(x=time,y=numday,ymax=numday,geom='linerange')
# 再观察十强选手的日内情况
flat.hour <- dcast(newdata,id~hour,value.var='hour',subset=.(id %in% topuser))# 平行坐标图
hour.melt <- melt(flat.hour)
p <- ggplot(data=hour.melt,aes(x=variable,y=value))
p + geom_line(aes(group=id,color=id))+theme_bw()+theme(legend.position = "none")
# 连续对话的次数,以三十分钟为间隔
newdata$realtime <- strptime(newdata$time,'%Y-%m-%d %H:%M')# 时间排序有问题,按时间重排数据
newdata2 <- newdata[order(newdata$realtime),]# 将数据按讨论来分组
group <- rep(1,dim(newdata2)[1])for (i in 2:dim(newdata2)[1]) {
?
?d <- as.numeric(difftime(newdata2$realtime[i],
? ? ? ? ? ? ? ? ? ? ? ? ? ? newdata2$realtime[i-1],
? ? ? ? ? ? ? ? ? ? ? ? ? ? units='mins')) ? ?
if ( d < 30) {
? ? ? ?group[i] <- group[i-1]
? ?}
? ?else {group[i] <- group[i-1]+1}
}
barplot(table(group))
# 得到 93 多组对话 group# igraph进行十强之间的网络分析# 建立关系矩阵,如果两个用户同时在一次群讨论中出现,则计数+1'group'in#
rownames(newdata4) <- newdata3[,1]
relmatrix <- newdata4 %*% t(newdata4)# 很容易看出哪两个人聊得最多
which(deldiag==max(deldiag),arr.ind=T)# 根据关系矩阵画社交网络画
'undirected'
g <-simplify(g)
V(g)$label<-rownames(relmatrix)
V(g)$degree<- degree(g)
layout1 <- layout.fruchterman.reingold(g)#egam <- 10*E(g)$weight/max(E(g)$weight))#V(g)$label.cex <- V(g)$degree / max(V(g)$degree)+ .2
V(g)$frame.color <- NA
E(g)$width <- egam
E(g)$color <- rgb(0,0,1,egam)
plot(g,layout=layout1)
#找到配对pairlist=data.frame(pair=1:length(attributes(deldiag)$dimnames[[1]]))
rownames(pairlist)<-attributes(deldiag)$dimnames[[1]]for(i in(1:length(deldiag[1,])))
{
pairlist[i,1]<-attributes(which(deldiag[i,]==max(deldiag[i,]),arr.ind=T))$names[1]
}
pairlist
pairmatrix=data.frame(pairA=1:length(attributes(deldiag)$dimnames[[1]]),pairB=1:length(attributes(deldiag)$dimnames[[1]]))
pairmatrix=data.frame(pair=1:length(attributes(deldiag)$dimnames[[1]]))for(i in (1:dim(deldiag)[1]))
{
deldiag[i,] <- ifelse(deldiag[i,] == max(deldiag[i,0)
}
deldiag
回复 R??????????? ??R语言快速入门免费视频?回复 统计??????? ??统计方法及其在R中的实现回复 用户画像 ??民生银行客户画像搭建与应用?回复 大数据??? ??大数据系列免费视频教程回复 可视化? ? ??利用R语言做数据可视化回复 数据挖掘 ? 数据挖掘算法原理解释与应用回复 机器学习 ??R&Python机器学习入门?