2018最高检工作报告词云记

JWen

指导老师:程振兴

“词云”这个概念由美国西北大学新闻学副教授、新媒体专业主任里奇·戈登(Rich Gordon)于提出,词云是一种可视化描绘单词或词语出现在文本数据中频率的方式,它主要是由随机分布在词云图的单词或词语构成,出现频率较高的单词或词语则会以较大的形式呈现出来,而频率越低的单词或词语则会以较小的形式呈现。词云主要提供了一种观察社交媒体网站上的热门话题或搜索关键字的一种方式,它可以对网络文本中出现频率较高的“关键词”予以视觉上的突出,形成“关键词云层”或“关键词渲染”,从而过滤掉大量的文本信息,使浏览网页者只要一眼扫过文本就可以领略文本的主旨。。
来自王亨的公众号推文

分词

首先我们可以从中华人民共和国最高人民检察院网站找到2018最高检工作报告全文(文字实录),复制粘贴到sublime中,将所有的逗号、句号、顿号都替换成换行,并保存为2018最高检工作报告词云.txt文件。这里“将所有的逗号、句号、顿号都替换成换行”是为了在Stata处理中不至于把所有字符串都塞进一个格子中,因为Stata的一个格子能装进的字符串有限,为避免装不下,将上述符号替换成换行。

分词并统计词频:

  1. 设定工作目录,读入txt文件,并删去空值

    1
    2
    3
    cd "../最高检工作报告词云"
    infix str v 1-200 using 2018最高检工作报告.txt, clear
    drop if v == ""

    可以看到这里一共有1055个观测值

  2. 针对变量v的每一个行,创建一个变量用来装每一行,可以看到运行之后创建了1055个变量(v1到v1055),ustrwordcount可能指unicode string wordcount,引用变量要加=。针对每个变量的第一个观测每个分词结果直接用”\n\t”分隔

    注意这里第三行如果是`=v[1]’的话,当第一个变量只有一个分词结果的时候,会造成后面所有变量的分词结果都只装一个!!!当然这里可以设定具体的数,但是什么时候装的完,什么时候装不完是不能确定的。

    1
    2
    3
    4
    5
    6
     forvalues i = 1/`=_N'{
    gen v`i' = ""
    forvalues j = 1/`=ustrwordcount("`=v[`i']'", "cn")' {
    replace v`i' = v`i' + ustrword("`=v[`i']'", `j', "cn") + "\n\t" in 1
    }
    }
  3. 保留第一行观测,然后将所有的变量重命名之后删除第一个变量,然后转置(此时变量名为_var1),最后讲变量_var1的每个观测按照\n\t分隔之后放在每个观测的后面。

    1
    2
    3
    4
    5
    6
    7
    8
    keep in 1
    foreach i of varlist _all{
    ren `i' temp`i'
    }
    drop tempv
    sxpose, clear
    split _var1, parse(\n\t)
    drop _var1
  4. 可以看到一共有36个变量,一共有1055个观测值,这里对于每个变量,依次装进1.dta,2.dta,···等文件(总共36个.dta文件)。如果一个循环运行preserve之后再次运行preserve会出现错误,所以在前面加上命令cap restore。将所有的.dta文件里的变量都命名为v,是为了在后面使用append纵向合并的时候可以合并在一起,否则,会依次在变量的末尾接上,合并之后整体呈现出数据在对角线上一样,贼难处理。(横向合并使用merge命令)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    local m = 1
    foreach i of varlist _all{
    cap restore
    preserve
    keep `i'
    ren `i' v
    save `m', replace
    local m = `m' + 1
    restore
    }
  5. 使用第一个.dta文件1.dta,并依次在其后使用append命令纵向合并,总文件为36个,所以直接2/36就可以了,40这个地方可以在上面提取出变量数设定一个local,然后引用宏变量。循环中用过的.dta文件依次删掉,最后删掉文件1.dta。

    1
    2
    3
    4
    5
    6
    use 1, clear
    forvalues i = 2/40{
    cap append using `i'
    cap erase `i'.dta
    }
    erase 1.dta
  6. 变量v仅保留中文字符,并对v下每个类进行计数。并使命令duplicates报告、标记或删除重复的观察。最后保存结果为“分词结果.dta”

    1
    2
    drop if ustrregexm(v, "[\u4e00-\u9fa5]+") == 0
    bysort v: egen num = count(v)

绘制词云

Echart模板可参考这里,里面贼多词云,当然你可以自己在里面寻找更完全的设定,并加在其中。

这个代码最漂亮的地方,除了fw命令之外(fw命令可以参考fw——Stata+ECharts的绘图规范),就是将可以设定的参数写成

