如何调整SAS代码实现10C9至10C1组合的均值与CV计算
SAS代码调整:批量计算10Ck(k=1到9)组合的均值与CV
原代码仅支持计算10取9的组合统计量,以下代码调整为批量处理10C9到10C1所有组合的width、length变量的均值与变异系数:
data yourdata; input Obs sample_index $ width length; datalines; 1 Hand1 112.92 48.4075 2 Hand1 132.315 69.9522 3 Hand1 233.248 39.021 4 Hand1 282.457 41.0748 5 Hand1 111.281 31.0925 6 Hand1 197.349 82.4425 7 Hand1 118.723 41.2737 8 Hand1 293.993 22.9405 9 Hand1 272.179 83.9418 10 Hand1 204.086 69.144 11 Hand2 132.35 83.6597 12 Hand2 113.897 46.8513 13 Hand2 185.176 94.1936 14 Hand2 135.936 56.0927 15 Hand2 265.141 64.873 16 Hand2 227.11 80.9043 17 Hand2 265.468 86.7117 18 Hand2 249.726 64.1256 19 Hand2 124.951 43.8425 20 Hand2 285.231 66.0117 ; %let total_obs = 10; /* 每个分组的总样本数 */ %let groups = Hand1 Hand2; /* 需要处理的分组 */ /* 宏:批量计算指定分组、指定组合数的统计量 */ %macro calc_combinations(group, k); /* 生成SQL连接的表别名和变量列表 */ %let tables =; %let width_vars =; %let length_vars =; %let obs_conditions =; %do i=1 %to &k; %let alias = %sysfunc(putn(&i, alphabets.)); /* 生成a、b、c...别名 */ %let tables = &tables yourdata as &alias; %let width_vars = &width_vars &alias..width as width&i; %let length_vars = &length_vars &alias..length as length&i; /* 生成Obs递增条件,避免重复组合 */ %if &i > 1 %then %do; %let prev_alias = %sysfunc(putn(&i-1, alphabets.)); %let obs_conditions = &obs_conditions and &prev_alias..Obs < &alias..Obs; %end; %end; /* 生成k个样本的组合表 */ proc sql; create table combinations_&group._k&k as select distinct &width_vars, &length_vars from &tables where &alias..sample_index = "&group" %do i=1 %to &k; and %sysfunc(putn(&i, alphabets.))..sample_index = "&group" %end; &obs_conditions; quit; /* 计算均值 */ data means_&group._k&k; set combinations_&group._k&k; num_values = &k; group = "&group"; combination_type = "&total_obs.C&k"; width_mean = mean(of width1-width&k); length_mean = mean(of length1-length&k); run; /* 计算变异系数CV */ data cv_&group._k&k; set means_&group._k&k; cv_width = (std(of width1-width&k) / width_mean) * 100; cv_length = (std(of length1-length&k) / length_mean) * 100; /* 过滤掉均值为0的情况,避免除零错误 */ if width_mean > 0 and length_mean > 0; run; %mend; /* 循环处理所有分组和所有k值(1到9) */ %do k=1 %to 9; %do i=1 %to %sysfunc(countw(&groups)); %let group = %scan(&groups, &i); %calc_combinations(&group, &k); %end; %end; /* 合并所有结果到一个表 */ data all_results; set %do k=1 %to 9; %do i=1 %to %sysfunc(countw(&groups)); cv_%scan(&groups, &i)_k&k %end; %end;; run; /* 查看合并后的结果 */ proc print data=all_results label; label combination_type = "组合类型" group = "分组" num_values = "组合样本数" width_mean = "Width均值" length_mean = "Length均值" cv_width = "Width变异系数(%)" cv_length = "Length变异系数(%)"; run;
关键调整说明
- 使用宏循环批量处理k=1到9的所有组合,避免重复编写代码
- 动态生成SQL的表连接、变量列表和Obs递增条件,确保组合无重复
- 新增组合类型标识(如10C9、10C5)和分组字段,方便结果区分
- 添加均值非零过滤,避免计算CV时出现除零错误
- 最后合并所有分组、所有组合的结果到一张表,便于查看分析
内容的提问来源于stack exchange,提问作者Emmanuel Alagbe
相关产品推荐
相关产品推荐

