我有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.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
我该怎么做?
答案 0 :(得分:3)
这可以通过使用数组的一个数据步骤来完成:
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;
答案 1 :(得分:1)
请参阅以下代码,该代码使用两个PROC TRANSPOSE
步骤和一个DATA
STEP + 1 PROC SORT
来实现您要查找的输出。这可能更有可能在使用DATA
的单个ARRAYS
步骤中完成。但是,大多数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
答案 2 :(得分:1)
如果您使用视图进行变量重命名,则可以在2个直通中轻松实现此目的。
首先转置数据,以便只有4列:
请注意,我使用IF语句来消除所有OLD模型,因为我没有在您想要的输出中看到它们。
proc transpose data=DATAINPUT out=TRANSPOSEOUTPUT;
where MODEL='NEW';
by id model;
run;
这里我们基本上将 NAME 分成标签和年份。此外,还有一些数据清理(删除 NAME &重命名COL1)
data V_TRANSPOSEOUTPUT (drop=_NAME_ rename=(COL1=value)) /view=V_TRANSPOSEOUTPUT;
length ID 8;
length model $3;
length year 8;
length label $1;
set TRANSPOSEOUTPUT;
label=scan(_NAME_,1,'_');
year=scan(_NAME_,2,'_');
run;
我发现proc制表比proc报告更合适,因为 - 至少在我的意见中 - 构建交叉表更容易。至少,根据您的评论,您希望将所需的输出显示为报告,而不是数据集。
proc tabulate data=V_TRANSPOSEOUTPUT;
table id*model*year,label*value;
class id model year year label;
var value;
run;
我测试了这个,我的输出与你写的略有不同,但我怀疑你在写出你想要的结果时犯了几个错误。 ;)