我有几个数据文件,这些数据文件中的总数需要重新计算。
这些变量按种族/民族*性别分类,然后得出总计。
该模式已重复进行了多次测量,因此无法重新构建数据文件。我必须保持结构完整。
已更新:例如,下面是其中一个文件的前32个变量(和10行数据)-西班牙裔男性,西班牙裔女性,美洲印第安人男性,美洲印第安人女性....总男性和女性总数分别是8年级和9年级。
我要完成的总数超过100,所以我想使流程自动化。如何选择以_M或_F结尾的7个先前变量进行求和(或某种程度的求和)? TIA !!!
G08_HI_M G08_HI_F G08_AM_M G08_AM_F G08_AS_M G08_AS_F G08_HP_M G08_HP_F G08_BL_M G08_BL_F G08_WH_M G08_WH_F G08_TR_M G08_TR_F TOT_G08_M TOT_G08_F G09_HI_M G09_HI_F G09_AM_M G09_AM_F G09_AS_M G09_AS_F G09_HP_M G09_HP_F G09_BL_M G09_BL_F G09_WH_M G09_WH_F G09_TR_M G09_TR_F TOT_G09_M TOT_G09_F 5 2 9 6 2 3 6 9 7 4 1 4 8 4。 。 7 11 2 13 4 2 14 10 10 13 2 11 9 5。 。 7 1 8 10 2 4 8 0 1 2 8 3 4 5。 。 7 13 12 13 5 15 3 2 2 13 11 15 3 15 。 7 8 10 9 0 4 7 9 8 0 3 10 7 1。 。 15 9 11 9 11 9 6 7 14 9 12 8 6 14 。 4 8 9 0 10 6 4 3 10 9 2 5 8 2。 。 13 2 5 13 3 14 5 15 10 15 7 11 9 6 。 7 6 5 1 4 5 7 4 5 1 8 3 4 4。 。 9 7 7 2 4 8 3 4 3 10 9 8 7 7。 。 3 1 0 2 4 10 2 10 5 9 7 1 8 8。 。 7 9 5 7 13 6 12 13 10 6 2 13 3 12。 。 5 7 4 1 7 9 6 8 3 1 3 2 10 4。 。 14 12 8 5 6 2 2 5 6 4 12 6 4 5。 。 8 9 3 2 3 10 6 5 9 10 8 1 4 5。 。 10 2 3 8 3 15 3 14 9 14 3 12 4 12。 。 4 3 2 6 4 1 2 5 5 6 4 5 4 1。 。 3 14 12 12 15 10 14 11 5 8 9 14 7 15 。 1 10 4 2 1 3 9 8 3 3 3 0 3 1。 。 12 9 5 7 14 9 13 9 6 14 5 7 13 13
答案 0 :(得分:0)
似乎总数被散布在要求和的变量之间,因此我们可以对“自最后一个符合某些条件的所有变量求和,例如以'_F'结尾”?
例如,可以如下进行。我使用了一个简化的数据集,但总数是自每个性别的上一个总数以来,每个变量的总和。我使用proc内容来获取变量列表。然后,我从该列表中查找男性和女性的求和表达式。当遇到名为tot的变量时,形式为tot1_M = sum(var1_M,var2_M,var3_M)的最后一行;输出。这些行收集在宏变量总计中,并插入到数据步骤中。
如果您知道男性总是7个变量,女性是7个变量,然后是一个总和,那么您可以只使用位置而不是名称,下面有一个更简单的解决方案。
data old;
var1_M=1;
var1_F=2;
var2_M=3;
var2_F=4;
var3_M=5;
var3_F=6;
tot1_M=.;
tot1_F=.;
var4_M=7;
var4_F=8;
var5_M=9;
var5_F=10;
var6_M=11;
var6_F=12;
tot2_M=.;
tot2_F=.;
run;
proc contents data=old out=contents noprint;
run;
proc sort data=contents;
by varnum;
run;
data temp;
set contents;
length sumline_F sumline_M $400;
if _n_=1 then do;
sumline_M="sum(";
sumline_F="sum(";
end;
retain sumline_M sumline_F;
if find(name, "_M")>0 and find(name,"tot")=0 then sumline_M=cat(strip(sumline_M),strip(name), ", ");
else if find(name, "_F")>0 and find(name,"tot")=0 then sumline_F=cat(strip(sumline_F), strip(name), ", ");
if find(name,"tot")>0 and find(name,"_M")>0 then do;
sumline_M=substr(sumline_M,1, length(sumline_M)-1);
finline=cat(strip(name), "=", strip(sumline_M),");");
sumline_M="sum(";
end;
if find(name,"tot")>0 and find(name,"_F")>0 then do;
sumline_F=substr(sumline_F,1, length(sumline_F)-1);
finline=cat(strip(name), "=", strip(sumline_F),");");
sumline_F="sum(";
end;
run;
proc sql;
select finline
into :totals separated by " "
from temp
where not missing(finline);
data new;
set old;
&totals;
run;
如果顺序始终相同(总是男女之间),则可以这样:
/* Defining data. Note that _M _F are always alternating, with no variables missing*/
data old;
var1_M=1;
var1_F=2;
var2_M=3;
var2_F=4;
var3_M=5;
var3_F=6;
var4_M=5;
var4_F=6;
var5_M=5;
var5_F=6;
var6_M=5;
var6_F=6;
var7_M=5;
var7_F=6;
tot1_M=.;
tot1_F=.;
var8_M=7;
var8_F=8;
var9_M=9;
var9_F=10;
var10_M=11;
var10_F=12;
var11_M=11;
var11_F=12;
var12_M=11;
var12_F=12;
var13_M=11;
var13_F=12;
var14_M=11;
var14_F=12;
tot2_M=.;
tot2_F=.;
run;
/* We have 7 _M and 7 _F-variables, so the first sum variable is number 15, the next 16. Adding 16 gived us the numbers of the next sum-variables*/
data totals;
do i=15 to 200 by 16;
output;
end;
do i=16 to 200 by 16;
output;
end;
run;
/* Puts the index of the sum variables into a macro variable*/
proc sql;
select i
into :sumvars separated by " "
from totals;
/* Loop variables using an array. If it is a sum variable, it's the sum of the 7 last variables, skipping every other.*/
data new;
set old;
array vars{*} _all_;
do i=1 to dim(vars);
if i in (&sumvars) then do;
vars{i}=sum(vars{i-2}, vars{i-4}, vars{i-6}, vars{i-8}, vars{i-10}, vars{i-12}, vars{i-14});
end;
end;
drop i;
run;