查看原文
其他

Unicode失效时如何转码dta文件?

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:孙雪丽

本文编辑:张   宇

技术总编:薛   原

爬虫俱乐部将于2019年1月19日至25日在武汉举行两期Stata编程技术定制培训,此次采取初级班和高级班分批次培训模式,采用理论与案例相结合的方式,旨在帮助大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。详细培训大纲及报名方式,请见往期推文《2019寒假Stata编程技术定制培训班》。报名表下载请点击文末阅读原文呦~

当我们读入数据遇到乱码问题时,需要对读入的文件进行转码。在我们之前的推文《朝花夕拾|识得庐山真面目-unicode命令》中介绍过最常用的转码命令——unicode。但是unicode命令并不总能满足我们转码的需要。

近期我们就收到在做社会科学研究的小伙伴发来的求助信,他的研究中用到了中国劳动力动态调查(CLDS)2014数据,其中的一个dta文件读入之后如下图所示:

小伙伴在用unicode三行命令对其转码时发现Stata会出现闪退的情况,重新打开,数据依然是乱码……unicode命令失效了。这种情况下我们如何对其转码,使其正常显示呢?今天我们就介绍一个强大的转码组合——ustrfrom()函数+label save命令。

可以看到,此数据中变量的标签(红色方框)、字符型变量的取值(紫色方框)、数值型变量的值标签(黄色方框)都是乱码,在一些数据中,甚至变量名也会存在乱码。其中,变量标签、字符型变量的取值、变量名的转码主要用到的是ustrfrom()函数,数值型变量值标签的转码主要用到label save命令。

1.变量标签的转码

对变量标签进行转码时,首先通过宏扩展函数将变量的标签暂时存储于局部宏lbl中;然后使用ustrfrom()函数将宏lbl的编码从gb18030转为utf-8;最后,用label var命令重新定义该变量的标签。数据中所有变量的标签都需要转码,因此将以上内容对所有变量循环:

