DAX度量实现列值累计乘积(Kaplan-Meier生存分析)异常问题
DAX生存分析Kaplan-Meier累计乘积异常修复
问题背景
需要在折线图中展示生存分析的Kaplan-Meier曲线:X轴为dayss,Y轴为截至当前日期的每日生存概率累计乘积(数值从1开始递减,最终趋近于0)。现有DAX度量中,除PRODUCTX计算的累计乘积结果异常外,其余变量均验证正确。
原代码核心问题
- 每日生存概率计算错误:
dead_selected和discharged_selected取的是全局上下文的度量值,而非按dayss分组后的当日数值,导致所有天数对应的生存概率[k]完全相同。 - 风险人数逻辑错误:使用固定值
all_-discharged_selected作为分母,未遵循Kaplan-Meier的逐日递减规则(期初风险人数=总人数-之前所有死亡/删失人数)。 - 日期筛选逻辑偏差:
FILTER中的MAX(BacteriologyRegistry_Whonet[dayss])依赖当前视觉上下文,未准确筛选到当前日期及之前的所有天数。
修复后的DAX代码
M_kaplan_meier_first_selected = VAR first_selected_MDR = MIN(BacteriologyRegistry_Whonet[MDR_lookups]) // 统计符合条件的总患者数 VAR all_patients = CALCULATE( DISTINCTCOUNT(BacteriologyRegistry_Whonet[PATIENT_ID]), ALL(BacteriologyRegistry_Whonet[dayss]), BacteriologyRegistry_Whonet[dayss] <> BLANK(), BacteriologyRegistry_Whonet[MDR_lookups] = first_selected_MDR ) // 生成按天数分组的每日死亡、删失数据 VAR daily_data = CALCULATETABLE( ADDCOLUMNS( SUMMARIZE(BacteriologyRegistry_Whonet, BacteriologyRegistry_Whonet[dayss]), "@daily_dead", CALCULATE([M_dead_daily], BacteriologyRegistry_Whonet[MDR_lookups] = first_selected_MDR), "@daily_censored", CALCULATE([m_totaldischarged], BacteriologyRegistry_Whonet[MDR_lookups] = first_selected_MDR) ), ALLSELECTED(BacteriologyRegistry_Whonet), BacteriologyRegistry_Whonet[dayss] <> BLANK(), BacteriologyRegistry_Whonet[MDR_lookups] = first_selected_MDR ) // 计算逐日期初风险人数与生存概率 VAR ranked_daily = ADDCOLUMNS( daily_data, "@rank", RANKX(daily_data, [dayss],, ASC, DENSE), // 按天数升序排名 "@prior_dead", CALCULATE(SUM([@daily_dead]), FILTER(daily_data, [@rank] < EARLIER([@rank]))), // 累计之前死亡人数 "@prior_censored", CALCULATE(SUM([@daily_censored]), FILTER(daily_data, [@rank] < EARLIER([@rank]))), // 累计之前删失人数 "@risk_start", all_patients - [@prior_dead] - [@prior_censored], // 当日期初风险人数 "@survival_prob", 1 - DIVIDE([@daily_dead], [@risk_start], 0) // 当日生存概率,避免除以0 ) // 计算截至当前天数的累计生存概率 VAR current_day = MAX(BacteriologyRegistry_Whonet[dayss]) VAR cumulative_survival = PRODUCTX( FILTER(ranked_daily, [dayss] <= current_day), [@survival_prob] ) // 初始状态(无天数或第一天之前)返回1 RETURN IF(cumulative_survival = BLANK(), 1, cumulative_survival)
修复说明
- 确保每日死亡/删失数据与
dayss分组绑定,避免全局上下文干扰。 - 按天数顺序计算累计死亡、删失人数,动态得出每日期初风险人数,符合Kaplan-Meier的核心逻辑。
- 明确筛选当前日期及之前的所有天数,保证
PRODUCTX计算的是正确的累计乘积。 - 处理除以0的边界情况,初始状态返回生存概率1,符合分析场景预期。
内容的提问来源于stack exchange,提问作者Abdallah Dababneh
相关产品推荐
相关产品推荐