1
fw `"var ···;"'

的形式,这样贼大的增加了代码的可读性,而且方便了作图时参数的修改。

总的过程如下:

  1. 设定工作目录,工作目录和上面分词时的工作目录一致,jscopy命令将js库从系统文件夹拷贝到当前的文件夹。作者是在苹果上写的,Windows操作系统下运行之后不知为啥会出现__MACOSX文件夹,不过这个文件不影响画图。

    1
    2
    cd "D:\Desktop\dwla project\czxa project\最高检工作报告词云"
    jscopy
  2. fw, s h()命令准备写文件,h()的参数为写出的html文件的文件名。lib, b s() o()命令用于调用js文件,基础js文件每次都调用,主题js文件这里使用dark主题,其他js文件这里使用了echarts-wordcloud.min的js文件。调用分词结果.dta文件,计算变量v每个观测的长度,发现一个中文的长度是3,于是使用命令drop if len == 3将一个中文的观测删除。获取最大的num并在后文设定为字体大小的最大值。

    1
    2
    3
    4
    5
    6
    fw, s h(最高检工作报告词云)
    lib, b s(dark) o(echarts-wordcloud.min)
    use 分词结果, clear
    gen len = length(v)
    drop if len == 3
    egen max = max(num)
  3. 设定词云参数并准备

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    * 设置词云的形状
    fw `"var shape = "./cnmap.png";"'
    * 设定宽度
    fw `"var w=800;"'
    * 设定高度
    fw `"var h=w/1.3;"'
    * 设定最小词频
    fw `"var minsize=1;"'
    * 设置最大词频
    local maxnum = `=max[1]'
    //引用变量加“=”,引用宏直接写
    fw `"var maxsize=`maxnum';"'
    fw `"var colorList = ['#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80',"'
    fw `" '#8d98b3', '#e5cf0d', '#97b552', '#95706d', '#dc69aa',"'
    fw `" '#07a2a4', '#9a7fd1', '#588dd5', '#f5994e', '#c05050',"'
    fw `"];"'
  4. 输入词云数据

    1
    2
    3
    4
    5
    6
    fw `"var data = ["'
    forval i = 1/`=_N'{
    local var `"{name: '`=v[`i']'', value: `=num[`i']'}"'
    if `i' < `=_N' fw `"`var',"'
    else fw `"`var'];"'
    }
  5. 写html文件的后半部分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    fw `"var maskImage = new Image();"'
    fw `"var option = {"'
    fw `" title:{"'
    fw `" text:"2018年最高检工作报告词云","'
    fw `" top: 50,"'
    fw `" left: 'center',"'
    fw `" textStyle:{"'
    fw `" fontSize:25,"'
    fw `" }"'
    fw `" },"'
    fw `" series: [ {"'
    fw `" type: 'wordCloud',"'
    fw `" width: w,"'
    fw `" height: h,"'
    fw `" sizeRange: [minsize,maxsize],"'
    fw `" rotationRange: [0, 45, 90, -45],"'
    fw `" rotationStep: 45,"'
    fw `" gridSize: 10,"'
    fw `" shape: 'pentagon',"'
    fw `" maskImage: maskImage,"'
    fw `" textStyle: {"'
    fw `" normal: {"'
    fw `" color: function(v) {"'
    fw `" "'
    fw `" if (v.value > 60) {"'
    fw `" return colorList[0]; "'
    fw `" } else if (v.value > 50) {"'
    fw `" return colorList[1];"'
    fw `" } else if (v.value > 40) {"'
    fw `" return colorList[2];"'
    fw `" }else if (v.value > 30) {"'
    fw `" return colorList[3];"'
    fw `" }else if (v.value > 20) {"'
    fw `" return colorList[4];"'
    fw `" }else if (v.value > 10) {"'
    fw `" return colorList[5];"'
    fw `" } else {"'
    fw `" return '#7c4dff';"'
    fw `" }"'
    fw `" },"'
    fw `" },"'
    fw `" emphasis : { "'
    fw `" shadowBlur : 10, "'
    fw `" shadowColor : '#333' "'
    fw `" } "'
    fw `" },"'
    fw `" data: data"'
    fw `" } ],"'
    fw `"};"'

    fw `"maskImage.onload = function () {"'
    fw `" option.series[0].maskImage"'
    fw `" myChart.setOption(option);"'
    fw `"}"'
    fw `"maskImage.src = shape"'
  6. 最后写文件的结尾

    1
    fw, e t

后记

振兴语录

图中作者鼓励盗版的命令在此。[坏笑][坏笑]

评论

敲黑板了!!!
本博客是在icarus基础上,振兴怒改,JWen小改后完成的。
R Stata
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×