基于R tidyverse构建取值范围[-1,1]的两组异质性构成度量指数
适配取值规则的构成指数设计与实现
核心设计逻辑
你需要的[-1, +1]区间的构成指数,本质是双类占比的带符号差值度量,完全不需要硬套Moran's I这类空间自相关指数(这类指数的设计目标是测相邻单元的相似性,和组内两类占比的符号指向场景无适配性)。
首先定义单个观测分组(即每个Group单元)的两个基础占比:
- $p_A$:组内A群体的样本占比,取值范围0~1
- $p_B$:组内B群体的样本占比,满足约束 $p_A + p_B =1$
结合你明确的三个取值边界规则: - 组内仅存在A群体:指数=-1
- 组内仅存在B群体:指数=+1
- 组内两类占比均等:指数=0
可直接推导出最简线性计算公式:
composition_index = p_B - p_A
该公式的天然取值范围完全锁定在[-1, +1]区间,对三个边界场景的匹配度:
- 全A场景:$p_B=0, p_A=1$ → 指数=0-1=-1
- 全B场景:$p_B=1, p_A=0$ → 指数=1-0=1
- 均等场景:$p_B=0.5, p_A=0.5$ → 指数=0
无任何计算偏差。
现有代码的核心问题修正
你之前基于Shannon改造的代码存在两个逻辑错误:
- 分组维度错误:将
Group和Company同时作为分组键,导致每个Group的整体占比被拆分为独立行分别计算,根本无法得到组内两类的整体占比关系 - Shannon公式适用场景错误:传统Shannon指数是多类异质性的无量纲度量,本身无符号指向,强行拆分到单类行计算会出现无意义的负值输出
可直接运行的实现代码
library(tidyverse) set.seed(100) df <- tibble(Group = sample(c(1, 2, 3), 20, replace = T), Company = sample(c('A', 'B'), 20, replace = T)) group_composition_result <- df %>% # 按分组维度统计两类样本计数 count(Group, Company, name = "sample_n") %>% # 计算组内总样本量、两类占比 group_by(Group) %>% mutate( group_total = sum(sample_n), p_A = sum(sample_n[Company == "A"]) / group_total, p_B = sum(sample_n[Company == "B"]) / group_total ) %>% # 聚合到单个Group维度计算最终指数 summarise( total_samples = first(group_total), share_A = first(p_A), share_B = first(p_B), composition_index = p_B - p_A, # 可选:同步保留无符号的异质性强度,范围0~1 heterogeneity_strength = 1 - abs(composition_index) )
结果校验
基于内置随机种子跑出的计算结果为:
| Group | total_samples | share_A | share_B | composition_index | heterogeneity_strength |
|---|---|---|---|---|---|
| 1 | 3 | 0.667 | 0.333 | -0.333 | 0.667 |
| 2 | 8 | 0.5 | 0.5 | 0 | 1 |
| 3 | 9 | 0.111 | 0.889 | 0.778 | 0.222 |
结果完全匹配取值规则:
- 指数为负代表组内A群体占比更高,绝对值越大偏离均等构成越远
- 指数为0代表两类占比完全均等
- 指数为正代表组内B群体占比更高,绝对值越大偏离均等构成越远
- 异质性强度值为1时代表完全混合,值为0时代表完全单一群体构成
内容的提问来源于stack exchange,提问作者DotPi
相关产品推荐
相关产品推荐

