作者:王美庭 (中南民族大学经济学院)
Stata 连享会:(知乎 | 简书 | 码云 | CSDN | 公众号 StataChina) 本文的目的: 当 Stata 官方提供的 unicode * 命令组和 连老师提供的 ua 命令执行完后仍然存在乱码时,可以试试本文的解决方案。

连享会最新专题直播

1. 问题阐述

时至今日,Stata 已经进入 16 时代代,各项功能日益完善。然而,对于广大中文老用户而言,仍然存在一个历史性问题——转码

这一切来源于 Stata 14 跨时代地全面启用了适用性更广的 UTF-8 编码格式,从而保证我们的 dofile.dta, .hlp 等文件中可以支持各种语言和字符,非英语用户再也不用一定使用英语字母作为变量名了。

历史遗留问题在于,对于国内用户,使用 Stata 13 及早期版本保存的 do 文件和 .dta 文件一般为 gb2312gbkgb18030 编码,而 Stata 14 及高级版本采用的是 UTF-8 编码。就像英文单词 he,在英语里的意思是他、男性,男子;雄性动物,而在汉语拼音中,可能被认为是和、何、禾等,所以同样的文字,在不同的编码下,将有不同的含义。于是,国内用户早期版本 Stata 保存下来的 do 文件和 .dta 文件在高级版本 Stata 下那些非英文字符出现乱码也是自然而然的事。

Stata 官方和用户们都给出了一些解决方案。比如,针对国内用户,官方提供了 unicode encoding set gb18030unicode translate * 命令组,以便实现转码 (从编码 gb18030 转码至 UTF-8 ) 命令,以及连玉君老师编写的 ua 命令对其的扩展(这里要注意的是,由于 gb18030 编码包含 gbk ,而 gbk 又包括 gb2312,所以针对国内用户,转码前设置编码 gb18030 即可)。

然而,当文件中包含了不可转换字符,则会导致以上命令无法奏效。当然,我们也可以加上 invalid 选项以保证上述命令被强制执行,但这样很可能会导致数据的部分位置被修改(而我们又不知道哪里被修改了),从而对后期的数据分析产生影响。

2. 解决方案

对于以上问题,在这里我们是怎么处理的呢?

对于 do 文件,处理还是比较简单的,我们在后期版本中打开时软件会自动提示选择何种编码打开,此时我们国内一般选择 gb18030 即可。本文重点在于解决 .dta 文件的转码。我们知道,.dta 文件的乱码一般会出现在数据标签、变量名、变量内容、变量标签、值标签。因此,对于每一个 .dta 文件,我们只需对这些部分利用相关的转码函数进行转码即可。这里看似与官方命令重复了,其实重要区别是如果 .dta 存在不可转换的字符,利用本文的做法,你就能发现不可转换的字符存在何处,然后通过本身对于数据的现有信息,手动更正即可(而对于官方命令,你不知道这里无法转换的字符在何处)。

我们最终的目的在于对于当前文件夹、子文件夹、子子文件夹中的所有 .dta 文件进行转码(由 gb18030 转至 UTF-8 ),如果刚开始就按照这个思维去写程序,这是比较困难的。我们先从单个文件入手,再进入单个文件夹,最后再对三层嵌套文件夹进行操作。

2.1 转码程序——单个 .dta 文件

使用说明

这里的目的在于将单个 .dta 文件由 gb18030 编码转换至 UTF-8 编码。前面已经说过,.dta 文件可能出现乱码的地方有:数据标签、变量名、变量内容、变量标签、值标签。因此我们用 Stata 对这些可能出现乱码的地方依次进行转码,最后再将转码后的数据替换原来的数据,以防万一,以下程序还备份了原来的 .dta 文件。

