在SAS 9.4中计算治疗周数中位数与95百分位值的技术求助
解决SAS横向周数数据的中位数与95百分位统计问题
嘿,我完全懂你现在的处境——手里攥着横向存储的周治疗数据,想算中位数和95百分位,结果用Proc Means/Univariate都是纵向统计,转置还丢数据,属实头疼。别慌,咱们一步步把这个问题拆解解决。
第一步:正确转置横向数据
你之前转置失败大概率是没保留分组变量,导致观测的对应关系丢失。咱们用proc transpose的时候,一定要加上by语句把NAME、TREATMENT、DATE这些标识变量保留下来,这样转置后每个周数都能对应到原观测。
先创建示例数据集(方便你测试),再执行转置:
/* 创建示例数据集 */ data have; input NAME $ TREATMENT $ DATE $ week0-week7; datalines; CCG1 Treatment1 APR16 1 1 3 2 4 0 0 0 CCG1 Treatment2 APR16 0 0 2 12 0 3 5 0 ; run; /* 转置横向周数为纵向,保留分组变量 */ proc transpose data=have out=long_data; by NAME TREATMENT DATE; /* 保留每个观测的标识 */ var week0-week7; /* 指定要转置的周数变量 */ run;
转置后,long_data会包含_NAME_(原变量名,比如week0)和COL1(对应周的治疗值),同时保留了每个观测的分组信息。
第二步:根据你的需求计算统计量
这里需要明确你要统计的是哪种“治疗所需周数”,我分两种常见场景给你代码:
场景1:统计每个观测的「总治疗持续周数」的中位数和95百分位
比如第一个观测从week0到week4有治疗,总持续5周;第二个观测从week2到week6有治疗,总持续5周。我们先提取周次数字,再计算每个观测的起止周,最后得到总周数:
/* 从_NAME_中提取周次数字(比如week0→0),并筛选有治疗的周 */ data long_data_clean; set long_data; /* 提取周数:从weekX中取出X的数值 */ week_num = input(scan(_NAME_, 2, 'week'), best.); where COL1 ne 0; /* 只保留有治疗记录的周 */ run; /* 计算每个观测的治疗起止周,得到总持续周数 */ data treatment_duration; set long_data_clean; by NAME TREATMENT DATE; if first.DATE then do; start_week = week_num; end_week = week_num; end; else do; start_week = min(start_week, week_num); end_week = max(end_week, week_num); end; /* 只保留每个观测的最终统计结果 */ if last.DATE then do; total_weeks = end_week - start_week + 1; output; end; keep NAME TREATMENT DATE total_weeks; run; /* 用Proc Means计算中位数和95百分位 */ proc means data=treatment_duration median p95 nolabels; var total_weeks; title '治疗持续总周数的中位数与95百分位'; run;
场景2:统计「所有有治疗的周次」的中位数和95百分位
如果你想统计所有出现治疗的周次(比如示例中的0、1、2、3、4、2、3、5、6这些周数)的中位数和95百分位,那转置后直接统计即可:
/* 沿用之前的long_data_clean数据集 */ proc univariate data=long_data_clean noprint; var week_num; /* 输出中位数和95百分位到新数据集 */ output out=week_stats median=median_week p95=p95_week; run; /* 查看统计结果 */ proc print data=week_stats noobs; title '有治疗周次的中位数与95百分位'; run;
为什么你之前转置会失败?
大概率是转置时没加by语句,导致所有观测的周数被混在一起,丢失了NAME、TREATMENT、DATE的对应关系,后续处理自然会丢数据或者统计结果错误。加上by语句后,SAS会按分组变量分别转置,保证每个观测的周数对应正确。
额外注意点
- 如果你的周变量命名不是
weekX格式(比如w0、week_0),需要调整提取周次的代码,比如用substr(_NAME_, 5)来截取数字部分(根据变量名的实际格式调整)。 - 如果存在所有周数都是0的观测,可以在
where语句里加上(sum(of week0-week7) ne 0)来排除这些无效观测。 - Proc Univariate比Proc Means能提供更详细的百分位信息,如果你需要更多统计量,优先选它。
内容的提问来源于stack exchange,提问作者Jack Rotherham
相关产品推荐
相关产品推荐

