基于现有SAS创建新行到数据集

时间:2017-12-08 09:31:44

标签: sas

我的数据集看起来像这样:

var1 var2   count 
cat1    no     1
cat1    yes    4
cat1    unkown 3
cat2    no     7
cat2    yes    3
cat2    unkown 5
cat3    no     2
cat3    yes    9
cat3    unkown 0

我想要做的是结合var1& var2为新变量,其中第一行来自var1,其他来自var2。所以看起来应该是这样的:

comb   count 
cat1    
no     1
yes    4
unkown 3
cat2
no     7    
yes    3
unkown 5
cat3    
no     2
yes    9
unkown 0

任何帮助都将受到高度赞赏!

1 个答案:

答案 0 :(得分:1)

这很简单。

这里是解决方案:

1)创建数据集源:

data testa;
 infile datalines dsd dlm=',';
   input var1 : $200. var2 : $200. count : 8. ;
   datalines;
cat1,no,1,
cat1,yes,4,
cat1,unkown,3,
cat2,no,7,
cat2,yes,3,
cat2,unkown,5,
cat3,no,2,
cat3,yes,9,
cat3,unkown,0,
; 
run;

2)var列表的选择:cat1 | cat2 | cat3

proc sql;
    select distinct(var1) into: list_var separated by '|' from testa;
run;

3)逐个处理var列表

%macro processListVar(list_var);

    data want;
    run;

    %let k=1;
    %do %while (%qscan(&list_var, &k,|) ne );
        %let var = %scan(&list_var, &k,|);


        data testb(drop=var1 rename=(var2=comb));
            set testa;
            N=_N_+1+&k;
            where var1="&var";
        run;

        data testc;
            N=1+&k;
            comb="&var";
            count=.;
        run;

        data tmp;
            set testb testc;
        run;

        proc sort data=tmp out=teste;
        by N;
        run;

        data want;
            set want teste;
        run;

        %put var=&var;
        %let k = %eval(&k + 1);
    %end;

%mend processListVar;

%processListVar(&list_var);

4)最后,你得到数据集中的结果。

你必须像那样最后排除N列:

data want_cleaned (drop=N);
set want;
run;

5)关于代码的更多解释。

一个。关键问题是保持cat1,cat2,cat3之间的顺序。

湾所以我按每个数据集cat1,cat2,..划分问题,并在循环类别时创建%do%。

℃。我们使用列N来计算行数(如索引),然后我们可以对此列进行排序,以保持顺序。

d。例如:第一个var cat1:我们选择列var2,我们将其重命名为comb列。我们删除了var1列。它创建了testb数据集。 testb数据集用于创建索引(列N),我们在testc中创建子数据集的第一行(N = 1 +& k)。 & k用于所有子数据集。就像那样,索引在子数据集之间继续。 (不互相干扰)。我们在testb和testc之间进行合并。数据集tmp包含cat1所需的所有信息。然后我们合并数据集中的所有子数据集。

总而言之,我们创建了一个循环,并在最后将数据集合并在一起。我们对N列进行排序,以按照您想要的顺序显示行。

此致