具体的注意事项如下:

  1. 在当前目录下生成了 backup files 子文件夹。
  2. 将原 .dta 数据保存至了 backup files 子文件夹中。
  3. 转码后 UTF-8 格式的 .dta 数据,覆盖了当前文件夹的原数据。
  4. 此程序 只能转一遍,只能转一遍,只能转一遍!否则原数据将丢失,且数据重新变回乱码。
  5. 转换后若还存在乱码(一般只有少数),则这些乱码就是所谓的利用官方命令(unicode translate *)无法转换的字符,需要加 invalid 选项才能继续运行命令,但这样将造成数据被更改和丢失。而在这里,运行以下程序后数据本身并没有发生变化(只是编码发生了变化),而且我们还能定位到发生乱码的具体位置,接着我们只需要根据数据本身的信息(如调查问卷的阐述)对其中存在的少量的乱码进行手动修改即可,以保证数据的原始性
  6. 程序有“用户修改部分”和“无需变更部分”,顾名思义,用户只需在“用户修改部分”修改少量的程序,即可把以下代码用在自己的数据中。
*----------------用户修改部分----------------------------
cd "D:stata15adopersonalNet_course"
local dta_file "gdpChina.dta"*-----------------无需变更部分---------------------------
use `dta_file', clear *将原dta文件备份至"backup files"文件夹中
cap mkdir "backup files"
copy `dta_file' "backup files", replace*对数据标签进行转码
local data_lbl: data label
local data_lbl = ustrfrom("`data_lbl'", "gb18030", 1)
label data "`data_lbl'"*对变量名、变量标签、字符型变量取值转码
foreach v of varlist _all {* 对字符型变量取值进行转码local type: type `v'   //将变量的类型放入宏type中if strpos("`type'", "str") {replace `v' = ustrfrom(`v', "gb18030", 1)   } //如果变量是字符型变量,使用ustrfrom()函数进行转码* 对变量标签进行转码//将变量的标签放入宏lbl中local lbl: var label `v'   //使用ustrfrom()函数对`lbl'转码local lbl = ustrfrom("`lbl'", "gb18030", 1) //将转码后的字符串作为变量的标签label var `v' `"`lbl'"'   * 对变量名进行转码//使用ustrfrom()函数将变量名字符串进行转码local newname = ustrfrom(`"`v'"', "gb18030", 1)   //将转码后的字符串重命名为变量名qui rename `v' `newname'
}*下面对数值标签进行转码
//将数值标签的程序保存到label.do中
//(如果原来dta数据是gb18030编码,则这里导出的do文件也是gb18030编码)
qui label save using label.do, replace
preserve //将do文件的内容用txt的方式导入一个变量之中
qui import delimited using label.do, ///varnames(nonames) delimiters("asf:d5f14d5d",asstring) encoding(gb18030) clear
qui describe
if r(N) == 0 {restoresave `dta_file', replace}else {qui levelsof v1, local(v1_lev)restoreforeach label_modify of local v1_lev {    //这个的foreach与前面的local(v_lev)对应,细节可查看帮助文件`label_modify'      //依次对原数据执行值标签替换操作} save `dta_file', replace  //将转码好的dta文件替换原来的dta文件}* 删除中间临时文件
erase label.do

2.2 转码程序——单个文件夹中的所有 .dta 文件

使用说明

这里的目的在于,将单个文件夹的所有 .dta 文件由 gb18030 编码转换至 UTF-8 编码。

具体的注意事项同 2.1 节一样。

*------------------------用户修改部分---------------------
// cd "D:stata15adopersonalNet_course"*-------------------------无需变更部分---------------------
local dir_dta: dir . files "*.dta", respectcase //windows系统需要加respectcase选项以区分大小写cap mkdir "backup files"  //建立备份文件夹
foreach dta_file of local dir_dta {qui copy `dta_file' "backup files", replace //将当前文件夹的dta数据备份至"backup files"文件夹中qui use `dta_file', clear*对数据标签进行转码local data_lbl: data labellocal data_lbl = ustrfrom("`data_lbl'", "gb18030", 1)label data "`data_lbl'"*对变量名、变量标签、字符型变量取值转码foreach v of varlist _all {* 对字符型变量取值进行转码local type: type `v'   //将变量的类型放入宏type中if strpos("`type'", "str") {replace `v' = ustrfrom(`v', "gb18030", 1)   //如果变量是字符型变量,使用ustrfrom()函数进行转码}* 对变量标签进行转码local lbl: var label `v'   //将变量的标签放入宏lbl中local lbl = ustrfrom("`lbl'", "gb18030", 1)   //使用ustrfrom()函数对`lbl'转码label var `v' `"`lbl'"'   //将转码后的字符串作为变量的标签* 对变量名进行转码local newname = ustrfrom(`"`v'"', "gb18030", 1)   //使用ustrfrom()函数将变量名字符串进行转码qui rename `v' `newname'   //将转码后的字符串重命名为变量名}*下面对数值标签进行转码qui label save using label.do, replace   //将数值标签的程序保存到label.do中preserve*- 将do文件的内容用txt的方式导入一个变量之中,然后再对该变量进行拉直qui import delimited using label.do, ///varnames(nonames) delimiters("asf:d5f15g4dsf9qw8d4d5d",asstring) encoding(gb18030) clearqui describeif r(N) == 0 {restoresave `dta_file', replace}else {qui levelsof v1, local(v1_lev)restoreforeach label_modify of local v1_lev {    //这个的foreach与前面的local(v_lev)对应,细节可查看帮助文件`label_modify' //依次对原数据执行值标签替换操作} save `dta_file', replace  //将转码好的dta文件替换原来的dta文件}* 删除中间临时文件erase label.do
}

2.3 转码程序——三层嵌套文件夹下的所有 .dta 文件

使用说明

这里的目的在于,将当前文件夹、所有子文件夹、以及所有子子文件夹下的所有 .dta 文件由 gb18030 编码转换至 UTF-8 编码。

具体的注意事项除了 2.1 节的以外,其他的还有: 1. 这部分程序嵌套了转码_单个文件夹.do文件(为了程序结构的易读性),于是用户在使用这部分程序之前,需要将 2.2 节的代码部分打包成转码_单个文件夹.do文件(内容无需更改,直接复制粘贴即可),然后将其放在D盘根目录下。 2. 在“用户修改部分”将路径修改为自己要转码的路径即可。

*------------------------用户修改部分---------------------
cd "D:stata15adopersonalNet_course"*-------------------------无需变更部分--------------------
*将当前文件夹下的所有dta文件进行转码(第一层)
do "D:转码_单个文件夹.do"*将当前子文件夹下的所有dta文件进行转码(第二层)
local dir_list : dir . dirs "*", respectcase
foreach subdir of local dir_list {if "`subdir'" == "backup files" {continue //保留备份的原文件不动}cd "`subdir'"do "D:转码_单个文件夹.do"*将当前子子文件夹下的所有dta文件进行转码(第三层)local dir_list2 : dir . dirs "*", respectcaseforeach subdir2 of local dir_list2 {if "`subdir2'" == "backup files" {continue //保留备份的原文件不动}cd "`subdir2'"do "D:转码_单个文件夹.do"qui cd ..}qui cd ..
}

附录

特别说明: 文中包含的链接在微信中无法生效。请点击本文底部左下角的【阅读原文】。

以上三部分代码的Stata do文件如下:

  • Stata转码_单个文件
  • Stata转码_单个文件夹
  • Stata转码_三层嵌套文件夹

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 欢迎赐稿: 欢迎赐稿至StataChina@163.com。录用稿件达 三篇 以上,即可 免费 获得一期 Stata 现场培训资格。
  • [往期精彩推文:] Stata绘图 | 时间序列+面板数据 | Stata资源 | 数据处理+程序 | 回归分析-交乘项-内生性 |
  • 连享会最新专题直播

hbase 数据导出乱码_赶尽杀绝:Stata中文乱码之转码相关推荐

  1. mysql不同版本乱码_解决MySQL中文乱码以及版本不一致问题_MySQL

    一.导出数据 先说明一下自己的环境:Mac OS X 10.8.3, MySQL Community Server 5.6.10, MySQL Workbench 5.2.47. 我想把本机数据库内的 ...

  2. mysql数据库 中文乱码_数据库 MySQL中文乱码解决办法总结

    MySQL中文乱码解决办法 前言: MySQL是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1 ...

  3. mysql .net 乱码_.net mysql中文乱码解决办法

    1) 只要是gb2312,gbk,utf8等支持多字节编码的字符集都可以储存汉字,当然,gb2312中的汉字数量远少于gbk,而gb2312,gbk等都可在utf8下编码. 2)用命令show var ...

  4. 图形化mysql出现乱码_关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)...

    最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅. 首先: 用show variables like &quo ...

  5. java解析xml中文字符乱码_各种Java中文乱码的处理方法

    对于Java,由于默认的编码方式是UNICODE,所以用中文也易出问题,常见的解决是: String s2 = new String(s1.getBytes("ISO-8859-1" ...

  6. xp mysql字符集与乱码_解决MYSQL中文乱码问题三种方法

    方法三 1>本文将消除乱码分为三步: >消除页面乱码, >消除从mysql教程中读出中文乱码, >消除插入mysql数据库教程中的中文乱码: 15>注意编码表示方式在网页 ...

  7. mysql linux 中文乱码_解决MySQL中文乱码的问题

    遇到MySQL中文乱码问题,首先用status命令检查数据库的配置,如下: 上图会显示数据库配置的各项信息. 还可以用 show create database XXX,来显示创建数据库的时候的编码设 ...

  8. 中文提交到git乱码_解决Git 中文乱码问题

    乱码情景对号入座和解决方案 乱码情景1 在cygwin中,使用git add添加要提交的文件的时候,如果文件名是中文,会显示形如274\232\350\256\256\346\200\273\347\ ...

  9. git配置中文乱码_解决git中文乱码问题

    进入git安装目录,改一下配置就可以基本解决: 1.etc\gitconfig: [gui] encoding = utf-8 [i18n] commitencoding = gbk [svn] pa ...

  10. linux mysql插入数据乱码_linux mysql数据库中文乱码

    mysql中文乱码 mysql是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1.中文乱码 1. ...

最新文章

  1. python学习笔记-基础、语句、编码、迭代器
  2. date oracle 表中_从 MySQL 迁移数据到 Oracle 中的全过程
  3. how can you save more space at home?
  4. 另一个绑定事件的方式 为元素绑定事件的区别
  5. 嵌入式linux字符设备驱动
  6. 《javaScript100例|02》超级经典一套鼠标控制左右滚动图片带自动翻滚
  7. Android转载一:Android文件命名规范
  8. IDEA 载入jQuery的方法
  9. 【java基础知识】java.util.LinkedHashMap cannot be cast to com.XXX.XXX
  10. HTML输入=“文件”接受属性文件类型(CSV)
  11. cpu要和gpu搭配吗_搞懂GPU为什么比CPU“快”
  12. java script幻灯片效果,JS实现图片幻灯片效果代码实例
  13. 今日,立秋。秋季养生篇。
  14. 百度地图api中文乱码
  15. html onclick点击事件失效,HTML onfocus,onclick事件不起作用
  16. uikit框架_UIkit框架的口哨之旅
  17. 香港爱情电影二十四经
  18. oracle odi的使用,Oracle ODI 使用
  19. WinUSB - 微软为所有 USB 设备提供的常规驱动程序
  20. C++语言单链表实现荷兰旗问题

热门文章

  1. 计算机接口cad图,管道接口CAD平面图怎么画
  2. 导入mysql数据库怎么错误信息_mysql导入数据库错误
  3. Linux之用户管理、权限管理、程序安装卸载
  4. conda tensorflow_TensorFlow笔记1——补充附录(1) 机器学习相关库安装、使用中遇到的报错情况...
  5. 伪原创工具-免费伪原创软件
  6. java 调用dll_Python调用海康SDK抓取红外图像
  7. css3实现非矩形图片效果
  8. el-table 值不同颜色_Excel核对对比数据,快速找出两份数据不同之处
  9. 递归函数实例大全 1
  10. 计算机网络3 数据链路层