基于Stata的上市公司耐心资本投资测算:从财报拆分到实证应用

发布时间:2026/9/16 2:18:06
基于Stata的上市公司耐心资本投资测算:从财报拆分到实证应用 先说句实在话我在几个常用财经数据库里翻了大半天也没有找到一个自带“耐心资本”字段的报表。但这不代表这个概念没法落到实证里反而说明它需要我们自己动手从财报里一笔一笔拆出来。所谓耐心资本投资通俗讲就是企业把钱投到回报周期长、短期利润表上不太好看、但决定未来三五年甚至十年竞争力的地方典型包括研发投入、长期产能建设、核心技术引进、战略股权投资等。这篇文章就以2000—2025年上市公司为样本手把手做一套能在Stata里跑通的耐心资本投资测算流程。文章不会只丢一个高深公式而是从口径设计、数据清洗、指标计算到常见坑位完整走一遍适合需要建长面板做实证研究的朋友也想给从财务角度筛选“长期主义”公司的读者一个可复现的参考脚本。1. 耐心资本投资的测算思路没有现成科目就从报表里拆在正式开始写代码之前我得先把测算口径讲清楚。因为“耐心资本”不是会计准则里的官方概念不同人做出来的指标很可能完全不一样甚至得出相反结论。我的做法是把公司财报里和“长期价值创造”强相关的支出拆成三个维度再根据研究需要选择主指标或合成指标。第一个维度是内部创新投入核心看研发支出。研发的钱花出去当期利润会受影响但新产品、新工艺、专利积累都是靠这种“看不见的资产”滚出来的。第二个维度是长期产能投入用现金流量表里的“购建固定资产、无形资产和其他长期资产支付的现金”来度量。这个科目非常直观企业在扩产线、建厂房、买设备说明它在为未来做实物资本布局。第三个维度是外部战略布局用长期股权投资的变动额来衡量。一家公司愿意长期持有一家上下游或同行的股权通常不是为了短期炒价而是为了产业协同和技术卡位。维度原始报表科目示例标准化分母说明研发创新投入研发支出 / 研发费用期初总资产 / 营业收入可反映创新驱动强度长期产能投入购建固定资产、无形资产和其他长期资产支付的现金期初总资产最稳定的长期投资代理变量外部战略布局长期股权投资期末余额减期初余额期初总资产关注产业协同而非金融投资主指标我一般用下面这个公式耐心资本投资率 研发支出 购建固定资产、无形资产和其他长期资产支付的现金 / 期初总资产这里有个容易忽略的细节分母我用的是期初总资产而不是当期期末总资产。原因很简单企业如果当年做了大额股权融资期末总资产会快速膨胀单纯以期末值做分母会把耐心资本投资率人为压低造成“资金越充裕、指标越难看”的错觉。期初总资产代表的是公司年初的可支配资源基数用它作分母更能反映企业利用存量资源进行长期布局的力度。当然这个主指标不是唯一答案。如果你研究的行业研发投入很少比如传统消费或公用事业那可以侧重长期产能投入如果你关注的是企业对外产业整合能力那长期股权投资变量就需要单独拿出来看。文章的代码部分会把这几个变量都生成出来方便按需取用。2. 原始数据清单与字段口径先用对表再用对代码跑任何长面板研究第一个拦路虎往往是原始数据表没对齐。耐心资本投资测算需要用到的数据主要来自四类表。第一类是资产负债表核心字段有资产总计、长期股权投资、固定资产等。第二类是现金流量表核心字段就是购建固定资产、无形资产和其他长期资产支付的现金这个科目在现金流量表的投资活动部分。第三类是研发投入明细表核心字段是研发支出金额通常按年度披露。第四类是公司基本信息表主要用来获取股票代码、上市日期、所属行业代码以及上市公司是否被ST/PT标记。合并这几张表之前有两点必须确认清楚否则后面全白做。第一点是报表类型强烈建议统一采用合并报表口径。合并报表反映的是上市公司整体及其子公司的经营全貌母公司报表只代表上市公司本部对于集团型企业来说两者差异很大。你从数据库导出数据时要留意“合并报表”和“母公司报表”的标记字段数据导入后第一件事就是把报表类型筛选为合并。第二点是年度口径2000—2025年跨越了26年中间会计准则发生过多次重大调整。早期企业披露“研发支出”的覆盖率和标准化程度和后期完全不同现金流量表科目名称也有过变化。所以建议统一按照报告期结束日期来提取年度数据绝大多数公司是12月31日个别非12月31日年结的公司需要单独决定取舍。我平时整理出来的一套标准字段命名如下后面Stata代码会直接基于这套命名来写统一变量名含义来源表stkcd证券代码六位字符基本信息表year会计年度各报表total_asset资产总计资产负债表lt_invest长期股权投资资产负债表capex购建固定资产等支付的现金现金流量表rd_exp研发支出研发明细表opt_revenue营业收入利润表ind_code行业代码基本信息表list_date上市日期基本信息表st_flagST/PT标记基本信息表如果你从CSMAR或Wind导出来的字段名是中文不用着急导入Stata后先rename成英文名再往下走就行。中文变量名Stata也能用但写长命令时切换输入法很痛苦一次性改好能省很多事。3. Stata数据清洗从重复值和错误口径中抢救出可用面板这一节我按实际操作的顺序来写代码每一步都解释为什么这么做。原始表导入后第一步永远不是直接算指标而是先检查数据状态。3.1 导入与统一字段命名* 以资产负债表为例假设从CSMAR导出的Excel中“报表类型”字段为“报表类型” import excel D:\patience_capital\资产负债表.xlsx, sheet(合并报表) firstrow clear rename 证券代码 stkcd rename 统计截止日期 date rename 资产总计 total_asset rename 长期股权投资 lt_invest rename 报表类型 report_type * 转换成Stata日期并提取年份 gen date2 date(date, YMD) format date2 %td gen year year(date2) * 保留年报数据绝大多数公司年报截止12月31日 keep if month(date2) 12 keep if report_type 合并 * 转字符串为六位证券代码防止前面的0被吃掉 tostring stkcd, replace format(%06.0f) duplicates tag stkcd year, gen(dup_tag) list stkcd year if dup_tag 0这里我要重点提醒一下证券代码的问题。Excel打开证券代码列时像“000001”这类代码很容易被自动变成数字1如果不在读取前设置文本格式导入Stata后就会丢开头两位。最稳妥的办法是在导入前检查一次导入后立刻用tostring补位。重复值检查也非常关键。有时候数据库会同时在某个表里出现两条同一公司同年度的记录可能是因为报表更新过、或者同一会计年度下出现多份报告。对于重复观测建议先在列表中人工确认确认只是重复后再去重。duplicates drop stkcd year, force3.2 多表合并成完整数据文件拿到清洗好的资产负债表后用同样的方式依次导入现金流量表、研发支出表、利润表和基本信息表然后通过证券代码和年度字段进行一对一的合并。* 假设现金流量表文件已经清洗完毕保存为cash_flow.dta use D:\patience_capital\balance.dta, clear merge 1:1 stkcd year using D:\patience_capital\cash_flow.dta keep if _merge 3 drop _merge merge 1:1 stkcd year using D:\patience_capital\rd_expense.dta keep if _merge 3 drop _merge merge 1:1 stkcd year using D:\patience_capital\info.dta keep if _merge 3 drop _merge save D:\patience_capital\full_sample.dta, replace这里用keep if _merge 3的逻辑是只保留在各张表里都存在的公司年度观测。如果你担心某张表缺失严重导致样本量下降也可以把主表换成资产负债表然后对其他表用merge m:1或keep if _merge ! 2再结合缺失情况做取舍。但研究的口径必须从头到尾一致不能在摘要里说一套、代码里跑另一套。3.3 样本筛选为什么剔除金融类公司和上市初期观测完整面板构建之后还需要做一轮样本筛选。我的常规标准有三条你可以根据研究目的调整。第一条剔除金融行业公司。银行、券商、保险公司的报表结构和一般企业差别太大它们的“长期股权投资”口径和存货、固定资产等科目都不具备可比性。行业代码字段中金融业通常以“J”开头可以直接按行业代码过滤。第二条剔除ST/PT状态的公司观测。ST公司往往处于经营异常状态其投资行为更多是财务救急而不是长期布局混在样本里会污染耐心资本指标。如果数据库里没有现成的ST标记也可以根据股票简称中包含的“ST”或“*ST”来过滤。第三条保留上市满三年以上的公司。耐心资本强调持续性如果公司刚上市两三年募投项目还在建设期指标波动会非常大。用xtset建立面板后可以统计每家公司的观测次数保留至少出现过三次以上的个体。* 剔除金融业和ST标记 drop if substr(ind_code, 1, 1) J drop if st_flag 1 * 建立面板 xtset stkcd year * 保留至少三年观测的公司 bysort stkcd: gen obs_count _N keep if obs_count 3特别说明一下为什么“上市满三年”这条标准很关键。次新股上市后账面上趴着大量募集资金资本开支和研发支出往往远高于正常经营状态如果把这些公司纳入计算又不做处理行业年度均值很容易被次新股拉偏。4. 核心测算耐心资本主指标、备选指标和行业年度调整数据面板整理好之后接下来就是生成核心指标。代码本身不复杂但每一条对应的计算逻辑和潜在陷阱我会拆开讲清楚。4.1 生成基础变量use D:\patience_capital\full_sample.dta, clear xtset stkcd year * 期初总资产 gen double total_asset_lag l.total_asset label variable total_asset_lag 期初总资产 * 长期资产投资率 gen double long_asset_inv capex / total_asset_lag label variable long_asset_inv 长期资产投资率 * 研发支出处理缺失值先补0并生成缺失标记 gen byte rd_missing missing(rd_exp) replace rd_exp 0 if rd_missing gen double rd_int rd_exp / total_asset_lag label variable rd_int 研发投资率 * 长期股权投资变动率 gen double long_eq_inv (lt_invest - l.lt_invest) / total_asset_lag label variable long_eq_inv 长期股权投资变动率 * 耐心资本主指标 gen double pat_cap (rd_exp capex) / total_asset_lag label variable pat_cap 耐心资本投资率(研发支出长期资本支出)/期初总资产为什么要把研发支出缺失值置为0这其实是一个容易被误解的做法。早期年份许多公司没有单独披露研发数据严格的“什么都不做”会让这些公司直接变成缺失值样本量大幅减少而且容易残留的是那些恰好有研发披露的大公司造成严重的选择偏差。相比之下补0后至少保留了观测同时加一个rd_missing虚拟变量在后续稳健性检验里可以把研发缺失的公司单独拿出来对比或者干脆对缺失率过高的年份做敏感性分析。4.2 缩尾和标准化长面板数据一定躲不开野值问题。有些公司可能是当年发生重大并购资本开支一下子翻了几十倍也有可能是数据录入错误出现明显异常值。处理方式通常有两种缩尾和截尾。实证中我更推荐缩尾因为截尾会丢失样本信息缩尾则把它们压回到合理区间。* 安装缩尾命令 cap which winsor2 if _rc ssc install winsor2, replace * 对核心连续变量进行1%和99%分位缩尾 winsor2 long_asset_inv rd_int long_eq_inv pat_cap, suffix(_w) cuts(1 99)这里顺带提一句行业年度调整。单纯看绝对数值不同行业的耐心资本投资率天然就不同。比如制造业的资本开支强度通常远超互联网行业用绝对值做横向比较并不公平。因此我会生成每个公司当年所处行业年度的相对位置指标这样既保留了时间维度上的变化又消除了行业固有差异。* 行业年度中位数 bysort ind_code year: egen pat_cap_med median(pat_cap_w) * 是否高于行业年度中位数 gen byte pat_cap_high (pat_cap_w pat_cap_med) if pat_cap_w ! .如果你的样本量不够大分行业年度算中位数可能会产生某些行业只有三五家公司的情况这时可以退一步用大类行业或者只控制行业固定效应而不做中位数分组。4.3 合成综合耐心资本指数主指标pat_cap已经把研发和长期资本支出一并纳入了这能满足大多数研究需要。但如果你希望把外部战略布局的长期股权投资也融进来可以构造一个综合指数。做法很简单先把三个子指标分别做标准化再加总。* 标准化三个子指标 foreach v of varlist long_asset_inv_w rd_int_w long_eq_w { egen z_v std(v) } * 综合耐心资本指数 gen patience_index z_long_asset_inv_w z_rd_int_w z_long_eq_w label variable patience_index 耐心资本综合指数这里要注意标准化之后的综合指数已经不是有量纲的投资率了它的经济学含义是“该企业在长期投资维度上相对全样本的位置”。用它做分组变量回归没问题但做描述性统计时一定要标注清楚这是标准化得分不能直接读成占比百分数。我自己一般会在实证里同时报告pat_cap和patience_index前者做基准回归后者做稳健性检验双轨并行。4.4 保存与导出指标生成完毕把需要的变量保留下来导出成excel或者直接存成dta文件方便后续合并其他数据。keep stkcd year ind_code pat_cap* long_asset_inv_w rd_int_w long_eq_w patience_index order stkcd year ind_code pat_cap* save D:\patience_capital\patience_capital_2000_2025.dta, replace * 导出excel export excel using D:\patience_capital\patience_capital_2000_2025.xlsx, firstrow(variables) replace注意如果你做学术研究导出的Excel主要用于人工快速查看最终跑回归时还是建议直接使用dta文件避免Excel重复打开和转换造成精度损失。5. 测算结果怎么用描述性统计、趋势图与后续实证接口指标算出来以后一定要先做充分的结果检查再进入正式分析。这一步很多人都图省事跳过直接拿指标跑回归结果回归出来不显著还找不出原因问题往往就出在前面没做基础校验。5.1 描述性统计先跑一遍use D:\patience_capital\patience_capital_2000_2025.dta, clear xtset stkcd year xtsum pat_cap_w long_asset_inv_w rd_int_w long_eq_w观察xtsum输出的三个部分overall、between和within。如果between方差太小说明各公司长期投资强度的差异不大这个指标可能区分度不够如果within方差太大说明公司个体在时间维度上波动剧烈可能受到宏观周期或并购事件影响。理性状态下耐心资本指标的个体之间差异和时序变动都要存在才适合做后续面板回归。5.2 按年份画趋势看时间趋势是长面板数据清理的最好体检方式。如果某一年突然出现断崖式下跌大概率不是经济现象而是数据处理出了问题。collapse (mean) pat_cap_mean pat_cap_w (median) pat_cap_median pat_cap_w, by(year) twoway (connected pat_cap_mean year, lpattern(solid)) /// (connected pat_cap_median year, lpattern(dash)), /// title(上市公司耐心资本投资率年度趋势) /// xtitle(年份) ytitle(耐心资本投资率) graph export D:\patience_capital\pat_cap_trend.png, replace width(1200)如果趋势图在会计准则变更的年份出现显著跳跃要单独核实是真实商业周期还是统计口径变化。处理办法也很直接把那两年分别画出来再对比调整前后的数值判断是否需要剔除或做分年段稳健性检验。5.3 作为回归变量的接口测算出来的耐心资本指标既可以当解释变量也可以当被解释变量。用pat_cap_high这种分组变量做实证很常见。比如检验耐心资本是否提升了企业长期价值可以用未来一期或未来三年的托宾Q值、ROA或全要素生产率做因变量。* 如果已安装reghdfe cap which reghdfe if _rc ssc install reghdfe, replace * 示例高耐心资本组对未来托宾Q的影响 gen tobinq (流通市值 非流通股*每股净资产 总负债) / total_asset reghdfe tobinq i.pat_cap_high size lev age, absorb(stkcd year) vce(cluster stkcd)这里我只用来说明测算结果的用法实际研究中控制变量和固定效应应该根据你的研究假设来定。有一点要提醒耐心资本指标和当期绩效变量往往存在内生性简单回归只能得到相关性不能直接解释成因果。如果文章层面需要更严格的因果识别可以寻找政策冲击或行业层面的外生变量做DID设计但这已经超出了本文代码部分的范畴。6. 我在2000—2025年长周期测算里踩过的几个坑前面这些都是按“理想流程”在讲实际做的时候一定不会一帆风顺。以下是我自己在跑2000—2025年这个超长面板时反复踩过的坑也是每一步代码背后为什么要那样写的真实原因。6.1 研发支出大规模缺口的处理2000年代初期的研发支出披露极不完整大量公司没有单独的研发费用科目。如果直接把缺失研发支出当成0会明显压低早期年份的耐心资本投资率造成一种“近年来企业突然变长期主义”的假象。我的处理办法是双轨制核心回归用2007年以后的数据做研发缺失严重的早期数据只用来算长期资产投资率不纳入包含研发的主指标。同时生成rd_missing变量在稳健性检验中把研发缺失公司单独控制住。这样至少可以识别出指标变动到底来自研发投入增长还是只是覆盖率提高。6.2 会计制度变更带来的序列断裂2007年前后上市公司执行的新企业会计准则在资产计量、研发费用处理、长期股权投资核算等方面都有较大变化。最典型的是研发费用中符合资本化条件的部分需要确认为无形资产而不是全部费用化这使得“研发支出”和“长期股权投资”两个科目的内涵在新旧准则下并不可比。如果你硬着头皮用同一套口径跑26年结果很容易在制度切换年份出现跳点。稳妥的办法是分阶段测算比如2000—2006年用长期资产投资率为主指标2007—2025年再启用包含研发支出和长期股权投资变动的完整指标。需要合并成年面板时再根据全样本模型和分阶段模型的系数方向是否一致来判断是否可以统一处理。6.3 合并报表与母公司报表不要混用这个坑很低级但发生的频率极高。有些数据库默认导出合并报表有些默认导出母公司报表如果中间换了一个人导出数据或者换了数据供应商很容易把两种口径的数据接在一起。合并报表和母公司报表的资产总计、长期股权投资差异很大尤其是集团型公司母公司报表中大量子公司的经营资产并不会体现在本体的长期股权投资科目上。同一家公司两种口径算出来的耐心资本投资率可能相差数倍。我的做法是在每次合并新表前都检查一遍report_type字段的取值分布并且用tab stkcd report_type抽查几家公司确保全样本统一。6.4 退市样本缺失导致幸存者偏差如果你直接按当前仍在上市的公司名单抓取历史数据那2000—2025年之间那些已经退市、被吸收合并的公司就不会出现在样本里测算结果天然偏向“活下来”的公司。这会让耐心资本投资率的均值被高估因为真正长期主义且生存下来的公司比例偏高。处理思路有两条一是尽量补全历史退市公司的财务数据很多数据库是保留历史上市代码的只是需要单独抓取二是在论文或分析报告的局限性部分专门披露幸存者偏差存在的可能性。对于商业数据分析场景如果只关注当前存量公司也可以接受但心里要知道这个边界在哪里。6.5 证券代码和单位问题证券代码被Excel变成数字是我在答疑时遇到最多的共性问题。此外还有金额单位不一致的坑有些表单位是元有些表单位是万元合并前没注意单位跑出来的耐心资本投资率会莫名大出或小出几个数量级。对单位问题我惯用一个笨办法每次合并完新表先按同一家公司在同一年的数据交叉验证一遍。比如资产总计应该在总资产附近资本开支不会超过总资产很多。跑两个list语句就能发现大部分低级错误但就是这关键的几分钟能帮你免掉后面返工几小时。6.6 长面板缩尾要分年度做吗文章前面用的是全样本缩尾因为代码简单、直观。但在2000—2025年这么长的窗口期里全样本缩尾有一个隐藏缺陷早期年份正常值在26年全样本中可能处于较低分位到了后期那些早期正常值反而被缩尾处理成异常值跨期可比性受影响。如果你想更严谨一点可以做分年度缩尾。思路是逐年对pat_cap进行1%和99%分位的缩尾再合并成全样本。这样能保证每个年度的数据分布都是自洽的尤其适合观察长期趋势的研究。缺点是为了保持跨期加总的一致性你得再跑一遍稳健性检验确认分年度缩尾和全样本缩尾对基准回归结论没有本质影响。我一般会把两套结果都附在附注里这种做法在评审中也更受认可。最后再分享一个我个人的习惯每次跑完这套测算我会把当年的缩尾变量分布和中间关键变量的对数图存成一份PDF按年份存档。因为代码过三个月再看哪怕有注释也容易忘了当时为什么做了某些特殊处理但看到图、看到分布上下文马上就能捡回来。做长面板数据真正厉害的不是跑出某个回归系数而是让任何一段数据都经得起别人从头到尾复现和推敲。