我的数据集看起来像这样:
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
任何帮助都将受到高度赞赏!
答案 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列进行排序,以按照您想要的顺序显示行。
此致