msgbartop
List for SAS fans and programmer
msgbarbottom

16 5月 12 SAS转置技巧 — 辅助变量


有时候数据分析的时候,总是需要把数据颠来倒去,从不同的角度分析N遍,SAS不但提供彪悍的统计分析程序,还提供了整理数据的辅助语句,每次都能把数据整理有条有理的。众所周知,SAS在清洗整理数据方面(ETL)的能力强大无比。很多SASor在垂涎和试用R语言提供新奇的分析和绘图模块时,不忘了先在SAS里面把数据整得服服帖帖的。

下面把自己遇到几个不那么常规的矩阵转置收集一下,它们都用到了增加辅助变量这一小技巧,尽管简单,其实都非常实用。

例1, 最近遇到一个需要对数据集进行操作的小问题,在SAS帮助proc transpose里面没找到例子,数据形式如下:

数据如下
1
2
3
4
5
6
7
8
9
10
11
12
13
data ex;
input group $ var1 var2 ;
cards;
a 1 5
a 2 6
a 3 7
b 3 7
b 4 8
b 5 9
c 3 4
c 6 8
;
run;
如果用数组也可以搞定的,代码如下:
1
2
3
4
5
6
7
8
9
data ccc(keep=group v new_var);
set ex;
array arr var1 var2;
do over arr;
v=vname(arr);
new_var=arr;
output;
end;
run;
不过我更倾向于直观的转置方法,增加一个辅助变量tem_N,搞定。
1
2
3
4
5
6
7
8
9
10
data sxl;
set ex;
tem_N =_N_;
run;

proc transpose data=sxl out=sxl2(drop= tem_N)
NAME=v prefix=New_var;
var var:;
by group tem_N;
run;

不要以为很简单,看似简单技巧,其实可以秒杀一片问题。具体可以参看论坛里面的类似问题:这个问题的第一步:http://bbs.pinggu.org/thread-996735-1-1.html ,还有此问题第一步:http://bbs.pinggu.org/thread-970841-1-1.html  等等;还有hssnow的博客文章:http://hssnow.name/2011/04/dataset-transformation/ 中的问题。

 

例2, 这是在网上搜到的webgu的一篇博文讨论的问题,见:http://blog.sina.com.cn/s/blog_41889b900100vk1w.html。
下面这个转换比较麻烦,需要用到3次矩阵转置,与webgu的方法相比,这个更具有通用性。比如说在原数据再增加一个变量(即增加一列),下面代码照常Ok。

 

原数据如下:
1
2
3
4
5
6
7
8
9
10
11
data ex1;
input name $ date res;
cards;
amy 2323 111
amy 2323 555
amy 1111 855
bob 3333 645
bob 0994 354
bob 4344 954
;
run;
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
proc transpose out=ex2;
by name;
run;

data ex3;
set ex2;
num=_N_;
run;
proc sort data=ex3 out=ex3;
by _name_;
run;

proc transpose data=ex3 out=ex4;
var col:;
by _name_ ;
id name;
run;

proc sort data=ex4 out=ex4;
by _name_;
run;

data ex5;
set ex4;
by _name_;
if first._name_ then nb=0;
nb+1;
name=catt(_name_,nb);
output;
run;

proc transpose name=id;
var amy bob;
id name;
run;

如果你感兴趣,可以贴个代码试试。

最后需要提醒一下,SAS转置存在一定的缺点,就是数据集太大的时候,需要消耗太大的内存,导致死机。

附一篇讲述SAS转置语句的语法示意图文章,比较形象,见: http://www.nesug.org/proceedings/nesug05/how/how5.pdf

原创文章: ”SAS转置技巧 — 辅助变量“,转载请注明: 转自SAS资源资讯列表

本文链接地址: http://saslist.net/archives/255


Reader's Comments

  1.    

    第一个问题,我是用土办法,两个步骤重命名变量得到
    data a;
    input grp $ a b;
    datalines;
    a 1 5
    a 2 6
    a 3 7
    b 3 7
    b 4 8
    b 5 9
    c 3 6
    c 6 8
    ;
    data a1(rename=(b=a));
    set a ;
    keep grp b;
    run;
    data combine;
    set a1 a(drop=b);
    run;

    Reply to this comment
    •    

      可以这样凑,但如果原数据是下面这样,则需要更多的凑,不够通用。
      data a;
      input grp $ a b c d;
      datalines;
      a 1 5 2 5
      a 2 6 3 5
      a 3 7 3 5
      b 3 7 3 5
      b 4 8 3 5
      b 5 9 3 5
      c 3 6 3 3
      c 6 3 3 5
      ;

      Reply to this comment
  2.    

    不过,如果列数多的时候,这个土方法就坑爹了。还是用矩阵好

    Reply to this comment
  3.    

    例2我试了两种方法,其中一个不用PROC TRANSPOSE,详见http://www.xianhuazeng.com/cn/?p=446

    Reply to this comment
    •    

      data步用得不错,效率会有所提高。

      顺便把代码转一下:
      data want;
      retain NUM 0;
      array VARL[6] DATE1 RES1 DATE2 RES2 DATE3 RES3;
      do until(last.NAME);
      set ex1;
      by NAME;
      if first.NAME then NUM=0;
      NUM=NUM+1;
      VARL[NUM]=DATE;
      NUM=NUM+1;
      VARL[NUM]=RES;
      end;
      drop NUM DATE RES;
      run;

      Reply to this comment
  4.    

    proc transpose data=ex1(drop=res) out=ex1_1;
    var date;
    by name;

    proc transpose data=ex1(drop=date) out=ex1_2;
    var res;
    by name;

    data ex2;
    merge ex1_1(rename=(name=id col1=date1 col2=date2 col3=date3) drop=_name_)
    ex1_2(rename=(name=id col1=res1 col2=res2 col3=res3) drop=_name_);
    run;

    Reply to this comment

Pingbacks/Trackbacks

  1. 一个关于SAS转置的问题 | 老Z博客

Leave a Comment

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据