使用Proc SQL高效地转置

6

我想知道在SAS中是否可以使用PROC SQL有效地从宽表转换为长表。

我知道PROC TRANSPOSE比我下面提出的方法要快得多。但我的一个目标是避免存储转置后的数据表。

举个例子,我有一个叫table1的表:

Id|   A|   B|   C|  D    
_____________________
 1|  100|3500|6900| 10300
 2|  200| 250| 300| 350
 3|  150|  32| 400| 204
 4|  200| 800|1400| 2000

and i want to turn it into

id|col1|  col2|
______________
 1|   A|   100|
 1|   B|  3500|
 1|   C|  6900|
 1|   D| 10300|
 2|   A|   200|
 2|   B|   250|
 2|   C|   300|
 2|   D|   350|
 3|   A|   150|
 3|   B|    32|
 3|   C|   400|
 3|   D|   204|
 4|   A|   200|
 4|   B|   800|
 4|   C|  1400|
 4|   D|  2000|

我可以这样操作: 从table1中选择id,并将'A'作为col1,A作为col2, 其中A的值不为空, 然后合并结果集 再从table1中选择id,并将'B'作为col1,B作为col2, 其中B的值不为空, 然后再次合并结果集等等。 但是这种方法效率极低。
您有什么想法吗?谢谢。

UNION 会删除任何重复项,如果您不关心是否有重复项,则可以使用 UNION ALL,这可能有助于提高性能。 - Taryn
看起来非常像SQL的“unpivot”,但将其与“PROC SQL”连接可能会很困难。 - Philip Kelley
2个回答

10
如果您使用的是SAS,可以使用PROC TRANSPOSE选项进行操作。在PROC SQL中没有特别好的方法来完成这个任务;虽然许多SQL变体都有自己的数据透视方式,但SAS具有PROC TRANSPOSE并期望您使用它。
SAS数据步骤也可以非常高效地完成此操作,甚至可能比PROC TRANSPOSE更好。以下是一个示例,包括根据注释创建视图。
data want/view=want;
set have;
array vars a b c d;                  *array of your columns to transpose;
do _t = 1 to dim(vars);              *iterate over the array (dim(vars) gives # of elements);
  if not missing(vars[_t]) then do;  *if the current array element's value is nonmissing;
    col1=vname(vars[_t]);            *then store the variable name from that array element in a var;
    col2=vars[_t];                   *and store the value from that array element in another var;
    output;                          *and finally output that as a new row;
  end;
end;
drop a b c d _t;                     *Drop the old vars (cols) and the dummy variable _t;
run;

非常有趣。那么有没有办法避免存储所需的表格呢?因为我的表格很大,而且我还有更多的步骤要完成。 - DJJ
当然,你可以将其创建为视图。 - Joe
所以就转置而言,Proc transpose或Proc data比Proc SQL更优秀。http://support.sas.com/documentation/cdl/en/lrcon/62955/HTML/default/viewer.htm#a001278887.htm。非常感谢。 - DJJ
这段代码很棒。你能再解释一下吗?第5行有错别字吗?应该是**missing(vars)而不是missing(vars[_t])**。 - DJJ
我给你的回答提供了一个不错的解决方案,但我必须质疑数据步骤比proc transpose更好的观点。即使是这个非常简单的问题,所需的代码也比proc transpose多得多,你可以在其他回答中看到。而且我严重怀疑你的数据步骤解决方案是否比proc transpose运行得更快。 - floydn
@floydn 当然不会认为它在代码方面更好。就运行效率而言,它是有差异的:某些数据在其中一个上更有效率。这可以作为视图来完成,在需要视图的情况下,这是与PROC TRANSPOSE相比的一个巨大优势,因为它不必将数据集写入磁盘上的任何位置。 - Joe

1

我今天实际上做了类似的事情。尝试这样做:

proc transpose data = ORIGINAL_DATA;
        out = NEW_DATA;
    by id;
    VAR A-D;
run;

我认为这应该可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接