Skip to content

yichaoli921/2008-2016-

Repository files navigation

2008-2016

从原数据获取每个变量对应的中文标签,方便agent跑数据

description: 为全国税收调查数据(2007-2016年)提取Stata变量中文标签,处理Excel合并单元格和PDF两种来源 auto_execution_mode: 3

税收调查数据 Stata 变量标签提取流程

概述

全国税收调查数据的 .dta 文件中变量名为 f2, f3, ... f295 等编号,不含中文说明。本流程从变量说明文件(Excel或PDF)中提取中文标签,生成 Stata label var 命令,应用到 .dta 文件。

数据来源与列结构差异

年份 说明文件格式 行号所在列 标签列 合并单元格逻辑
2012 Excel (.xlsx) E列(5) B(2)/C(3)/D(4) C+D合并→取C/D值;否则取D列
2013 Excel (.xlsx) E列(5) B(2)/C(3)/D(4) C+D合并→取C/D值;否则取D列
2014 Excel (.xlsx) E列(5) B(2)/C(3)/D(4) C+D合并→取C/D值;否则取D列
2015 Excel (.xlsx) F列(6) C(3)/D(4)/E(5) D+E合并→取D/E值;否则取E列
2016 PDF - - 手动/OCR提取

关键发现:pandas 的 read_excel 无法识别合并单元格,会导致标签提取错误。必须使用 openpyxl 库处理。

步骤一:从Excel提取标签(2012-2015年)

1.1 安装依赖

pip install openpyxl

1.2 合并单元格处理逻辑

Excel中标签列常有合并单元格,例如:

  • C列是大分类标题(如"营业利润的计算"),纵向合并多行
  • D+E列横向合并,包含具体变量描述(如"营业收入(269=270+271)")

提取规则(以2015年C/D/E列为例,2012-2014年B/C/D列同理):

  1. C、D、E三列合并成同一个范围 → 取该合并单元格的值
  2. D、E合并但C是不同范围(C通常是纵向大分类) → 取D/E合并单元格的值(这才是具体变量描述)
  3. 三列都没合并 → 取最右列(2015年取E列,2012-2014年取D列)

1.3 运行提取脚本

# 2012-2014年
python3 extract_2012_2014_labels_merged.py

# 2015年
python3 extract_2015_labels_merged.py

脚本会生成:

  • {年份}_variable_mapping_merged.txt — 变量映射表
  • {年份}_stata_labels_merged.do — Stata标签do文件

1.4 核心Python代码逻辑

import openpyxl
import re

wb = openpyxl.load_workbook(excel_file, data_only=True)
ws = wb.active
merged_ranges = list(ws.merged_cells.ranges)

def get_merged_range(cell_row, cell_col):
    for mr in merged_ranges:
        if cell_row >= mr.min_row and cell_row <= mr.max_row \
           and cell_col >= mr.min_col and cell_col <= mr.max_col:
            return mr
    return None

def get_description_for_row(ws, excel_row, label_cols, merged_ranges):
    """
    label_cols: 2012-2014为[2,3,4](B/C/D),2015为[3,4,5](C/D/E)
    """
    col_b, col_c, col_d = label_cols  # 逻辑上的左/中/右三列
    mr_b = get_merged_range(excel_row, col_b)
    mr_c = get_merged_range(excel_row, col_c)
    mr_d = get_merged_range(excel_row, col_d)

    # 情况1:三列合并成同一个范围
    if mr_b and mr_c and mr_d and mr_b == mr_c == mr_d:
        return ws.cell(row=mr_b.min_row, column=mr_b.min_col).value

    # 情况2:中间+右侧列合并(最常见的情况)
    if mr_c and mr_d and mr_c == mr_d:
        return ws.cell(row=mr_c.min_row, column=mr_c.min_col).value

    # 情况3:都没合并,取最右列
    val = ws.cell(row=excel_row, column=col_d).value
    return val if val else ws.cell(row=excel_row, column=col_c).value

步骤二:从PDF提取标签(2016年)

2016年变量说明为PDF格式,无法用openpyxl处理。需要:

  1. 用OCR工具或手动方式从PDF提取变量编号和中文描述
  2. 生成 2016_stata_labels_from_pdf.do 文件
  3. PDF标签末尾常带"全年累计数或期初、期末数"后缀,属于格式残留,可按需清理

步骤三:应用标签到Stata数据

3.1 Stata do文件模板

* 应用变量标签
clear all
set more off

global data_dir "数据目录路径"
global labels_dir "标签do文件目录"

* 处理某年数据
use "$data_dir/XXXXsd.dta", clear
do "$labels_dir/XXXX_stata_labels_merged.do"
save "$data_dir/XXXXsd_labeled.dta", replace

3.2 在Stata中执行

/Applications/Stata/StataMP.app/Contents/MacOS/stata-mp -b do apply_labels.do

3.3 验证标签

在Stata中运行 describe 命令检查:

describe f2 f3 f269 f271 f272

常见问题与注意事项

双引号问题

标签文本中若包含中文双引号(如 ""管理费用""),会导致Stata label var 命令语法错误(r(198))。解决方法:在生成do文件时移除标签中的双引号,而非转义。

Stata标签长度限制

Stata变量标签最长80字符(UTF-8下中文约26个字),超长标签会被自动截断。

不同年份变量含义不同

同一编号在不同年份含义可能不同。例如:

  • f269:2012年=税率(25%),2013年=工资,2014/2015年=营业收入
  • f127:2012年=已纳城镇土地使用税税额,2013年=已纳房产税税额,2014/2015年=土地面积合计

切勿跨年份直接复制标签!

文件清单

必须保留的文件

文件 说明
extract_2012_2014_labels_merged.py 2012-2014年标签提取脚本(openpyxl,正确处理合并单元格)
extract_2015_labels_merged.py 2015年标签提取脚本(openpyxl,正确处理合并单元格)
2012_stata_labels_merged.do 2012年Stata标签命令
2013_stata_labels_merged.do 2013年Stata标签命令
2014_stata_labels_merged.do 2014年Stata标签命令
2015_stata_labels_merged.do 2015年Stata标签命令
2016_stata_labels_from_pdf.do 2016年Stata标签命令(PDF来源)

数据文件位置

  • 原始数据:{数据目录}/XXXXsd.dta
  • 标注后数据:{数据目录}/XXXXsd_labeled.dta
  • Excel说明文件:{数据目录}/税调变量说明07-16/XXXX年企业数据表.xlsx

About

从税调原数据获取每个变量对应的中文标签,方便agent跑数据

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors