实证方法教程 / descriptive_stats

描述性统计

第一张表不是凑数,是数据可信度体检

这节课解决什么用于进入模型前确认样本、变量、分布和基础诊断是否可信。
先准备哪些变量变量含义清楚
会看到哪张表描述性统计.csv
论文里怎么克制解释正文只报告和主模型相关的关键口径;完整清洗记录放到附录或复现包。

描述性统计是什么?

描述性统计回答的是样本长什么样,而不是假设是否成立。Table 1 不是证明假设的地方,它要让读者看清样本量、变量量纲、离散程度、极端值和后续模型可能遇到的数据问题。

先用一句话理解

把描述性统计想成论文的体检表。体检表不能告诉你药有没有效果,但能告诉你样本是否健康、变量是否偏态、有没有明显异常值,以及后面的模型为什么要做对数、缩尾或样本限制。

什么时候用

判断项教科书式判断
适合用在论文进入模型前,先交代核心变量、控制变量和样本分布。
先不要用在想证明因果关系或检验假设时。描述统计只描述样本,不提供识别。
最关键的前提Table 1 的变量口径应和主回归一致,不能用一套变量做描述、另一套变量做模型。
读表顺序先看 N,再看均值/中位数,再看标准差、最小值和最大值。
论文表述边界只能写样本分布特征,不能把均值差或极端值直接写成机制结论。

把它和相近方法分清楚

容易混淆的对象怎么区分初学者记法
描述性统计展示每个变量自身的分布。回答样本长什么样。
相关矩阵展示两个变量是否一起变化。回答变量之间是否同向变化。
基准回归控制其他因素后估计条件关系。回答主模型下核心关系是否稳定。

核心直觉和模型公式

均值、离散程度和样本量

最基础的描述统计通常从均值和标准差开始:

\[\bar{x}=\frac{1}{N}\sum_{i=1}^{N}x_i,\quad s=\sqrt{\frac{1}{N-1}\sum_{i=1}^{N}(x_i-\bar{x})^2}\]

均值告诉你变量中心位置,标准差告诉你变量分散程度;右偏变量还必须看中位数和最大值。

公式里的符号怎么读

符号含义在本页怎么理解
N样本量每个变量实际可用的观测数。
x_i第 i 个观测值某个企业、个人或地区在该变量上的数值。
x_bar均值变量的平均水平,容易受极端值影响。
s标准差变量围绕均值波动的程度。
median中位数右偏变量里比均值更稳的中心位置。
min / max最小值和最大值用来发现异常值、缺失码或不合理量纲。

专业使用口径

专业 Table 1 的价值在于帮读者预判模型,而不是把软件默认输出原样贴上去。

口径专业写法
变量选择只放论文主模型和关键稳健性会用到的变量。
量纲说明对数变量、标准化变量、百分比变量要在变量名或注释中说清。
缺失情况不同变量 N 差异很大时,说明后续回归样本可能变化。
异常值极端最大值、负值或缺失码要在正文或附录说明处理方式。

一步一步做:从问题到结果的五步

步骤这一页具体做什么做到什么程度才算读懂
1. 列出主模型变量先确定因变量、核心解释变量和控制变量。Table 1 应服务于主模型。
2. 固定样本口径只统计后续论文会使用的样本范围。全样本描述和回归样本描述不能混用。
3. 输出关键统计量N、均值、标准差、最小值、中位数、最大值。右偏变量不能只看均值。
4. 检查异常值看最大值、最小值和标准差是否合理。异常值要先处理再进入模型。
5. 写成论文语言用一句话概括样本和关键变量分布。不要逐格复述整张表。

结果怎么读:先读口径,再读数字

本页案例读表时,先记住这个口径:Patent 的均值是 1.9930556,中位数是 2,最大值是 7;这说明创新产出不是正态连续变量,后面做回归要考虑右偏和计数特征。

读表顺序本页怎么读不要这样读
先看 N确认每个变量有多少可用观测。不要先看均值。
再看中心位置均值和中位数差很大时,说明变量可能右偏。右偏变量不宜只解释均值。
然后看离散程度标准差和极值帮助判断变量波动和异常。标准差大不自动代表研究有问题。
最后看模型影响描述统计要服务于后面的对数、缩尾和模型选择。不要把 Table 1 写成结论表。

初学者最容易错在哪里

误读为什么错
把 Table 1 当显著性检验错。描述统计不检验因果,也不检验主假设。
变量口径和主模型不一致错。读者会无法对照后续回归表。
只给均值和标准差不够。右偏变量至少还要看中位数和最大值。
不处理缺失码和异常值错。999、-99 这类编码会污染均值和标准差。

先看这个案例的结论

  • Patent 的均值是 1.9930556,中位数是 2,最大值是 7;这说明创新产出不是正态连续变量,后面做回归要考虑右偏和计数特征。
  • DFI 的均值是 -.062502638,标准差是 1.0140283,区间从 -3.2634001 到 3.2537999;核心解释变量有足够横截面差异。
  • 这张表用的是 720 条公司-年观测,后续相关、VIF、Hausman 和基准回归都应该尽量保持同一口径。

变量要求和案例口径

字段口径
数据CSMAR 风格 A 股企业创新面板
原始样本196 家上市公司,2015-2020 年,约 1200 个公司-年观测;各方法有效样本以本页输出表 N 为准
因变量patent_count;回归页通常使用 ln(1 + patent_count)
核心解释变量dfi_index,数字普惠金融指数;部分案例输出展示的是标准化后的 dfi_index
控制变量roa、lev、size、growth、cashflow、tobinq、top1、dual、board、indep、soe、age
输出文件描述性统计.csv
角色要求无硬性角色要求
依赖包无额外 Stata 社区包要求

实际代码

下面是本页案例里的最小 Stata 代码。它的作用是帮助你看清变量怎么进入模型、结果文件怎么生成,而不是要求你在网页里手动运行。

log using "/root/workspace/empirical-wizard/workspace/5b186599/analysis.log", replace text
global JOB_DIR "/root/workspace/empirical-wizard/workspace/5b186599"
set more off
adopath + "/root/ado/plus"
global DATA_PATH "/root/workspace/empirical-wizard/workspace/test_e2e/csmar_innovation.csv"
import delimited "/root/workspace/empirical-wizard/workspace/test_e2e/csmar_innovation.csv", clear case(preserve)
capture confirm global JOB_DIR
if _rc global JOB_DIR "."
quietly duplicates drop

local statvars "patent_count dfi_index roa lev size growth cashflow tobinq top1 dual"
local timevar "year"
local idvar "stkcd"
local dvvar "patent_count"
local ivvar "dfi_index"

tempfile ewiz_desc
tempname ewiz_post
postfile `ewiz_post' str64 variable double count mean sd min p25 p50 p75 max using `ewiz_desc', replace
foreach v of local statvars {
    capture confirm numeric variable `v'
    if !_rc {
        quietly summarize `v', detail
        post `ewiz_post' ("`v'") (r(N)) (r(mean)) (r(sd)) (r(min)) (r(p25)) (r(p50)) (r(p75)) (r(max))
    }
}
postclose `ewiz_post'

preserve
use `ewiz_desc', clear
rename count N
export delimited using "$JOB_DIR/描述性统计.csv", replace
restore

quietly pwcorr `statvars', sig
matrix EWIZ_C = r(C)
matrix EWIZ_P = r(sig)
local nvars : word count `statvars'
preserve
clear
set obs `nvars'
gen str64 variable = ""
forvalues i = 1/`nvars' {
    local vname : word `i' of `statvars'
    replace variable = "`vname'" in `i'
}
forvalues j = 1/`nvars' {
    gen c`j' = .
}
forvalues i = 1/`nvars' {
    forvalues j = 1/`nvars' {
        replace c`j' = EWIZ_C[`i', `j'] in `i'
    }
}
forvalues j = 1/`nvars' {
    local vname : word `j' of `statvars'
    rename c`j' `vname'
}
export delimited using "$JOB_DIR/相关系数矩阵.csv", replace
restore

* 同时导出 p 值矩阵(上三角 p、下三角系数约定:这里直接把 p 矩阵单独导出
* 供 reporter 读取;渲染时组合成『下三角系数+星号 / 上三角 p』学术格式)
preserve
clear
set obs `nvars'
gen str64 variable = ""
forvalues i = 1/`nvars' {
    local vname : word `i' of `statvars'
    replace variable = "`vname'" in `i'
}
forvalues j = 1/`nvars' {
    gen p`j' = .
}
forvalues i = 1/`nvars' {
    forvalues j = 1/`nvars' {
        capture replace p`j' = EWIZ_P[`i', `j'] in `i'
    }
}
forvalues j = 1/`nvars' {
    local vname : word `j' of `statvars'
    rename p`j' `vname'
}
export delimited using "$JOB_DIR/相关系数矩阵_pvalue.csv", replace
restore

foreach v in `dvvar' `ivvar' {
    if "`v'" != "" {
        capture confirm numeric variable `v'
        if !_rc {
            quietly inspect `v'
            local _nunique = r(N_unique)
            quietly summarize `v', meanonly
            local _vmin = r(min)
            local _vmax = r(max)
            // Treat as dummy ONLY when there are exactly 1-2 unique values AND they are 0/1.
            if `_nunique' <= 2 & `_vmin' >= 0 & `_vmax' <= 1 & `_vmax' - `_vmin' <= 1 & `_vmax' == int(`_vmax') & `_vmin' == int(`_vmin') {
                graph bar (mean) `v', title("`v' Distribution") ytitle("Share") blabel(bar, format(%9.3f))
            }
            else {
                histogram `v', normal title("`v' Distribution") xtitle("`v'") ytitle("Frequency")
            }
            capture graph export "$JOB_DIR/distribution_`v'.png", replace width(1600)
        }
    }
}

