选择前n个变量以求和SAS

时间:2018-09-13 20:52:04

标签: select sas sum

我有几个数据文件,这些数据文件中的总数需要重新计算。

这些变量按种族/民族*性别分类,然后得出总计。

该模式已重复进行了多次测量,因此无法重新构建数据文件。我必须保持结构完整。

已更新:例如,下面是其中一个文件的前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

1 个答案:

答案 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;