Stata基于变量后续值生成点位矩阵计算ID距离的移位缺失问题
问题根源
你当前使用的行号偏移索引逻辑存在固有局限:
- Stata对
变量[_n+偏移量]的索引规则有明确限制,当计算得到的索引位置超过数据集总观测数(即_n + 偏移量 > _N)时,系统会自动返回缺失值,这一规则无法通过循环设置直接规避。 - 顺着这个逻辑生成的偏移列,越靠近数据集末尾的观测行,可满足索引范围的偏移量越少,自然会形成下半部分大面积缺失的矩阵结构,根本支撑不了全组合的距离计算需求。
适配的实现方案
方案1:修正原有宽表生成逻辑,彻底消除缺失
如果还是需要按你期望的矩阵结构(每列存储对应偏移位置的原变量取值)生成无缺失的宽表,不要依赖实时行号索引,提前把全量变量值存入暂元后再生成列,就能绕开索引越界的缺失问题:
* 先清理之前循环生成的冗余偏移变量 drop id_* num1_* num2_* * 把每个原始变量的全量取值预先存入暂元,不受行号索引规则限制 foreach var of varlist id num1 num2 { local `var'_values "" forvalues row = 1/`=_N' { local `var'_values ``var'_values' `var'[`row'] } } * 逐偏移量生成对应列,直接从暂元中按顺序取对应位置的取值 forvalues offset = 1/`=_N' { * 对应偏移位置取暂元中从offset开始的连续值,索引越界时自动循环映射到有效行范围,无缺失 gen id_`offset' = word("`id_values'", mod(_n + `offset' - 1, `=_N') + 1) gen num1_`offset' = real(word("`num1_values'", mod(_n + `offset' - 1, `=_N') + 1)) gen num2_`offset' = real(word("`num2_values'", mod(_n + `offset' - 1, `=_N') + 1)) }
- 逻辑说明:这里用
mod()取模运算把索引位置映射到1~_N的有效范围内,哪怕当前行号加偏移量超过总行数,也会自动映射到合法的观测行位置,全程不会出现缺失值。
方案2:更高效的全距离计算实现(推荐)
2000个点位的全两两组合计算,不需要构建占内存极高的超宽矩阵,直接生成配对长表计算的效率是宽表方案的数倍,内存占用也会大幅降低:
* 保留原始点位变量为临时数据集 preserve keep id num1 num2 tempfile raw_points save `raw_points' * 生成全量两两配对组合,自动关联两个点的所有属性,无缺失 cross using `raw_points' * 逐对计算点位距离,覆盖所有可能的ID配对 * 欧氏距离直接计算即可 gen pair_distance = sqrt((num1 - num11)^2 + (num2 - num21)^2) * 如果需要计算球面地理距离,可安装geodistance命令后直接调用: * ssc install geodistance * geodistance id num1 num2 id1 num11 num21, gen(geo_distance) * 计算完成后如果需要转回宽矩阵结构,可通过reshape wide指令快速转换 restore
内容的提问来源于stack exchange,提问作者Makiko
相关产品推荐
相关产品推荐

