我对SAS很新。我过去曾经用过它,但我真的很生气。
我有一张看起来像这样的表:
Key Group1 Metric1 Group2 Metric2 Group3 Metric3
1 . r 20 .
1 . . t 3
对于几个独特的键。 我希望所有内容都显示在一行上,所以它看起来像。
Key Group1 Metric1 Group2 Metric2 Group3 Metric3
1 . r 20 t 3
另一个问题是我不知道我将拥有多少组和公制列(虽然我总是有相同的数字)。
我不确定如何处理这个问题。我能够得到一个列名列表并在宏中使用它们,我只是不确定我需要使用什么proc或datastep函数来解决所有问题。对于任何建议,我都会非常感激。
答案 0 :(得分:3)
有一种非常简单的方法可以使用一个很好的技巧来做到这一点。我之前已经回答了类似的问题,请参阅here其中一个问题。这应该达到你想要的目的。
答案 1 :(得分:1)
您可以使用2个临时数组(一个用于字符变量,另一个用于数字),并相应地填充非空值。当您到达last.key
时,可以将临时数组加载回源变量。
如果您事先知道字符变量的最大长度,则可以对其进行硬编码,但如果不知道,则可以动态确定它。
这假设对于每个键,每个变量仅填充一次。否则,它将获取它在每个键中为特定变量看到的最后一个值。
%LET LIB = work ; %LET DSN = mydata ; %LET KEYVAR = key ; /* Get column name/type/max length */ proc sql ; /* Numerics */ select name, count(name) into :NVARNAMES separated by ' ', :NVARNUM from dictionary.columns where libname = upcase("&LIB") and memname = upcase("&DSN") and name ^= upcase("&KEYVAR") and type = 'num' ; /* Characters */ select name, count(name), max(length) into :CVARNAMES separated by ' ', :CVARNUM, :CVARLEN from dictionary.columns where libname = upcase("&LIB") and memname = upcase("&DSN") and name ^= upcase("&KEYVAR") and type = 'char' ; quit ; data flatten ; set &LIB..&DSN ; by &KEYVAR ; array n{&NVARNUM} &NVARNAMES ; array nt{&NVARNUM} _TEMPORARY_ ; array c{&CVARNUM} &CVARNAMES ; array ct{&CVARNUM} $&CVARLEN.. _TEMPORARY_ ; retain nt ct ; if first.&KEYVAR then do ; call missing(of nt{*}, of ct{*}) ; end ; /* Load non-missing numeric values into temporary array */ do i = 1 to dim(n) ; if not missing(n{i}) then nt{i} = n{i} ; end ; /* Load non-missing character values into temporary array */ do i = 1 to dim(c) ; if not missing(c{i}) then ct{i} = c{i} ; end ; if last.&KEYVAR then do ; /* Load numeric back into original variables */ call missing(of n{*}) ; do i = 1 to dim(n) ; n{i} = nt{i} ; end ; /* Load character back into original variables */ call missing(of c{*}) ; do i = 1 to dim(c) ; c{i} = ct{i} ; end ; output ; end ; drop i ; run ;