先对分析进行简单构思:
1、搜集并格式化数据
a、搜集QQ群记录-从QQ导出txt文档,筛选出需要统计的QQ群记录信息。
b、导入QQ群记录信息,根据\n换行符读取每一行的信息。
c、逐行读取,利用正则表达式判断该行是否是时间行,是的话进行切割,分割出时间和昵称,该行的下一行则为聊天信息。
d、把时间、昵称、聊天信息统一放到一个数据框中。
#导入QQ群记录 #stringsAsFactors=F 不转换为因子 #encoding="UTF-8" 读取编码为UTF-8 #sep="\n"换行读取 jilu<- read.table("QQ群记录.txt",stringsAsFactors=F,encoding="UTF-8",sep="\n",quote = NULL) #定义data数据框,后面读取jilu中的数据需要添加在里面 #定义几个临时变量,dateTime,name,des data<-data.frame(dateTime=c(),user_name=c(),user_des=c(),stringsAsFactors = F) dateTime <- character() name <-character() des<-character() #获取jilu的行数,[1]代表行,[2]代表列 rCount<-dim(jilu)[1] count <- 1 for(i in 1:rCount){ #利用正则表达式,判断是否是时间行 #下面表达式代表2017-06-29 13:42:35格式 #[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]+:[0-9]+:[0-9]+ #当该行满足表达式的时候,reg为满足的时间第一个字符所在的位置,不满足否则为-1 reg <- regexpr("[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]+:[0-9]+:[0-9]+",jilu[i,]) #因为聊天记录特殊性,只有满足表达式并且第一个字符就是时间的行才为真实的时间行 if(reg==1){ #计算昵称开始的位置=时间起始位置+时间长度+1 #"match.length"在执行dt_pattern会自动显示这个为满足条件时间的长度 #接上面,如果单独attr()使用的话,则是attr(已执行的正则,"match.length")获取在该正则中满足条件的字符长度 user_begin=reg+attr(reg,"match.length")+1 #计算昵称结束位置=该条记录长度,因为昵称都是写在最后的,nchar()计算字符串的长度 user_end=nchar(jilu[i,]) #获取昵称,substring(被截取的字符串,截取起点,截取终点) name <- substring(jilu[i,],user_begin,user_end) #获取时间,具体规则如上面 dt_begin <- reg dt_end <- reg+attr(reg,"match.length")-1 dateTime <-substring(jilu[i,],dt_begin,dt_end) #获取聊天信息 des <- jilu[i+1,] #把昵称、时间、聊天信息加入data中 #行合并,一行一行自动添加入data,列合并为:cbind data <- rbind(data,data.frame(dateTime,name,des)) } }
最终data数据如下: