
简介这份 docx 文档面向 Stata 初学者及社科、经管、生物医学领域的数据分析入门者围绕软件基本操作与常用命令展开帮助读者建立可复用的数据处理与统计分析流程。压缩包内仅 1 个 docx 文件约 366KB以命令讲解配合示例代码编排便于对照软件同步练习。内容从界面与窗口讲起说明结果窗口、命令窗口、变量名窗口的功能差异继而覆盖 use、edit、browse 等数据导入与编辑命令变量格式部分展开 e、f、g 三种数值格式及 %9.2f、%15s 等写法并讲解 label variable、label define、format 的标签设置。数据操作章节整理 if、in、by、bysort 筛选与分组语句创建数据集涉及 rename、save、cd 等命令描述性统计介绍 describe、list、codebook绘图与回归提及 graph、regress 等进阶入口并附常用函数清单。读者可据此完成数据导入、格式规范、变量标签、条件筛选、描述统计与基础绘图等常见任务。目前已有 4217 人学习适合系统梳理 Stata 基础命令与数据管理思路的读者参考。1. 打开 wage1.dta 之后Stata 的窗口分工与命令执行链路拿到一份 .dta 文件双击打开结果窗口滚出一片黑底白字变量名窗口里几十个变量排成一列——这是多数人第一次接触 Stata 的现场。窗口布局在各版本里基本一致Stata 下载安装完第一次打开看到的就是四块结果窗口、命令窗口、命令回顾窗口、变量名窗口。结果窗口的颜色编码值得记牢黑色是刚执行过的命令回显蓝色是可点击跳转的链接红色是报错。看到红色先别急着重敲往上翻一行读错误码问题多半出在变量名拼写、数据没读进来或者条件表达式写错。命令窗口是唯一真正下指令的地方回车即执行命令回顾窗口按时间列出执行过的命令单击把它复制回命令窗口双击直接重跑。这套设计意味着敲过的每条命令都是可复用的脚本碎片攒够量就该写进 do-file而不是靠回忆找回来。适合谁需要把分析过程交底的人最有价值问卷分析、实证论文、团队复核都算只做一次描述统计的临时需求点菜单也够用。2. 变量显示格式与标签format、label define 与 encode/decode 的联动显示格式只改变看起来是什么样不改变内存里存的值。这一点没分清后面所有导出表格的排版都会返工数字被截成1234.4还以为精度丢了其实是%9.2f的宽度不够撑不下整个数字。2.1 数值格式 %w.d 与 e/f/g 三种写法%w.d(e/f/g)里 w 是整个字段占的字符宽度d 是小数点后位数。格式默认右对齐在%后面加一个短横线-改成左对齐。格式符显示方式示例写法典型显示结果e科学计数法%9.2e1.23e04f固定小数位%9.2f1234.41g一般格式按数值大小在 f 与 e 间切换%9.2g1234.41f 加 c固定小数位并加千分位%9.2fc1,234.41%-左对齐%-9.2f1234.41 后补空格s字符变量只写宽度%15s左对齐填充的字符串sysuse auto, clear format price %9.2fc // 千分位 两位小数金额类变量常用 format mpg %-9.2f // 左对齐方便跟字符列并排 format make %15s // 字符变量限定 15 个字符宽 format // 不带参数列出当前数据集所有变量的格式最后一行format不带参数时是查询不是修改。很多人第一次看到format var1 %9.2f的写法以为是赋值给某个叫 var1 的格式其实语法是变量名在前格式串在后顺序写反会直接报错。2.2 标签三件套label data、label variable、label define/valuesStata 的标签分三层各管一件事混用是导出结果里出现裸数字的头号原因。label data WAGE // 给整个数据集挂说明 label variable south SOUTH // 给单个变量挂中文/英文说明 label define race 1 white 2 black 3 other // 定义值标签字典 label values raceid race // 把字典绑定到具体变量上 label list race // 回看字典内容label data是数据集级别的注释出现在describe的输出顶部label variable是变量级别的说明出现在describe和图表轴标题里label define只是一本字典必须再用label values绑定到某个变量否则前面定义的全都白写。这个定义和绑定分两步的设计是最容易漏的一步检查办法是label list race之后直接tabulate raceid看输出里有没有显示成文字。2.3 encode、decode 与 real()字符串和数值互换问卷数据从 Excel 进来时常常是字符型比如sex存着 male/female做回归前必须转成数值型。encode sex, gen(gender) // 字符型 - 带值标签的数值型 list sex gender in 1/4, nolabel // 不加标签罗列看清底层数值 label list gender // 查看 gender 的值标签内容 decode gender, gen(gender2) // 数值型 标签 - 字符型 gen income2 real(income_str) // 从看起来像数字的字符串直接取值encode生成的数值编码顺序是按字符串排序后的顺序不是按语义顺序所以 female 有可能排在 male 前面。要在报告里写1 代表男性就不要指望encode自动给出这个对应关系得自己确认一遍label list。decode是反向操作把数值和它的值标签拼成字符串。real()是另一条路直接尝试把字符串解析成数值解析失败返回缺失值.适合处理 1,234 这类脏数据。数值型字符串更常见的处理是destring income_str, replace一步到位还不用新建变量。2.4 格式与标签的落地顺序一个能复现的 do-file 头部顺序基本固定读数据 →describe看字段 → 批量format定显示格式 →label define加label values绑定 → 建衍生变量 →save。保存时注意save的nolabel选项它会丢掉标签做中间文件时无所谓做交付文件时别加。整套流程的目标只有一个半年后你自己打开这份数据不用查笔记就知道每一列是什么。3. if/in/by 条件表达式与 describe/list/codebook 数据探查筛选、分组、探查三件事占掉了日常 Stata 操作的七成。这三件事的语法都很短但配合方式多出错的概率也高尤其是缺失值的处理。3.1 in 的五种范围写法in用来按观测序号取子集写法比想象中灵活。写法含义in 5第 5 个观测in 3/7第 3 个到第 7 个观测in 10/l第 10 个到最后一个观测in f/8第一个到第 8 个观测in -5/l倒数第 5 个到最后一个观测顺序敏感的操作比如取末尾几条检查数据尾部的异常值用in -5/l比先排序再筛选快得多前提是你清楚当前数据的排序状态。3.2 if 表达式的运算符与缺失值陷阱browse if 统计学成绩 70 数学成绩 70 // 多条件与 browse if 统计学成绩 70 // 相等判断用 不是 browse in 1/3 if 英语成绩 80 // in 与 if 可以叠加 browse in -1/3 // 只看倒数后三条逻辑运算符三个!或~表示非表示与|表示或。判断相等必须用单等号是赋值写错会直接报语法错误而不是静默出错这一点反而是安全的。真正危险的是缺失值。Stata 里缺失值.在数值比较中被当作一个极大的值if x 10会把缺失值也捞进来。写区间条件时养成习惯补上右边界if educ 12 educ .。如果变量名本身是中文脚本复用和跨平台协作都会难受建议在 do-file 开头统一重命名成英文比如rename 统计学成绩 stat_score。3.3 by 与 bysort以及亚组分析的两种落地写法bysort female: summarize height weight bysort female married: summarize wage bysort female: regress wage educ experby是前置语句语法是by varlist: 命令含义是按分组依据分别执行后面的命令。by要求数据已按分组变量排序bysort会先排再执行所以实际写代码时优先用bysort少一个坑。想按性别和婚否的交叉组合分组直接写两个变量即可执行时按组合逐组运算。亚组分析在 Stata 里最常见的落地方式是两种交互项写法regress wage c.educ##i.female能一次拿到组间差异的检验bysort分组跑模型则更直观适合看每组各自的系数。如果要批量把各亚组结果收集成一张表用statsby收集后导出比手工拷贝几十次回归输出稳。3.4 describe、list、codebook 的探查粒度三个命令的定位完全不同describe看结构list看内容codebook看质量。describe, simple // 只列变量名字段多时先看规模 describe, detail // 详细信息含存储类型和格式 list make price in 1/5, noobs clean // 去掉观测序号列和分隔线 list make price if price 10000, nolabel // 显示底层取值而非标签 codebook price, compact // 精简版变量报告 codebook, header // 数据集名称与最后一次修改时间 summarize price, detail display r(min) r(max)codebook会给出缺失值个数、唯一值个数和取值分布是接手陌生数据时性价比最高的一个命令。compact压缩输出header显示数据集名称和最后修改时间用来确认自己看的是不是最新一版文件。summarize执行后会把统计量存进r()结果里r(min)、r(max)、r(mean)、r(sd)都能直接取出来做后续判断这是查极值最省事的做法不用先排序再list。4. generate、replace、egen 与虚拟变量构造建变量是数据清洗的主战场。Stata 把这件事拆成三条命令generate造新变量replace改已有变量egen做跨观测聚合。用哪个取决于等号右边写的是一条算式还是一个函数调用。4.1 generate 的类型系统gen educ2 educ^2 gen educ_exper educ*exper if educ 9 // 带条件生成不满足的观测取缺失 gen logexper ln(exper) gen educ3 round(sqrt(educ)) gen double bigid id * 1000000 // 整数很大时显式指定 doublegenerate [type] newvar exp [if] [in]里的 type 是可选项可取byte、int、long、float、double。不写 type 时 Stata 按表达式自动推导多数情况下得到float而float只有约 7 位有效数字存身份证号、大额金额或长整型 ID 会悄悄丢精度。遇到这类字段显式写double是最省心的做法。条件生成if的语义要留意不满足条件的观测不是被删掉而是新变量取缺失值.。所以gen x 1 if female 1之后count if x 1得到的数字会小于总观测数这是预期行为。4.2 数学函数与分布函数速查函数含义abs(x)绝对值exp(x)指数函数ln(x) / log10(x)自然对数 / 以 10 为底的对数logit(x)对数发生比 ln(x/(1-x))mod(x,y)x 除以 y 的余数round(x) / round(x,y)四舍五入到整数 / 以 y 为单位四舍五入sqrt(x)平方根uniform()产生 [0,1] 均匀分布随机数chi2(n,x) / chi2tail(n,x)自由度为 n 的累积 / 反向累积卡方分布f(n1,n2,f) / fttail(n1,n2,f)累积 / 反向累积 F 分布tden(n,t) / ttail(n,t)自由度为 n 的 t 分布密度 / 反向累积gen loginc ln(income) gen pval 2*ttail(28, 2.05) // 双侧 p 值28 是自由度 set seed 20240601 gen u uniform() // 先设种子保证结果可复现uniform()是伪随机数发生器不设种子每次跑出来的样本都不一样做随机抽样或模拟前先set seed是硬性要求否则别人复现不了你的结果。4.3 replace 与 nopromatereplace oldvar exp [if] [in] [, nopromate]只能改已经存在的变量写之前变量必须先gen出来。gen educat 0 replace educat 1 if inlist(educ, 4, 5, 6) replace educat 2 if educ 7 educ 9 replace educat 3 if educ 10nopromate用来阻止 Stata 为了容纳新赋值而自动提升变量类型。默认情况下往一个byte变量里写 300Stata 会把它提升成int多数时候这是好事但在循环里反复改类型会拖慢速度也会让describe出来的存储类型和预期不一致需要严格控类型时加上这个选项。4.4 egen 的聚合语义egen右边必须是函数调用不能写算式这是它和gen最本质的区别。egen educavg mean(educ) // 全体均值每个观测都得到同一个值 gen educed educ - educavg // 去均值回归里常用 sum educ educavg educed // 核对结果educed 的均值应接近 0 bysort female: egen educmed median(educ) // 分性别的教育年限中位数 egen stdeduc std(educ) // 标准化均值 0 标准差 1 egen higheduc anyvalue(educ), v(13/18) // 取值落在 13-18 的提取出来 list higheduc educ in 1/20 egen sexmar group(female married) // 按两个变量生成组合分组编号常用 egen 函数包括mean()、median()、sd()、std()、min()、max()、total()、iqr()、skew()、kurt()、group()、anyvalue()以及同一观测内多列聚合的rowtotal()、rowmean()。要分清两类聚合方向mean(educ)是跨观测求一列的平均rowmean(x1 x2 x3)是同一行里求几列的平均名字像但方向完全相反混用是静默出错的重灾区。4.5 虚拟变量与分类变量的四种构造方式gen college 0 replace college 1 if educ 12 gen college2 (educ 12) // 一行搞定推荐 gen master (educ 16 educ .) // 记得排除缺失值 tab1 college college2 master recode educ (1 2 3) (4/7 3), gen(nx) // 合并取值 gen exper1 autocode(exper, 5, 1, 51) // 1-51 等距切成 5 组 sort exper gen exper2 group(5) // 按排序等规模切成 5 组 gen exper3 recode(exper, 5, 15, 25, 40, 51) // 按断点归组 tab1 exper1 exper2 exper3gen var (条件)这种写法利用的是布尔表达式的返回值 0/1比gen加replace两行更紧凑也不会出现忘记初始化导致缺失值的问题是我一般会用的形式。recode的规则语法有几条固定形式写错就报错规则写法含义##单个值转换如 31###多个值合并如 2.9 表示 2 和缺失值都转为 9#/##区间转换如 1/59nonmissing#所有非缺失值统一转换missing#所有缺失值统一转换autocode(x, n, xmin, xmax)把区间等距切 n 份group(x)按排序位置切成 x 个等规模子样本两者对不等距分布的数据会给出完全不同的分组结果group()保证每组样本量接近autocode()保证每组区间等宽。做分组回归前先看一眼tabulate出来的各组频数别等回归跑出来才发现某一组只有三个观测。5. merge、append、joinby、cross 的数据合并诊断合并出错是数据清洗里最难排查的一类问题因为它往往不报错只是悄悄多出几行或者少了几行等到回归样本量和预期对不上才发现。四类合并命令对应四种数据结构先认清方向再动手。5.1 merge 的匹配关系与 _merge 诊断merge [varlist] using filename [,options]做横向合并样本不变、变量变多。gen id _n // 没有唯一标识时先造一个序号变量 use autotech, clear merge make using autocost // make 是关键索引变量 tabulate _merge // 必做看匹配情况_merge的取值只有三个1 表示只出现在主数据2 表示只出现在using的数据3 表示两边都匹配上。跑完 merge 第一件事就是tabulate _merge如果 3 的数量远小于预期多半是索引变量的取值格式不一致比如一边是字符串 A01、一边是数值 1表面看着一样匹配时为 0。匹配关系分 1:1、1:m、m:1、m:m 四种。默认要求索引变量在两边唯一出现重复值会直接报错这是保护机制不是 bug。确实存在一对多关系时用keep(match)、keep(master match)等选项控制保留哪些观测比事后筛_merge再删更清楚。use original, clear merge make using updates, updateupdate选项的含义是主数据里的缺失值允许被using数据里的非缺失值替换主数据的非缺失值不动。合并新旧两版数据时这是常用写法但要清楚它只填缺失不做覆盖。5.2 append 的变量对齐规则use odd, clear append using even list append using even, keep(price mpg) // 只保留内存中已有的变量append using filename [,options]做纵向合并变量数不变、观测变长。两个数据集的变量名不完全一致时Stata 会取并集缺失的那部分填.。keep(varlist)用来限制从外部数据带进来的变量当外部数据变量远多于内部时很有用能省内存也省去事后drop的步骤。合并之后立刻count一下看总行数是否等于两边行数之和不等就说明有变量名对不上导致的重复列。5.3 joinby 组内交叉与 cross 组外交叉use parent, replace sort family_id joinby family_id using child list, sepby(family_id)joinby做组内交叉同一个family_id下的所有父样本会和该组下所有子样本两两配对。多阶段抽样数据家庭-个人结构合并时用这个。sepby(family_id)让输出按组加空行肉眼核对很直观。use agecat, clear cross using sexlistcross做组外交叉结果是两个数据集的笛卡尔积行数为 n1×n2。构造完整的分组框架、给每个年龄组和性别的组合预先占位时用得上但两份数据各有几千行就要谨慎交叉后内存会瞬间膨胀。命令方向样本量变化典型场景merge横向加宽行数基本不变补充变量、对接新旧版本append纵向加长行数相加多期数据、多地区数据拼接joinby组内交叉按组配对扩张家庭-个人等多阶段抽样数据cross组外交叉n1×n2构造完整分组占位框架5.4 sample 抽样与 by() 分层use wage, replace set seed 20240601 sample 15, count // 抽 15 个观测 sample 15 // 抽 15% 的观测 sample 15, by(educ) // 各教育水平上各抽 15% sample 10 if female 1, count // 只对女性抽样男性保持不变 sample 10, count by(female married) // 按性别与婚否的组合各抽 10 个sample #不带count时 # 是百分比带count时 # 是观测个数。by()做分层抽样可以叠加多个分层变量组合数多了以后每组样本量会摊薄抽之前先用tabulate看看最小的那组有多少行。抽样是不可逆操作正确姿势是先set seed再sample中间出错直接use重新读一遍数据不要在已经抽过的数据上再抽一次。6. twoway 复合绘图与 graph export 的参数收敛Stata 的绘图命令短但参数极多一次把十几个选项堆上去改一个坏一个。比较稳的做法是先定骨架再补细节。6.1 从 scatter 到 twoway 的叠加语法scatter y1var xvar是最简形式命令后跟两个变量时第一个是 y 轴、第二个是 x 轴。要叠加多种图层用||分隔use auto, clear twoway (scatter mpg weight, msymbol(dh) mcolor(gs10)) /// (line mpg weight, sort) /// (lfit mpg weight), /// ytitle(MPG) xtitle(Weight) /// ylabel(10(5)45) xlabel(1500(500)5000) /// legend(label(1 观测) label(2 连线) label(3 拟合) cols(3))line图层必须加sort否则点按原始数据顺序连线画出来是一团乱麻。msymbol()控制散点形状常用缩写有O圆圈、T三角形、D钻石、dh空心小钻石、i不显示符号mcolor()控制颜色可写green blue black依次对应各个散点组。颜色和大小清单可以用graph query colorstyle和graph query markersizestyle查比翻文档快。6.2 参数收敛顺序排列顺序按这个来改起来最不容易互相覆盖先坐标轴尺度与刻度再散点/连线样式最后标题与图例。twoway (scatter mpg weight) (scatter price weight, yaxis(2)), /// ylabel(10(5)45, axis(1)) ytick(#10, axis(2)) /// xlabel(#10) yline(25) scale(1.2)yaxis(2)让第二个图层走右侧 y 轴双轴图必须显式指定axis()否则两个图层的刻度会挤在同一侧。scale()是整幅图的缩放系数1 是默认1.2 放大两成字号太小导出时先调这个比逐个改字号快。参考线用yline(25)、xline(1944 1988)加想让它跟网格线同色就写yline(25, lstyle(grid))。分图用by(varlist)by(foreign, total row(1))会多出一张总体图并把子图排成一行。图例的位置在by()内外含义不同写在外面是相对单幅子图定位写在by()里面是相对整张图定位。6.3 导出、复用与批量出图graph export mpg_weight.png, replace width(1200) graph save mpg_weight.gph, replace graph use mpg_weight.gph graph display graph export mpg_weight.pdf, replacegraph export里有replace时必须加否则同名的旧图会让命令直接失败这是最常见的命令没错但没输出文件的原因。存成.gph的好处是保留完整绘图参数之后可以graph use重新加载再改细节不用把几十行命令重敲一遍。做网状 Meta 分析或亚组图时输出的图对象最终也是走graph export这条路格式选 PDF 用于排版、PNG 用于网页。同一个样式要用在几十张图上写成循环最省事foreach v of varlist price mpg weight length { twoway scatter v weight, name(g_v, replace) title(v vs weight) graph export g_v.png, replace width(1200) }local宏v在每次迭代里被替换成变量名name()给每张图起独立名字避免互相覆盖导出文件名也跟着变量名走。把foreach的变量清单换成你要批量画的那些列几十张排版统一的图一次出完图例和坐标轴设置也不会因为手抖而不一致。本文还有配套的精品资源点击获取