具有100多个变量的SAS转置
我有一个数据集,其中包含100个变量,前缀变量为2013年至2022年。我想转换数据。请在下面找到样品具有100多个变量的SAS转置,sas,Sas,我有一个数据集,其中包含100个变量,前缀变量为2013年至2022年。我想转换数据。请在下面找到样品 ID MODEL A_2013 A_2014 ....A_2022 B_2013 B_2014...B_2022 C_2013..C_2022 1 NEW 0.5 0.2 ... 0.8 0.2 0.3 0.9 0.2 0.5 2 OLD 0.2 0.9 .... 0.9 0.5 0.6 0.2 0
ID MODEL A_2013 A_2014 ....A_2022 B_2013 B_2014...B_2022 C_2013..C_2022
1 NEW 0.5 0.2 ... 0.8 0.2 0.3 0.9 0.2 0.5
2 OLD 0.2 0.9 .... 0.9 0.5 0.6 0.2 0.6 0.6
3 NEW 0.2 0.3 .... 0.2 0.6 0.9 0.2 0.6 0.1
我想做喜欢的事
ID MODEL YEAR A B C
1 NEW 2013 0.5 0.2 0.2
1 NEW 2014 0.2 0.5 0.8
1 NEW 2022 0.8 0.2 0.5
如何操作?请参阅下面的代码,其中使用了两个
PROC TRANSPOSE
步骤和1DATA
STEP+1PROC SORT
来实现您要查找的输出。使用数组
可以在单个数据
步骤中完成此操作。但是,大多数SAS程序员都可以使用以下方法
/*sample data*/
data have;
INPUT ID MODEL $ A_2013 A_2014 A_2022
B_2013 B_2014 B_2022
;
datalines;
1 NEW 0.5 0.2 0.1 0.4 3.4 12.89
2 OLD 0.5 0.2 0.3 0.4 3.4 12.5
3 NEW 0.5 0.2 0.1 0.2 3.4 12.4
4 OLD 0.5 0.2 4.1 0.4 3.4 12.0
5 NEW 0.2 0.1 0.3 0.4 3.1 12.1
6 OLD 2.5 1.2 2.1 1.4 2.4 1.2
;
run;
/*1st transpose: turn the input dataset from short and wide to long and thin*/
proc transpose data = have out = have_t(rename = (col1=value));
by id model;
run;
/*split the labels into two parts, segment & year*/
data have_t2;
length segment $8 year 8;
set have_t;
underScorePosition=index(_name_,'_');
segment = substr(_name_,1, underScorePosition-1);
year = input(substr(_name_,underScorePosition+1), 4.);
drop _name_;
run;
/*make sure values are properly sorted before passing to 2nd transpose*/
proc sort data = have_t2;
by id model year;
run;
/*2nd transpose: here turn sgements into columns*/
proc transpose data = have_t2 out = want(drop =_name_);
by id model year;
id segment;
var value;
run;
输出:
ID MODEL year A B
1 NEW 2013 0.5 0.4
1 NEW 2014 0.2 3.4
1 NEW 2022 0.1 12.89
2 OLD 2013 0.5 0.4
2 OLD 2014 0.2 3.4
2 OLD 2022 0.3 12.5
3 NEW 2013 0.5 0.2
3 NEW 2014 0.2 3.4
3 NEW 2022 0.1 12.4
4 OLD 2013 0.5 0.4
4 OLD 2014 0.2 3.4
4 OLD 2022 4.1 12
5 NEW 2013 0.2 0.4
5 NEW 2014 0.1 3.1
5 NEW 2022 0.3 12.1
6 OLD 2013 2.5 1.4
6 OLD 2014 1.2 2.4
6 OLD 2022 2.1 1.2
请参阅以下代码,该代码使用两个
PROC TRANSPOSE
步骤和1DATA
STEP+1PROC SORT
来实现所需的输出。使用数组
可以在单个数据
步骤中完成此操作。但是,大多数SAS程序员都可以使用以下方法
/*sample data*/
data have;
INPUT ID MODEL $ A_2013 A_2014 A_2022
B_2013 B_2014 B_2022
;
datalines;
1 NEW 0.5 0.2 0.1 0.4 3.4 12.89
2 OLD 0.5 0.2 0.3 0.4 3.4 12.5
3 NEW 0.5 0.2 0.1 0.2 3.4 12.4
4 OLD 0.5 0.2 4.1 0.4 3.4 12.0
5 NEW 0.2 0.1 0.3 0.4 3.1 12.1
6 OLD 2.5 1.2 2.1 1.4 2.4 1.2
;
run;
/*1st transpose: turn the input dataset from short and wide to long and thin*/
proc transpose data = have out = have_t(rename = (col1=value));
by id model;
run;
/*split the labels into two parts, segment & year*/
data have_t2;
length segment $8 year 8;
set have_t;
underScorePosition=index(_name_,'_');
segment = substr(_name_,1, underScorePosition-1);
year = input(substr(_name_,underScorePosition+1), 4.);
drop _name_;
run;
/*make sure values are properly sorted before passing to 2nd transpose*/
proc sort data = have_t2;
by id model year;
run;
/*2nd transpose: here turn sgements into columns*/
proc transpose data = have_t2 out = want(drop =_name_);
by id model year;
id segment;
var value;
run;
输出:
ID MODEL year A B
1 NEW 2013 0.5 0.4
1 NEW 2014 0.2 3.4
1 NEW 2022 0.1 12.89
2 OLD 2013 0.5 0.4
2 OLD 2014 0.2 3.4
2 OLD 2022 0.3 12.5
3 NEW 2013 0.5 0.2
3 NEW 2014 0.2 3.4
3 NEW 2022 0.1 12.4
4 OLD 2013 0.5 0.4
4 OLD 2014 0.2 3.4
4 OLD 2022 4.1 12
5 NEW 2013 0.2 0.4
5 NEW 2014 0.1 3.1
5 NEW 2022 0.3 12.1
6 OLD 2013 2.5 1.4
6 OLD 2014 1.2 2.4
6 OLD 2022 2.1 1.2
如果使用视图重命名变量,则可以通过两次传递很容易地实现这一点 1-Proc转置 首先转置数据,以便只有4列:
proc transpose data=DATAINPUT out=TRANSPOSEOUTPUT;
where MODEL='NEW';
by id model;
run;
2数据步骤视图
在这里,我们基本上将名称分为标签和年份。此外,对数据进行一些清理(删除名称并重命名COL1)
3过程列表(代替过程报告)
我发现proc制表比proc报告更合适,因为——至少在我看来——构造交叉表更容易。至少,我从您的评论中得出,您希望将所需的输出显示为报告,而不是数据集
proc tabulate data=V_TRANSPOSEOUTPUT;
table id*model*year,label*value;
class id model year year label;
var value;
run;
我对此进行了测试,我的输出与您编写的略有不同,但我怀疑您在编写所需结果时犯了几个错误。;) 如果使用视图重命名变量,则可以通过两次传递轻松实现这一点 1-Proc转置 首先转置数据,以便只有4列:
proc transpose data=DATAINPUT out=TRANSPOSEOUTPUT;
where MODEL='NEW';
by id model;
run;
2数据步骤视图
在这里,我们基本上将名称分为标签和年份。此外,对数据进行一些清理(删除名称并重命名COL1)
3过程列表(代替过程报告)
我发现proc制表比proc报告更合适,因为——至少在我看来——构造交叉表更容易。至少,我从您的评论中得出,您希望将所需的输出显示为报告,而不是数据集
proc tabulate data=V_TRANSPOSEOUTPUT;
table id*model*year,label*value;
class id model year year label;
var value;
run;
我对此进行了测试,我的输出与您编写的略有不同,但我怀疑您在编写所需结果时犯了几个错误。;) 这可以通过使用数组的一个数据步骤来完成:
Data [Output] (keep=ID MODEL YEAR A B);
set [Input];
array arr_A{10} A_2013 - A_2022;
array arr_B{10} B_2013 - B_2022;
DO i=1 to 10;
A=arr_A[i];
B=arr_B[i];
YEAR = 2012+i;
OUTPUT;
END;
RUN;
这可以通过使用阵列的一个数据步骤完成:
Data [Output] (keep=ID MODEL YEAR A B);
set [Input];
array arr_A{10} A_2013 - A_2022;
array arr_B{10} B_2013 - B_2022;
DO i=1 to 10;
A=arr_A[i];
B=arr_B[i];
YEAR = 2012+i;
OUTPUT;
END;
RUN;
好吧,这一步不行。您首先需要进行proc转置。然后,执行一个数据步骤,将标签和年份彼此分开,并将所有内容聚合在一起。对我来说,这似乎是最简单的方法。即使我也在考虑同样的方法来转置,然后创建报告,但我如何使用转置来拆分标签和年份?我编辑了一个无法一步完成的postWell。您首先需要进行proc转置。然后,执行一个数据步骤,将标签和年份彼此分开,并将所有内容聚合在一起。对我来说,这似乎是最直接的方法。即使我也在考虑转置,然后创建报告,但如何使用转置来拆分标签和年份?我编辑了帖子。这将比涉及proc转置的解决方案更有效。由于要处理100个变量,我建议编写一点宏逻辑来处理它们。这将比涉及proc转置的解决方案更有效。由于要处理100个变量,我建议编写一些宏逻辑来处理它们。