if "`timevar'" != "" & "`dvvar'" != "" {
    capture confirm variable `timevar'
    if !_rc {
        preserve
        keep `timevar' patent_count dfi_index
        collapse (mean) patent_count dfi_index, by(`timevar')
        sort `timevar'
        if "`ivvar'" != "" {
            twoway (line `dvvar' `timevar', lcolor(navy) lwidth(medthick) msymbol(o)) (line `ivvar' `timevar', yaxis(2) lcolor(maroon) lpattern(dash) msymbol(diamond)), title("Core Variable Trends") xtitle("`timevar'") ytitle("`dvvar' mean", axis(1)) ytitle("`ivvar' mean", axis(2)) legend(order(1 "`dvvar'" 2 "`ivvar'"))
        }
        else {
            twoway line `dvvar' `timevar', lcolor(navy) lwidth(medthick) msymbol(o) title("Outcome Trend") xtitle("`timevar'") ytitle("`dvvar' mean")
        }
        capture graph export "$JOB_DIR/descriptive_trend.png", replace width(1800)
        restore
    }
}

if "`idvar'" != "" & "`timevar'" != "" {
    capture confirm variable `idvar'
    capture confirm variable `timevar'
    if !_rc {
        preserve
        collapse (count) obs_count=`timevar' (min) start_period=`timevar' (max) end_period=`timevar', by(`idvar')
        export delimited using "$JOB_DIR/panel_structure.csv", replace
        restore
    }
}

di "描述性统计与相关分析输出完成"
log close

实际输出表

这张表是本方法页配套案例的输出结果,用来把前面的公式、变量口径和代码对应到实际数字。

variableNmeansdminp25p50p75max
patent_count7201.99305561.346176401237
dfi_index720-.0625026381.0140283-3.2634001-.72144997-.052749999.63583.2537999
roa720.0416552761.0799717-3.2021-.64324999.02565.785553.7595
lev720.0516491681.0138992-3.0769999-.65769994.1188.782150033.2701001
size720-.061905281.0274159-3.0518999-.76375002-.045199998.659550012.7516999
growth720-.023481252.9872914-2.4997001-.68540001-.054750003.627099993.191
cashflow720.0339645861.0026336-2.9795001-.59189999.017999999.736500023.7314
tobinq720.060584169.99526453-3.1794-.59360003.1068.657150033.4525001
top1720-.02420889.98265254-2.8601999-.70795-.03805.648352.4839001
dual720-.0120437481.0300157-2.691-.77559996-.060199998.670950064.1808

补充输出

下面这些文件来自同一次案例生成流程,用来补齐主表之外的诊断信息。

panel_structure.csv

stkcdobs_countstart_periodend_period
F0000620152020
F0001620152020
F0002620152020
F0003620152020
F0004620152020
F0005620152020
F0006620152020
F0007620152020
F0008620152020
F0009620152020
F0010620152020
F0011620152020
F0012620152020
F0013620152020
F0014620152020
F0015620152020
F0016620152020
F0017620152020
F0018620152020
F0019620152020
F0020620152020
F0021620152020
F0022620152020
F0023620152020
F0024620152020
F0025620152020
F0026620152020
F0027620152020
F0028620152020
F0029620152020
F0030620152020
F0031620152020
F0032620152020
F0033620152020
F0034620152020
F0035620152020

这里只展示前 36 行;页面保留截断预览,避免过长表格影响阅读。

相关系数矩阵.csv

variablepatent_countdfi_indexroalevsizegrowthcashflowtobinqtop1dual
patent_count1.43950948.24073994.013024604.17620607-.027265593.033593308.019011619-.032499224.0060554333
dfi_index.439509481.010009783.0087096244.03340555-.021365453.012453728-.0013975492-.0043962095-.0011652668
roa.24073994.0100097831.026359176-.039585255.044941634.02670249.015529391-.0061969026.025583275
lev.013024604.0087096244.0263591761.070986755-.027704539.020903539.041491505.0043391068.00078530196
size.17620607.03340555-.039585255.0709867551.0048936065-.062741034-.030523267-.033124272.010508359
growth-.027265593-.021365453.044941634-.027704539.00489360651-.012840015.042992894-.01781022.0097842375
cashflow.033593308.012453728.02670249.020903539-.062741034-.0128400151-.016293354.013908384.056830361
tobinq.019011619-.0013975492.015529391.041491505-.030523267.042992894-.0162933541-.0075492994-.0093645761
top1-.032499224-.0043962095-.0061969026.0043391068-.033124272-.01781022.013908384-.00754929941.01563069
dual.0060554333-.0011652668.025583275.00078530196.010508359.0097842375.056830361-.0093645761.015630691

相关系数矩阵_pvalue.csv

variablepatent_countdfi_indexroalevsizegrowthcashflowtobinqtop1dual
patent_count2.3083303e-355.9494361e-11.727168621.9633560e-06.4650985.36807188.61054552.38388494.87114561
dfi_index2.3083303e-35.78859872.81552684.37075645.56707507.73868072.97013813.90625918.97509962
roa5.9494361e-11.78859872.48007327.28880164.22842577.47437078.6774112.86816245.49309739
lev.72716862.81552684.48007327.056927469.45794097.57548803.2661905.9074713.98321754
size1.9633560e-06.37075645.28880164.056927469.89571053.092520148.41347557.37480077.77833712
growth.4650985.56707507.22842577.45794097.89571053.73088443.24925995.63328677.793253
cashflow.36807188.73868072.47437078.57548803.092520148.73088443.66249871.70946801.12763354
tobinq.61054552.97013813.6774112.2661905.41347557.24925995.66249871.83974481.80193251
top1.38388494.90625918.86816245.9074713.37480077.63328677.70946801.83974481.67542642
dual.87114561.97509962.49309739.98321754.77833712.793253.12763354.80193251.67542642

案例图

这是一张由同一份案例数据生成的页面内诊断图。

真实 smoke 输出:Patent 与 DFI 的年度趋势。
真实 smoke 输出:Patent 与 DFI 的年度趋势。
真实 smoke 输出:Patent 计数分布。
真实 smoke 输出:Patent 计数分布。
真实 smoke 输出:DFI 指数分布。
真实 smoke 输出:DFI 指数分布。

论文里怎么写

本文在共用企业面板样本上报告描述性统计,核心输出见 描述性统计.csv。结果解释时同时关注样本口径、变量构造、系数方向、标准误和适用前提,避免只凭单个 p 值完成方法选择。

检查清单

  • Table 1 至少读样本量、均值、标准差、中位数和极值;不要只盯均值。
  • Patent 这类计数变量要看右偏程度,决定后续是否使用 ln(1 + Y) 或计数模型。
  • 描述性统计只说明样本长什么样,不能写成 DFI 影响企业创新。

返回教程库 · 查看共用案例