我正在尝试将SAS中的数据从长格式转换为宽格式。我遇到的问题是我有多个要转置的列。我在下面有一些示例数据集来演示我正在尝试做的事情。我正在执行的实际数据集将非常大,我认为处理此问题的一种方法可能是转置各个列,然后在最后合并,但是我将继续执行的数据集正在要大得多(成千上万列),所以这是不可行的。
下面是我开始使用的数据:
data current_state;
input id $ att_1 $ att_2 $ att_3 $ att_4 $ att_5 $ Dollars;
datalines;
1 d234 d463 d213 d678 d435 50
2 d213 d690 d360 d145 d269 25
3 d409 d231 d463 d690 d609 10
;
下面是我希望转置的结果:
data desired_state;
input id $ d145 $ d213 $ d231 $ d234 $ d269 $ d360 $ d409 $ d435 $ d463 $ d609 $ d678 $ d690;
datalines;
1 0 50 0 50 0 0 0 50 0 0 50 0
2 25 25 0 0 25 25 0 0 0 0 0 25
3 0 0 10 0 0 0 10 0 10 10 0 10
;
我尝试了以下操作,但并没有达到预期的输出结果。
proc transpose data=current_state out=test1;
by id;
id att_1 att_2 att_3 att_4 att_5;
var Dollars;
run;
答案 0 :(得分:1)
Proc TRANSPOSE
没有用于“并行枢轴”到单行的语法-多个ID串联在一起成为列名的结果ID。
使用串行枢轴可以实现并行枢轴结果-首先枢轴到更高的矢量布局,然后再枢转到较宽的布局。
proc transpose data=current_state out=stage1_vector;
by id Dollars;
var att_1 att_2 att_3 att_4 att_5;
run;
proc transpose data=stage1_vector out=want;
by id;
id col1;
run;
want
中的列顺序基于矢量布局中数据中col1
的值外观。您可以通过创建虚拟记录来强制排序列的顺序,其中col1
的值应按所需的出现顺序出现。
proc transpose data=current_state out=stage1_vector(drop=_name_);
by id Dollars;
var att_1 att_2 att_3 att_4 att_5;
run;
proc sort nodupkey data=stage1_vector(keep=col1) out=ids;
by col1;
run;
data vector_view / view=vector_view;
set ids stage1_vector;
run;
proc transpose data=vector_view out=want;
by id;
id col1;
run;
应该仔细考虑用零替换缺失值的要求,尤其是如果您要计算带有d *值的ID的数量(Proc MEANS等)时,尤其要注意这一点。无论如何,可以在转置后的步骤中完成替换。
data want;
set want;
array zerome d:;
/* re-purpose _n_ temporarily as a loop index variable
* that does not have to be explicitly dropped
*/
do _n_ = 1 to dim(zerome);
if missing(zerome(_n_)) then zerome(_n_) = 0;
end;
run;
答案 1 :(得分:0)
这是一种完全动态的方式,但这可能不是最有效的。
将1转换为美元金额-供您选择。
data current_state;
input id $ att_1 $ att_2 $ att_3 $ att_4 $ att_5 $ Dollars;
datalines;
1 d234 d463 d213 d678 d435 50
2 d213 d690 d360 d145 d269 25
3 d409 d231 d463 d690 d609 10
;
*transpose to long;
proc transpose data=current_state out=long;
by id dollars;
var att_1-att_5;
run;
/*Run model within PROC GLMMOD for it to create design matrix
Include all variables that might be in the model*/
proc glmmod data=long outdesign=want outparm=p;
class col1;
model dollars = col1;
run;
/*Create rename statement automatically
THIS WILL NOT WORK IF YOUR VARIABLE NAMES WILL END UP OVER 32 CHARS*/
data p;
set p;
if _n_=1 and effname='Intercept' then var='Col1=Intercept';
else var= catt("Col", _colnum_, "=", vvaluex(effname));
run;
proc sql;
select var into :rename_list separated by " "
from p;
quit;
/*Rename variables*/
proc datasets library=work nodetails nolist;
modify want;
rename &rename_list;
run;quit;
proc print data=want;
run;