具有100多个变量的SAS转置

具有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

我有一个数据集,其中包含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

如何操作?

请参阅下面的代码,其中使用了两个
PROC TRANSPOSE
步骤和1
DATA
STEP+1
PROC 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
步骤和1
DATA
STEP+1
PROC 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列:

  • 身份证
  • 模型(模型)
  • 标签年组合(名称)
  • 值(COL1)
  • 请注意,我使用了一个IF语句来消除所有旧模型,因为我没有在您想要的输出中看到它们

    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列:

  • 身份证
  • 模型(模型)
  • 标签年组合(名称)
  • 值(COL1)
  • 请注意,我使用了一个IF语句来消除所有旧模型,因为我没有在您想要的输出中看到它们

    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个变量,我建议编写一些宏逻辑来处理它们。