foreach v of varlist _all {       local lbl: var label `v'   //将变量的标签放入宏lbl中       local lbl = ustrfrom("`lbl'", "gb18030", 1)  //使用ustrfrom()函数对`lbl'转码,并将转码后的内容放入宏lbl中       label var `v' `"`lbl'"'   //将转码后的字符串作为变量的标签 }

变量标签转码完成:

2.字符型变量取值的转码

ustrfrom()是一个字符串函数,可以对字符型变量转码,但是其对数值型变量转码时会报错,因此,在用ustrfrom()函数转码前,需要先判断变量是否为字符型变量,若是,则用ustrfrom()函数对其转码,并用replace命令进行替换。判断的方法是使用宏扩展函数将变量类型放入局部宏type中,如果变量类型中出现了"str"则说明是字符型变量。这里同样对所有变量循环:

foreach v of varlist _all {       local type: type `v'   //将变量的类型放入宏type中       if strpos("`type'","str") {              replace `v' = ustrfrom(`v', "gb18030", 1)       } }

字符型变量的取值转码完成:


3.变量名的转码

尽管此数据中变量名并不是乱码,但有些数据中变量名也同样可能出现乱码问题。变量名转码同样可以用ustrfrom()函数,为了便于大家使用,我们附上变量名的转码程序:

foreach v of varlist _all {       local newname = ustrfrom(`"`v'"', "gb18030", 1)         rename `v' `newname'   //将转码后的字符串重命名为变量名 }

将以上三个循环中的内容合并到一个循环中,变量标签、字符型变量的取值、变量名转码的完整程序如下:

clear use D:\CLDS数据\CLDS2014.dta foreach v of varlist _all {       local lbl: var label `v'   //将变量的标签放入宏lbl中       local lbl = ustrfrom("`lbl'", "gb18030", 1)  //使用ustrfrom()函数对`lbl'转码,并将转码后的内容放入宏lbl中       label var `v' `"`lbl'"'   //将转码后的字符串作为变量的标签       local type: type `v'   //将变量的类型放入宏type中       if strpos("`type'","str") {              replace `v' = ustrfrom(`v', "gb18030", 1)         }       local newname = ustrfrom(`"`v'"', "gb18030", 1)         rename `v' `newname'   //将转码后的字符串重命名为变量名 }

爬虫俱乐部是您身边的科研助手,能够为您在数据处理实证研究中提供帮助。承蒙30000+粉丝的支持与厚爱,我们在腾讯课堂推出了网络视频课程,专注于数据整理、网络爬虫、循环命令编制和结果输出…李老师及团队精彩地讲解,深入浅出,注重案例与实战,让您更加快速高效地掌握Stata技巧及数据处理的精髓,而且可以无限次重复观看,百分百好评,简单易学,一个月让您从入门到精通。绝对物超所值!观看学习网址:https://ke.qq.com/course/286526?tuin=1b60b462,敬请关注!



4.数值型变量值标签的转码

Stata中数值型变量的观测值以黑色字体显示,但当某数值型变量被赋予特定的值标签后便以蓝色字体显示,数据中的蓝色乱码即数值型变量的值标签。数值型变量值标签的转码很难用ustrfrom()函数处理,但可以用label save命令保存定义值标签的程序,将保存的do文件处理后运行,实现转码的目的。

label save using mylabel.do,replace

这条命令将数据中定义值标签的程序存入到了一个叫mylabel的do文件中,在Stata15中打开这个do文件,选择中文(gb18030)编码:

打开后,如下图所示:

可以看到,字母i开头的值标签的定义中有乱码,若直接运行此文件,stata同样会出现闪退,因此我们要将这部分有乱码的程序删除,运行值标签定义正确的剩余部分程序。之后在命令窗口输入label list查看值标签的定义:

可以看到,其余值标签均已显示正常,i60、i61、i62、i63、i64、i65、i73、i978的定义依然是乱码。这时我们用label drop命令删除这几个值标签的定义规则,再用label define命令重新为其定义。程序如下:

label drop i60 i61 i62 i63 i64 i65 i73 i978 label define i60 1 "有" 2 "没有" 99999 "不清楚"
label define i61 1 "有" 2 "没有" 99999 "不清楚"
label define i62 1 "有" 2 "没有" 99999 "不清楚"
label define i63 1 "有" 2 "没有" 99999 "不清楚"
label define i64 1 "有" 2 "没有" 99999 "不清楚"
label define i65 1 "有" 2"没有" 99999 "不清楚"
label define i73 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 "高山族" 56 "珞巴族" 99 "其他"
label define i978 1 "没有" 2 "有"

数值型变量值标签的转码完成:

至此,我们就完成了对所有乱码的转码,最终的数据如下图所示:

最后,用如下命令将转码完成的数据保存即可:

save CLDS2014, replace

这个案例几乎涉及了dta文件中可能出现乱码的所有情况,学习过这个案例的转码之后,大概再复杂的转码问题都难不倒你了吧,小伙伴们get到了吗?

数值型变量值标签转码的过程中,为了便于完整地展示值标签的修改过程,我们采用了label drop和label define命令,在我们腾讯课堂的课程《精通stata之数据整理》转码专题为大家介绍了另一种值标签的转码方法,并且有更多更详细的转码知识,欢迎大家前去学习。我们会持续更新新的学习内容哦!

观看学习网址:https://ke.qq.com/course/286526?tuin=1b60b462,敬请关注!

有问题,不要怕!访问 

http://www.wuhanstring.com/uploads/5_aboutus/爬虫俱乐部-用户问题登记表.docx (复制到浏览器中)下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~

爬虫俱乐部的github主站正式上线了!我们的网站地址是:https://stata-club.github.io,粉丝们可以通过该网站访问过去的推文哟~

爬虫俱乐部隆重推出数据定制及处理业务,您有任何网页数据获取及处理方面的难题,请发邮件至我们邮箱statatraining@163.com,届时会有俱乐部高级会员为您排忧解难!

对爬虫俱乐部的推文累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!

往期推文推荐

关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。


此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存