加载中…
个人资料
谷子歌的2018
谷子歌的2018
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,101
  • 关注人气:199
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

也说行列互换之proc transpose

(2011-10-16 15:12:36)
标签:

sas

transpose

转置

行列互换

分类: Data_Coding

题记:不能偷懒了…… 

 

其实proc transpose还是挺复杂的(个人感觉),不知为啥,初次接触时,想起来那时学线性代数的不易(现在也忘光了)。 Transpose:转置,调换顺序。顾名思义,调换行列的位置,即行列互换。 大致语法如下图:http://s16/middle/41889b90taf654dac3a0f&690transpose" TITLE="也说行列互换之proc transpose" />

data out指定源数据集和目标数据集,labelname为转置后SAS自动生成的变量(_label_, _name_)改名。Prefix ID联合控制目标数据集中的转置后生成的变量名。Var By联合控制转置后生成的“数据矩阵”, Var为要转置的变量,by 指定分组变量。

 

实例:

Topic1、转一个变量。Old1 转成new1

http://s6/middle/41889b90taf654f681f25&690transpose" TITLE="也说行列互换之proc transpose" />

      

 http://s6/middle/41889b90taf654f775735&690transpose" TITLE="也说行列互换之proc transpose" />

 

****solution1: proc transpose*****;

proc transpose data=old1 out=new1 (drop=_name_) prefix=date;

  var date;

  by name;

run;

 

*****solution2: do+array****;

data new1(drop=i date);

  informat name ;

  array dates[1:3]$ date1-date3;

  do i=1 to 3;

    set old;

    dates[i]=date;

    end;

run;

注:上面的do +array 的方法 有两个弱点;1code较多。2、必须知道OLD中各NAMEdate的确切个数,且这个数必需相等。

 

改进:计算出各NAMEDATE计数,并找其中的最大值 ,赋组宏变量,传给数组

 

***improved code****;

proc sql noprint;

  select max (countdate)

  into:max

  from (select count(date) as countdate from old1 group by name);

 

%let max=&max;

 

data new1(drop=i date);

  informat name ;

  array dates[&max]   $ date1-date&max;

  do i=1 to &max;

    set old1;

    by name;

    dates[i]=date;

  end;

run;

 

如何转回来:

*** proc transpose***;

proc transpose data=new1 out=old1_back(drop=_name_ rename=(col1=date)) ;

  var date1-date3;

  by name;

run;

 

*****do +array****;

data old1_back(keep=name date);

  set new1;

  array dates[1:3] $ date1-date3;

  do i=1 to 3;

    date=dates[i];

    output;

  end;

run; 

 

Topic2 转多个变量。数据集old2 new2

多个变量的转置会有所不同,以两个变量为例。

http://s7/middle/41889b90taf654f869ad6&690transpose" TITLE="也说行列互换之proc transpose" />

 

 http://s7/middle/41889b90taf654f86a3c6&690transpose" TITLE="也说行列互换之proc transpose" />

 

Solution1: do+array

data new2(drop=i date result);

   format name date1-date3 result1-result3;

   array dates[1:3] $  date1-date3;

   array results[1:3] $ result1-result3;

   do i=1 to 3;

     set old2;

     dates[i]=date;

     results[i]=result;

   end;

run; 

solution2: proc transpose +merge

 转置多个变量时,无法一次性完成上述要求。需用merge做后继处理。

*****solution1plus: proc transpoe +merge***;

proc transpose data=old2 out=tmp;

  var date result;

  by name;

run;

 

data new2(drop=_name_);

  merge tmp(where=(_name_='date')   rename=(col1-col3=date1-date3))

         tmp(where=(_name_='result') rename=(col1-col3=result1-result3));

  by name;

run; 

 或者一次转一个,转多次后MERGE.

proc transpose data=old2 out=tmp1(drop=_name_) prefix=date;

   var date;

   by name;

run;

 

proc transpose data=old2 out=tmp2(drop=_name_) prefix=result;

   var result;

   by name;

run;

 

data  new2;

  merge tmp1 tmp2;

  by name;

run; 

 

 如何转回来:

 

****do +array****;

data old2_back(keep=name date result);

  set new2;

  array dates[1:3] $ date1-date3;

  array results[1:3] $ result1-result3;

  do i=1 to 3;

    date=dates[i];

    result=results[i] ;

    output;

  end;

run;

 

***transpose +merge****;

proc transpose data=new2 out=old2_tmp;

   var date1-date3 result1-result3;

   by name;

run;

 

data old2_back(drop=_name_);

  merge  old2_tmp(where=(substr(_name_,1,4)='date')    rename=(col1=date) )

         old2_tmp(where=(substr(_name_,1,6)='result')  rename=(col1=result)) ;

  by name;

run;

 

参考:1.SUGI PAPER, An Animated Guide: Proc Transpose

     2.SUGI PAPER,Changing the Shape of Your Data:  PROC TRANSPOSE vs. Arrays

     3.SAS 9.2 SQL Procedure User's Guide.

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有